#include <cstdio>
using namespace std;
inline int max(int a,int b)
{
if(a>b)
return a;
return b;
}
inline int tata(const int nod)
{
return nod/2;
}
inline int fiu1(const int nod)
{
return nod<<1;
}
inline int fiu2(const int nod)
{
return (nod<<1)+1;
}
struct sp
{
int a,b;
int val;
} v[500000];
void build(const int nod,const int a,const int b)
{
v[nod].a=a;
v[nod].b=b;
v[nod].val=0;
if(a<b)
{
int mij=(a+b)>>1;
build(fiu1(nod),a,mij);
build(fiu2(nod),mij+1,b);
}
}
void update(const int val,const int nod,const int a)
{
if(v[nod].a<v[nod].b)
{
int mij=(v[nod].a+v[nod].b)>>1;
if(a<=mij)
{
update(val,fiu1(nod),a);
}
else if(a>mij)
{
update(val,fiu2(nod),a);
}
v[nod].val=max(v[fiu1(nod)].val,v[fiu2(nod)].val);
}
else v[nod].val=val;
}
int query(const int nod,const int a,const int b)
{
int sol=0;
if(v[nod].a>=a&&v[nod].b<=b)
{
return v[nod].val;
}
if(a<=v[fiu1(nod)].b)
sol=max(sol,query(fiu1(nod),a,b));
if(b>=v[fiu2(nod)].a)
sol=max(sol,query(fiu2(nod),a,b));
return sol;
}
int n,m;
int main()
{
freopen("arbint.in","r",stdin);
freopen("arbint.out","w",stdout);
scanf("%d%d",&n,&m);
build(1,1,n);
for(int i=1;i<=n;i++)
{
int a;
scanf("%d",&a);
update(a,1,i);
}
for(int i=1;i<=m;i++)
{
int o,a,b;
scanf("%d%d%d",&o,&a,&b);
if(o==1)
{
update(b,1,a);
}
else if(o==0)
{
printf("%d\n",query(1,a,b));
}
}
return 0;
}