#include <cstdio>
#include <algorithm>
using namespace std;
int m,n;
struct arb
{
int st,dr,mx=0;
}nod[100005];
FILE *in=fopen("arbint.in","r"),*out=fopen("arbint.out","w");
void constr(int poz, int val,int decons)
{
if(nod[decons].st==nod[decons].dr)
{
nod[decons].mx=val;
return;
}
nod[decons].mx=max(val,nod[decons].mx);
int mij=(nod[decons].dr+nod[decons].st)/2;
if(poz<=mij)
nod[decons*2].st=nod[decons].st,
nod[decons*2].dr=mij,
constr(poz,val,decons*2);
else
nod[decons*2+1].st=mij+1,
nod[decons*2+1].dr=nod[decons].dr,
constr(poz,val,decons*2+1);
}
void inloc(int poz,int val, int dever)
{
if(nod[dever].st==nod[dever].dr)
{
nod[dever].mx=val;
return;
}
int mij=(nod[dever].dr+nod[dever].st)/2;
if(poz<=mij)
inloc(poz,val,dever*2),
nod[dever].mx=max(nod[dever*2+1].mx,nod[dever*2].mx);
else
inloc(poz,val,dever*2+1),
nod[dever].mx=max(nod[dever*2].mx,nod[dever*2+1].mx);
}
int maxim(int st, int dr)
{
int poz=1,mij,ant;
while(1)
{
mij=(nod[poz].st+nod[poz].dr)/2;
if(st==nod[poz].st)
{
if(dr>nod[poz].dr)break;
else if(dr==nod[poz].dr)return nod[poz].mx;
else poz*=2;
}
else
{
if(st<=mij)
poz=poz*2;
else
poz=poz*2+1;
}
}
ant=poz;
mij=nod[poz].mx;
while(1)
{
if(poz%2)
{
++poz;
if(nod[poz].mx==0)poz/=2;
}
else
poz/=2;
if(nod[poz].dr>dr)
{
poz=ant*2+1;
if(nod[poz].mx==0) ++poz;
return max(mij,nod[poz].mx);
}
if(nod[poz].dr==dr)return max(mij,nod[poz].mx);
if(nod[poz].dr<dr) mij=max(mij,nod[poz].mx),ant=poz;
}
return mij;
}
/*
void scriefrum()
{
int i,lvl=2,k;
for(k=1;k<n;)k*=2;
k*=2;
for(i=1;i<k;++i)
{
if(lvl==i)
fprintf(out,"\n"),
lvl*=2;
fprintf(out,"% 3d ",nod[i].mx);
}
fprintf(out,"\n\n\n");
}
*/
int main()
{
fscanf(in,"%d%d",&n,&m);
nod[1].dr=n-1;
nod[1].st=0;
int i,a,b,cmnd;
for(i=0;i<n;++i)
fscanf(in,"%d",&a),
constr(i,a,1);
for(i=0;i<m;++i)
{
fscanf(in,"%d%d%d",&cmnd,&a,&b);
if(cmnd)inloc(a-1,b,1);
else fprintf( out,"%d\n",maxim(a-1,b-1));
}
return 0;
}