#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstdio>
#define MAXN 100001
using namespace std;
long M[4*MAXN + 66],N,Mx,NQ;
void update(int,int,int,int,int);
void query(int,int,int,int,int);
int main() {
freopen("arbint.in","r",stdin);
freopen("arbint.out","w",stdout);
int x,y,c;
scanf("%d%d",&N,&NQ);
for (int i=0;i<N;++i) {
scanf("%d",&x);
update(1,1,N,i+1,x);
}
//fprintf(stderr,"Segment tree:\n");
//for (int i=0;i<20;++i) fprintf(stderr,"%d %d\n",i,M[i]);
for (int i=0;i<NQ;++i) {
scanf("%d%d%d",&c,&x,&y);
switch (c) {
case 0:
Mx = -1;
query(1,x,y,1,N);
printf("%d\n",Mx);
break;
case 1:
//fprintf(stderr,"Update A[%d] -> %d\n",x,y);
update(1,1,N,x,y);
//for (int i=0;i<20;++i) fprintf(stderr,"%d %d\n",i,M[i]);
break;
default: break;
}
}
fclose(stdin);
fclose(stdout);
return 0;
}
void update(int node,int left,int right,int pos,int val) {
if (left == right) {
M[node] = val;
} else {
int div = (left + right) / 2;
if (pos <= div) update(node*2,left,div,pos,val);
else update(node*2+1,div+1,right,pos,val);
M[node] = max(M[node * 2],M[node * 2 + 1]);
}
}
void query(int node,int begin,int end,int left,int right) {
if (left >= begin && end >= right) {
if (Mx < M[node]) Mx = M[node];
} else {
int div = (left + right) / 2;
if (begin <= div) query(node*2,begin,end,left,div);
if (end > div) query(node*2+1,begin,end,div+1,right);
}
}