#include <fstream>
#include <vector>
using std::vector;
unsigned read(std::istream &in,vector<unsigned> &tree, unsigned node, unsigned cleft, unsigned cright){
if(cleft==cright){
in>>tree[node];
return tree[node];
}
else{
unsigned mid = (cleft+cright)>>1;
tree[node] = read(in,tree,node<<1,cleft,mid);
unsigned right = read(in,tree,(node<<1)+1,mid+1,cright);
if(right>tree[node]) tree[node]=right;
return tree[node];
}
}
unsigned alter(unsigned pos, unsigned val, vector<unsigned> &tree, unsigned node, unsigned cleft, unsigned cright){
// !!! cleft<=pos and pos<=cright
if(cleft==cright) return tree[node]=val;
else{
unsigned mid = (cleft+cright)>>1;
if(pos<=mid){
tree[node]=tree[(node<<1)+1];
unsigned left = alter(pos,val,tree,node<<1,cleft,mid);
if(left>tree[node]) tree[node]=left;
}
else{
tree[node]=tree[node<<1];
unsigned right = alter(pos,val,tree,(node<<1)+1,mid+1,cright);
if(right>tree[node]) tree[node]=right;
}
return tree[node];
}
}
unsigned getmax(const unsigned a,const unsigned b,const vector<unsigned> &tree,const unsigned node,const unsigned cleft,const unsigned cright){
// !!! cleft <= a <= b <= cright
if(cleft==cright) return tree[node];
else{
unsigned mid = (cleft+cright)>>1;
if(b<=mid) return getmax(a,b,tree,node<<1,cleft,mid);
else if(a<=mid){
unsigned left=getmax(a,mid,tree,node<<1,cleft,mid);
unsigned right=getmax(mid+1,b,tree,(node<<1)+1,mid+1,cright);
if(left>right) return left;
else return right;
}
else return getmax(a,b,tree,(node<<1)+1,mid+1,cright);
}
}
int main(){
std::ifstream fin("arbint.in");
std::ofstream fout("arbint.out");
unsigned N,M;
fin>>N>>M;
vector<unsigned> tree( ( (N&(N-1))==0 )?(N<<1):(N<<2) ,0);
unsigned temp1,temp2;
char c;
read(fin,tree,1,1,N);
while(M--){
fin>>c>>temp1>>temp2;
if(c=='0') fout<<getmax(temp1,temp2,tree,1,1,N)<<'\n';
else alter(temp1,temp2,tree,1,1,N);
}
}