#include <cstdio>
const int L_ARB_MAX = 1<<18;
const int INF = 2000000000;
int arb[L_ARB_MAX]; int n;
inline int max(int a, int b)
{
return (a>b)?a:b;
}
/* Pentru un interval (cred)
apel cu update(1,1,n,poz,poz,val);
void update(int nod, int x, int y, int a, int b, int val)
{
if (a <= x && y <= b)
{
arb[nod] = val;
return;
}
if (y < a || b < x)
return;
int mij = (x+y)/2;
update(2*nod,x,mij,a,b,val);
update(2*nod+1,mij+1,y,a,b,val);
arb[nod] = max(arb[2*nod],arb[2*nod+1]);
}
*/
void update(int nod, int x, int y, int poz, int val)
{
if (x == poz && y == poz)
{
arb[nod] = val;
return;
}
/*
if (y < poz || poz < x)
return;
*/
int mij = (x+y)/2;
if (poz <= mij)
update(2*nod,x,mij,poz,val);
else
update(2*nod+1,mij+1,y,poz,val);
arb[nod] = max(arb[2*nod],arb[2*nod+1]);
}
int query(int nod, int x, int y, int a, int b)
{
if (a <= x && y <= b)
return arb[nod];
if (y < a || b < x)
return -INF;
int mij = (x+y)/2;
return max(query(2*nod,x,mij,a,b) ,
query(2*nod+1,mij+1,y,a,b));
}
inline void actualizare(int poz, int val)
{
update(1,1,n,poz,val);
}
inline int interogare(int a, int b)
{
return query(1,1,n,a,b);
}
int main()
{
int m;
int op,a,b;
freopen("arbint.in","r",stdin);
freopen("arbint.out","w",stdout);
scanf("%d%d",&n,&m);
for (int i = 1; i <= n; ++i)
{
scanf("%d",&a);
actualizare(i,a);
}
for (int i = 1; i <= m; ++i)
{
scanf("%d%d%d",&op,&a,&b);
if (op == 0)
printf("%d\n",interogare(a,b));
else
actualizare(a,b);
}
return 0;
}