#include <fstream>
#include <cmath>
using namespace std;
const int maxN=1e5+2;
int v[maxN];
int n,q,sqroot;
int bucket[maxN];
inline int getBucket(int pos){
return (pos-1)/sqroot+1;
}
void build(){
for(int i=1; i<=n; i++)
if(i%sqroot==1)
bucket[(i-1)/sqroot+1]=v[i];
else
bucket[(i-1)/sqroot+1]=max(v[i],bucket[(i-1)/sqroot+1]);
}
void update(int pos,int val){
v[pos]=val;
int where=getBucket(pos);
bucket[where]=v[(where-1)*sqroot+1];
for(int i=(where-1)*sqroot+2; i<=where*sqroot; i++)
bucket[where]=max(bucket[where],v[i]);
}
int bruteQuery(int st,int dr){
int res=0;
for(int i=st; i<=dr; i++)
res=max(res,v[i]);
return res;
}
int query(int st,int dr){
int leftBucket=getBucket(st);
int rightBucket=getBucket(dr);
if(leftBucket==rightBucket)
return bruteQuery(st,dr);
int res=0;
for(int i=st; i<=leftBucket*sqroot; i++)
res=max(res,v[i]);
for(int i=leftBucket+1; i<rightBucket; i++)
res=max(res,bucket[i]);
for(int i=(rightBucket-1)*sqroot+1; i<=dr; i++)
res=max(res,v[i]);
return res;
}
int main()
{
ifstream f("arbint.in");
ofstream g("arbint.out");
f>>n>>q;
sqroot=sqrt(n)+1;
for(int i=1; i<=n; i++)
f>>v[i];
build();
while(q--){
int op,x,y;
f>>op>>x>>y;
if(op==0)
g<<query(x,y)<<'\n';
else
update(x,y);
}
return 0;
}