#include<stdio.h>
#include<assert.h>
#include<algorithm>
using namespace std;
struct inte_tree{
int val,st_inte,dr_inte;
inte_tree *st_tree,*dr_tree;
};
void create_tree(inte_tree *p,int left,int right){
p->val=0;
p->st_inte=left;
p->dr_inte=right;
if(left==right)
return;
p->st_tree=new inte_tree;
p->dr_tree=new inte_tree;
create_tree(p->st_tree,left,(right+left)/2);
create_tree(p->dr_tree,(right+left)/2+1,right);
}
void update(inte_tree *p,int pos,int value){
if(p->st_inte==p->dr_inte){
p->val=value;
return ;
}
if((p->dr_inte+p->st_inte)/2>=pos)
update(p->st_tree,pos,value);
else
update(p->dr_tree,pos,value);
p->val=max((p->st_tree)->val,(p->dr_tree)->val);
}
int query(inte_tree *p,int left,int right){
if(left==right)
return p->val;
if(p->st_inte==left && p->dr_inte==right)
return p->val;
int sol;
if(left<=(p->dr_inte+p->st_inte)/2)
sol=query(p->st_tree,max(left,p->st_inte),min((p->dr_inte+p->st_inte)/2,right));
if(right>(p->dr_inte+p->st_inte)/2)
sol=max(sol,query(p->dr_tree,max((p->dr_inte+p->st_inte)/2+1,left),min(right,p->dr_inte)));
return sol;
}
int main(){
assert(freopen("arbint.in","r",stdin)!=NULL);
assert(freopen("arbint.out","w",stdout)!=NULL);
int i,n,m,q_type,q_val1,q_val2,s,x;
inte_tree cop;
scanf("%d%d",&n,&m);
create_tree(&cop,1,n);
for(i=1;i<=n;++i){
scanf("%d",&x);
update(&cop,i,x);
}
for(i=1;i<=m;++i){
scanf("%d%d%d",&q_type,&q_val1,&q_val2);
if(q_type==1)
update(&cop,q_val1,q_val2);
else{
s=query(&cop,q_val1,q_val2);
printf("%d\n",s);
}
}
return 0;
}