#include<iostream>
#include<fstream>
#include<vector>
#include<cstring>
#include<map>
#include<algorithm>
#include<set>
#include<deque>
#include<queue>
using namespace std;
ifstream in("arbint.in");
ofstream out("arbint.out");
const int mx=1e5;
int n,m,v[mx],tree[3*mx];
void read(){
in>>n>>m;
for(int i=0;i<n;i++){
in>>v[i];
}
}
void build_tree(int index,int l,int r){
if(l==r){
tree[index]=v[l];
}
else{
int m=(l+r)/2;
build_tree(index*2,l,m);
build_tree(index*2+1,m+1,r);
tree[index]=max(tree[index*2],tree[index*2+1]);
}
}
int query(int index,int l,int r,int a,int b){
if(l>=a && r<=b){
return tree[index];
}
int m=(l+r)/2,result=-1;
if(a<=m){
result=max(result,query(index*2,l,m,a,b));
}
if(b>m){
result=max(result,query(index*2+1,m+1,r,a,b));
}
return result;
}
void update(int index,int l,int r,int pos,int value){
if(l==r){
tree[index]=value;
}
else{
int m=(l+r)/2;
if(pos<=m){
update(index*2,l,m,pos,value);
}
else{
update(index*2+1,m+1,r,pos,value);
}
tree[index]=max(tree[index*2],tree[index*2+1]);
}
}
void solve(){
int q,l,r;
build_tree(1,0,n-1);
while(m--){
in>>q>>l>>r;
if(q==0){
out<<query(1,0,n-1,l-1,r-1)<<'\n';
}
else{
update(1,0,n-1,l-1,r);
}
}
}
int main(){
read();
solve();
return 0;
}