#include <iostream>
#include <fstream>
std::ifstream f("arbint.in");
std::ofstream g("arbint.out");
int n, m, x, y, t, maxim, start, finish, st, dr, tree[100001];
void update(int nod, int poz, int val, int st, int dr){
if(st==dr){ tree[nod] = val; return; }
int mid = (st+dr)/2;
if( poz<=mid ) update(2*nod, poz, val, st, mid);
if( poz>mid ) update(2*nod+1, poz, val, mid+1, dr);
if( tree[2*nod] >= tree[2*nod+1] ) tree[nod] = tree[2*nod];
else tree[nod] = tree[2*nod+1];
}
void query(int nod, int &maxim, int start, int finish, int st, int dr){
if( start <= st && dr<=finish ){if( maxim<tree[nod] ) maxim=tree[nod]; return;}
int mid = (st+dr)/2;
if( start<=mid ) query(2*nod, maxim, start, finish, st, mid);
if( mid<finish ) query(2*nod+1, maxim, start, finish, mid+1, dr);
}
int main() {
f>>n>>m;
for(int i=1 ; i<=n ; i++){
f>>x;
update(1, i, x, 1, n);
}
for(int i=1 ; i<=m ; i++){
f>>t>>x>>y;
if(t==0){
maxim = -1;
start = x;
finish = y;
query(1, maxim, start, finish, 1, n);
//std::cout<<maxim<<"\n";
g<<maxim<<"\n";
}
if(t==1){
update(1, x, y, 1, n);
}
}
return 0;
}