#include <fstream>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
struct node{
int value;
node *left;
node *right;
};
int N , Q ;
void Build(node *&Tree,int p,int u){
if(p==u){
fin>> Tree -> value;
return;
}
Tree -> left = new node;
Tree -> right = new node;
int mid=(p + u) >> 1;
Build(Tree -> left,p,mid);
Build(Tree -> right,mid+1,u);
Tree -> value = max(Tree -> left -> value,Tree -> right -> value);
}
void Update(node *&Tree,int p,int u,int pos,int val){
if(p==u){
Tree -> value = val;
return;
}
int mid = (p + u) >> 1;
if(pos <= mid)
Update(Tree -> left,p,mid,pos,val);
else
Update(Tree -> right,mid+1,u,pos,val);
Tree -> value = max(Tree -> left -> value,Tree -> right -> value);
}
int Query(node *&Tree,int p,int u,int lb,int ub){
if(p >= lb && u <= ub){
return Tree -> value;
}
int mid = (p + u) >> 1;
int maxim = -0x3f3f3f3f;
if(mid >= lb)
maxim = max(maxim,Query(Tree -> left,p,mid,lb,ub));
if(mid + 1 <= ub)
maxim=max(maxim,Query(Tree -> right,mid+1,u,lb,ub));
return maxim;
}
int main(){
fin >> N >> Q ;
node *Tree= new node;
Build(Tree,1,N);
while(Q--){
int Task;
fin>> Task;
if(Task == 0){
int Lower_Bound, Upper_Bound;
fin >> Lower_Bound >> Upper_Bound;
fout << Query(Tree,1,N,Lower_Bound,Upper_Bound) << "\n";
}
else{
int Position, New_Value;
fin >> Position >> New_Value;
Update(Tree,1,N,Position,New_Value);
}
}
return 0;
}