#include <fstream>
using namespace std;
#define endl '\n'
ifstream f("arbint.in");
ofstream g("arbint.out");
const int NMAX = 100005;
int n , m , v[NMAX] , arb[NMAX * 4 + 1];
inline int left_son(int node) { return node * 2; }
inline int right_son(int node) { return node * 2 + 1; }
void init_arb(int node , int left , int right)
{
if(left == right)
arb[node] = v[left];
else
{
int middle = (left + right) / 2;
init_arb(left_son(node), left , middle);
init_arb(right_son(node) , middle + 1 , right);
arb[node] = max(arb[right_son(node)] , arb[left_son(node)]);
}
}
void update(int node , int left , int right , int pos , int value)
{
if(left == pos && pos == right)
arb[node] = value;
else
{
int middle = (left + right) / 2;
if(pos <= middle)
update(left_son(node) , left , middle , pos , value);
else
update(right_son(node) , middle + 1 , right , pos , value);
arb[node] = max(arb[right_son(node)] , arb[left_son(node)]);
}
}
int query(int node , int left , int right , int new_left , int new_right)
{
if(new_left <= left && right <= new_right)
return arb[node];
else
{
int middle = (left + right) / 2;
int res1 = -100000000, res2 = -100000000 ;
if(new_left <= middle)
res1 = query(left_son(node) , left , middle , new_left , new_right);
if(new_right > middle)
res2 = query(right_son(node) , middle + 1 , right , new_left , new_right);
return max(res1 , res2);
}
}
int main()
{
f>>n>>m;
for(int i=1;i<=n;i++)
f>>v[i];
init_arb(1, 1, n);
for(int i=1;i<=m;i++)
{
int caz , a , b;
f>>caz>>a>>b;
if(caz == 0)
g<<query(1 , 1 , n , a , b)<<endl;
else
update(1, 1, n, a, b);
}
return 0;
}