//
// Created by Lucifer on 24.03.2024.
//
#include <bits/stdc++.h>
using namespace std;
struct segmentTree{
int n;
vector<int> st;
void init(int sz){
this->n = sz;
st.resize(4*n,INT_MIN);
}
void build(vector<int> &v){
build(0,n-1,0,v);
}
void build(int start,int end, int node, vector<int> &v){
if(start == end){
st[node] = v[start];
return;
}
int mid = (start+end)/2;
build(start,mid,2*node+1,v);
build(mid+1,end,2*node+2,v);
st[node] = max(st[2*node+1],st[2*node+2]);
}
int query(int l,int r){
return query(0,n-1,l,r,0);
}
int query(int start,int end,int l,int r,int node){
if(start>r || end<l) return INT_MIN;
if(start>=l && end<=r) return st[node];
int mid = (start+end)/2;
int q1 = query(start,mid,l,r,2*node+1);
int q2 = query(mid+1,end,l,r,2*node+2);
return max(q1,q2);
}
void update(int x,int y){
update(0,n-1,0,x,y);
}
void update(int start,int end,int node, int index,int value){
if(start == end){
st[node] = value;
return;
}
int mid = (start+end)/2;
if(index<=mid){
update(start,mid,2*node+1,index,value);
}else{
update(mid+1,end,2*node+2,index,value);
}
st[node] = max(st[2*node+1],st[2*node+2]);
}
};
int main(){
freopen("arbint.in","r",stdin);
freopen("arbint.out","w",stdout);
int n,x,k;cin>>n>>k;
vector<int> v;
for(int i = 0;i<n;i++){
cin>>x;
v.push_back(x);
}
segmentTree tree;
tree.init(n);
tree.build(v);
while(k--){
int a,b,c;
cin>>a>>b>>c;
if(a == 0)
cout<<tree.query(b-1,c-1)<<'\n';
else tree.update(b-1,c);
}
return 0;
}