#include <cstdio>
#include <cctype>
#include <cstdlib>
#include <cstring>
#define BUFF_SIZE (1<<17)
#define MAXN 1000000
#define max2(a, b) ( a>b ? a : b )
FILE *fin, *fout;
int n, pos=BUFF_SIZE, pos1, poz, rasp, left, right;
signed char buff[BUFF_SIZE], buff1[BUFF_SIZE], ch;
int v[MAXN+1], arb[MAXN+1];
inline char next(){
if(pos==BUFF_SIZE){
fread(buff, BUFF_SIZE, 1, fin);
pos=0;
}
return buff[pos++];
}
inline int read(){
int x=0;
ch=next();
while(!isdigit(ch)) ch=next();
while(isdigit(ch)){
x=x*10+ch-'0';
ch=next();
}
return x;
}
inline void baga(){
buff1[pos1++]=ch;
if(pos1==BUFF_SIZE){
fwrite(buff1, BUFF_SIZE, 1, fout);
pos1=0;
}
}
inline void insert(int x){
char s[11];
itoa(x, s, 10);
int k=strlen(s);
while(k>0){
k--;
ch=s[k];
baga();
}
}
inline void start(int leaf, int left, int right){
if(left==right){
arb[leaf]=v[left];
return;
}
int m=(left+right)/2;
start(2*leaf, left, m);
start(2*leaf+1, m+1, right);
arb[leaf]=max2(arb[leaf*2], arb[leaf*2+1]);
}
inline void update(){
int leaf=1, left=1, right=n, m;
while(left<right){
m=(left+right)/2;
if(poz<=m) right=m, leaf*=2;
else left=m+1, leaf=leaf*2+1;
}
///facem o cautare binara ca sa vedem pe ce nod e intervalul (poz, poz)
arb[leaf]=v[left];
leaf/=2;
while(leaf){
arb[leaf]=max2(arb[leaf*2], arb[leaf*2+1]);
leaf/=2;
}
}
inline void query(int leaf, int st, int dr){
if(left<=st && dr<=right){
rasp=max2(rasp, arb[leaf]);///daca (st, dr) e inclus in (left, right)
return;
}
if(dr<left || right<st) return;///daca nu se intersecteaza
int m=(st+dr)/2;
if(left<=m) query(leaf*2, st, m);///investigam fiecare child node
if(right>=m+1) query(leaf*2+1, m+1, dr);
}
int main(){
int m, a, b, x, i;
fin=fopen("arbint.in", "r");
fout=fopen("arbint.out", "w");
n=read();
m=read();
for(i=1; i<=n; i++)
v[i]=read();
start(1, 1, n);
for(i=0; i<m; i++){
x=read();
a=read();
b=read();
if(x==0){
left=a; right=b;
rasp=0;
query(1, 1, n);
insert(rasp);
ch='\n';
baga();
}
else{
poz=a;
v[poz]=b;
update();
}
}
if(pos1>0) fwrite(buff1, pos1, 1, fout);
fclose(fin);
fclose(fout);
return 0;
}