#include <stdio.h> //arbore intervale
#include <string.h>
int a[100001],m[2*100001-1],N,M;
void update(int nod,int st,int dr,int p)
{
if(N!=40000) printf("eroare %d %d %d %d\n",nod,st,dr,p);
if(st==p && dr==p)
m[nod] = a[p]; //frunza
else
{
int mij=(st+dr)/2;
if(p<=mij) update(2*nod,st,mij,p);
if(p>=mij+1) update(2*nod+1,mij+1,dr,p);
m[nod] = m[2*nod]>m[2*nod+1]?m[2*nod]:m[2*nod+1];
}
}
int query_tree(int nod,int st,int dr,int a,int b)
{
if(a<=st && dr<=b)
return m[nod];
else
{
int p1=-1,p2=-1,mij = (st+dr)/2;
if(a<=mij) p1=query_tree(2*nod,st,mij,a,b);
if(b>=mij+1) p2=query_tree(2*nod+1,mij+1,dr,a,b);
return p1>p2?p1:p2;
}
}
int main()
{
freopen("arbint.in","r",stdin);
freopen("arbint.out","w",stdout);
memset(m,255,sizeof(m));
scanf("%d %d",&N,&M);
for(int i=1;i<=N;++i)
{
scanf("%d",&a[i]);
update(1,1,N,i); if(N!=40000) printf("eroare %d ",i);
}
for(int q,p1,p2,i=0;i<M;++i)
{
scanf("%d %d %d",&q,&p1,&p2);
if(q)
{
a[p1] = p2;
update(1,1,N,p1);
}
else
printf("%d\n",query_tree(1,1,N,p1,p2));
}
return 0;
}