#include <cstdio>
using namespace std;
#define maxn 100005
#define MAXIM 10010
int maximul[maxn*4+10];
int max,poz,val,c1,c2;
int pozitie=MAXIM-1;
char buff[MAXIM];//citesc bucati de cate maxim 10005 caractere
void cit(int &nr){
nr=0;
while(buff[pozitie]<'0' || buff[pozitie]>'9')//cat timp nu e cifra, treci mai departe
if (++pozitie==MAXIM){
fread (buff,1,MAXIM,stdin);
pozitie=0;
}
while('0'<=buff[pozitie] && buff[pozitie]<='9'){//cat timp e cifra
nr=nr*10+(buff[pozitie]-'0');
if (++pozitie==MAXIM){
fread (buff,1,MAXIM,stdin);
pozitie=0;
}
}
}
void react(int nod,int li, int ls){
if(li==ls){
maximul[nod]=val;
return;
}
int mij=li+(ls-li)/2;
//o iau prin stanga
if(poz<=mij)react(nod*2,li,mij);
else react(nod*2+1,mij+1,ls);//prin dreapta
//reactualizez tot ce e mai sus de locul unde am introdu noua valoare
//e maximul dintre cele doua intervale
if(maximul[nod*2]>maximul[nod*2+1])maximul[nod]=maximul[nod*2];
else maximul[nod]=maximul[nod*2+1];
}
void afla_maximul(int nod,int li, int ls){
//daca intervalul li, ls e inclus in cel cautat, atunci incerc sa reactualizez maximul
if(c1<=li && ls<=c2){
if(maximul[nod]>max)max=maximul[nod];
return;
}
//daca intervalul care ma intereseaza nu e inclus, inseamna ca e intersectie
int mij=li+(ls-li)/2;
if(c1<=mij)afla_maximul(nod*2,li,mij);
if(c2>mij)afla_maximul(nod*2+1,mij+1,ls);
}
int main(){
freopen("arbint.in","r",stdin);
freopen("arbint.out","w",stdout);
int i;
int cod, a,b,m,n;
cit(n);
cit(m);
//citesc vectorul
for(i=1;i<=n;i++){
poz=i;
cit(a);
val=a;
react(1,1,n);//sunt in nodul 1 (adica intervalul 1,n), pe total vreau sa bag valoare a pe pozitia poz
//vreau sa fac asta pastrand vectorul maximul actualizat
}
for(i=0;i<m;i++){
cit(cod);
cit(a);
cit(b);
if(cod==0){//deci afisare de maxim
max=-1;//toate val sunt pozitive, e ok sa init cu -1
//trebuie sa aflu unde in vector se afla intervalul a,b
c1=a;
c2=b;
afla_maximul(1,1,n);
printf("%d\n",max);//sunt pe locul 1, si intervalul este 1,n
}else{//schimb valoarea unui element
poz=a;
val=b;
react(1,1,n);
}
}
return 0;
}