#include <stdio.h>
int n,m,i,x,y,z;
int v[100001];
struct arbore {int valoare; int st; int dr; };
struct arbore arb[200000];
void creaza(int poz, int st, int dr)
{
arb[poz].st=st;
arb[poz].dr=dr;
if(st!=dr)
{
int mij=(st+dr)/2;
creaza(2*poz, st, mij);
creaza(2*poz+1,mij+1,dr);
}
}
void actualizare1(int nod, int valoare, int pozitie)
{
if(arb[nod].st<=pozitie && pozitie<= arb[nod].dr)
{
if(arb[nod].valoare<valoare)arb[nod].valoare=valoare;
actualizare1(2*nod, valoare, pozitie);
actualizare1(2*nod+1,valoare,pozitie);
}
}
int actualizare2(int nod,int valoare,int pozitie)
{
if(arb[nod].st<= pozitie && pozitie<= arb[nod].dr)
{
if(arb[nod].st==arb[nod].dr){arb[nod].valoare=valoare; return valoare; }
else
{
int fiust,fiudr;
fiust=actualizare2(2*nod,valoare,pozitie);
fiudr=actualizare2(2*nod+1,valoare,pozitie);
int max; if(fiust<fiudr)max=fiudr; else max=fiust;
arb[nod].valoare=max;
return max;
}
}
else return arb[nod].valoare;
}
int interogare(int nod, int a, int b)
{
if(a<=arb[nod].st && arb[nod].dr<=b)return arb[nod].valoare;
else
{
int mij=(arb[nod].st+arb[nod].dr)/2;
int fiust=0,fiudr=0;
int max;
if(a<=mij)fiust=interogare(2*nod,a,b);
if(b>mij)fiudr=interogare(2*nod+1,a,b);
if(fiust<fiudr)return fiudr;
else return fiust;
}
}
int main(void)
{
freopen("arbint.in","r",stdin);
freopen("arbint.out","w",stdout);
scanf("%d %d",&n,&m);
for(i=1; i<=n; i++) scanf("%d",&v[i]);
creaza(1,1,n);
for(i=1; i<=n; i++)actualizare1(1,v[i],i);
for(i=1; i<=m; i++)
{
scanf("%d %d %d",&x, &y, &z);
if(x){int zz=actualizare2(1,z,y); }
else
{
int zzz=interogare(1,y,z);
printf("%d\n",zzz);
}
}
return 0;
}