#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=0,b=0;
int val=0;
} 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);
}
}
int x;
void get_x(int n)
{
while(n)
{
x++;
n=n>>1;
}
}
inline void update(int nod)
{
while(tata(nod)!=nod)
{
v[nod].val=max(v[fiu1(nod)].val,v[fiu2(nod)].val);
nod=tata(nod);
}
}
int sol=0;
void query(int nod,int a,int b)
{
if(v[nod].a>=a&&v[nod].b<=b)
{
sol=max(sol,v[nod].val);
return;
}
if(a>=v[fiu2(nod)].a)
query(fiu2(nod),a,b);
else if(b<=v[fiu1(nod)].b)
query(fiu1(nod),a,b);
else
{
query(fiu1(nod),a,v[fiu1(nod)].b);
query(fiu2(nod),v[fiu2(nod)].a,b);
}
}
int n,m;
int main()
{
freopen("arbint.in","r",stdin);
freopen("arbint.out","w",stdout);
scanf("%d%d",&n,&m);
int np=n;
while((n&(n-1))!=0)
n++;
get_x(n);
build(1,1,n);
for(int i=1;i<=np;i++)
{
int a;
scanf("%d",&a);
v[(1<<(x-1))+i-1].val=a;
}
for(int i=(1<<(x-1))-1;i>=1;i--)
{
v[i].val=max(v[fiu1(i)].val,v[fiu2(i)].val);
}
/*for(int i=1,poz=1;i<=n;i=i*2)
{
for(int j=1;j<=i;j++,poz++)
{
printf("%d ",v[poz].val);
}
printf("\n");
}*/
for(;m;m--)
{
int o,a,b;
scanf("%d%d%d",&o,&a,&b);
if(o==1)
{
v[(1<<(x-1))+a-1].val=b;
update(tata((1<<(x-1))+a-1));
}
else
{
sol=0;
query(1,a,b);
printf("%d\n",sol);
}
}
return 0;
}