#include <cstdio>
#include <limits>
#include <fstream>
using namespace std;
#define NMAX 100001
#define SIZE_MAX NMAX<<1
struct nod {
int st, dr;
int max;
};
int N, M;
int arb_int[SIZE_MAX];
void update(int nod, int st, int dr, int a, int b, int val) {
if (nod>SIZE_MAX) return;
if (a<=st && b>=dr) {
arb_int[nod] = val;
}
else {
int mid = (st+dr)/2, left=nod<<1, right=left|1;
if (a<=mid) update(left,st,mid,a,b,val);
if (b>mid) update(right,mid+1,dr,a,b,val);
int maxLeft = (left <= SIZE_MAX)?arb_int[left]:INT_MIN;
int maxRight = (right <= SIZE_MAX)?arb_int[right]:INT_MIN;
arb_int[nod] = max(maxLeft,maxRight);
}
}
int query(int nod, int st, int dr, int a, int b) {
if (nod > SIZE_MAX) return INT_MIN;
if (a<=st && b>=dr) {
return arb_int[nod];
}
int mid = (st+dr)/2;
int max_st = INT_MIN, max_dr=INT_MIN;
if (a<=mid) max_st = query(nod<<1,st,mid,a,b);
if (b>mid) max_dr = query((nod<<1)|1,mid+1,dr,a,b);
return max(max_st, max_dr);
}
int main() {
int i,x,a,b;
freopen("arbint.in","r",stdin);
freopen("arbint.out","w",stdout);
scanf("%d %d",&N,&M);
for (i=1;i<=N;i++) {
scanf("%d",&x);
update(1,1,N,i,i,x);
}
for (i=1;i<=M;i++) {
scanf("%d %d %d",&x,&a,&b);
if (x)
update(1,1,N,a,a,b);
else
printf("%d\n",query(1,1,N,a,b));
}
return 0;
}