#include<stdio.h>
#define MAXN 100001
#include<algorithm>
FILE*fin,*fout;
void update(int nod,int st,int dr,int poz,int val);
int query(int nod,int st,int dr,int queryst,int querydr);
inline int left_son(int nod);
inline int right_son(int nod);
int arbint[4*MAXN];
int main()
{
fin=fopen("arbint.in","r");
fout=fopen("arbint.out","w");
int N,M;
fscanf(fin,"%d%d",&N,&M);
for(int i=1; i<=N; i++)
{
int x;
fscanf(fin,"%d",&x);
update(1,1,N,i,x);
}
for(int i=1; i<=M; i++)
{
int type,st,dr;
fscanf(fin,"%d%d%d",&type,&st,&dr);
if(type==0)
{
fprintf(fout,"%d\n",query(1,1,N,st,dr));
}
if(type==1)
{
update(1,1,N,st,dr);
}
}
fclose(fin);
fclose(fout);
return 0;
}
inline int left_son(int nod)
{
return 2*nod;
}
inline int right_son(int nod)
{
return 2*nod+1;
}
void update(int nod,int st,int dr,int poz,int val)
{
if(st==dr)
{
arbint[nod]=val;
return;
}
int mij=(st+dr)/2;
if(poz<=mij)
{
update(left_son(nod),st,mij,poz,val);
}
else
{
update(right_son(nod),mij+1,dr,poz,val);
}
arbint[nod]=std::max(arbint[left_son(nod)],arbint[right_son(nod)]);
}
int query(int nod,int st,int dr,int queryst,int querydr)
{
if(queryst<=st && dr<=querydr)
{
return arbint[nod];
}
if(querydr<st || dr<queryst)
{
return 0;
}
int mij=(st+dr)/2;
int a=query(left_son(nod),st,mij,queryst,querydr);
int b=query(right_son(nod),mij+1,dr,queryst,querydr);
return std::max(a,b);
}