#include <stdio.h>
long n,m,i,x,y,z;
long v[100001];
struct arbore {long valoare; long st; long dr; };
struct arbore arb[250000];
void creaza(long poz, long st, long dr)
{
arb[poz].st=st;
arb[poz].dr=dr;
if(st!=dr)
{
long mij=(st+dr)/2;
creaza(2*poz, st, mij);
creaza(2*poz+1,mij+1,dr);
}
}
void actualizare1(long nod, long valoare, long 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);
}
}
long actualizare2(long nod,long valoare,long pozitie)
{
if(arb[nod].st<= pozitie && pozitie<= arb[nod].dr)
{
if(arb[nod].st==arb[nod].dr){arb[nod].valoare=valoare; return valoare; }
else
{
long fiust,fiudr;
long max;
fiust=actualizare2(2*nod,valoare,pozitie);
fiudr=actualizare2(2*nod+1,valoare,pozitie);
if(fiust<fiudr)max=fiudr; else max=fiust;
arb[nod].valoare=max;
return max;
}
}
else return arb[nod].valoare;
}
long interogare(long nod, long a, long b)
{
if(a<=arb[nod].st && arb[nod].dr<=b)return arb[nod].valoare;
else
{
long mij=(arb[nod].st+arb[nod].dr)/2;
long fiust=0,fiudr=0;
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("%ld %ld",&n,&m);
for(i=1; i<=n; i++) scanf("%ld",&v[i]);
creaza(1,1,n);
for(i=1; i<=n; i++)actualizare1(1,v[i],i);
for(i=1; i<=m; i++)
{
scanf("%ld %ld %ld",&x, &y, &z);
if(x){long zz=actualizare2(1,z,y); }
else
{
long zzz=interogare(1,y,z);
printf("%ld\n",zzz);
}
}
return 0;
}