#include <fstream>
#include <stdio.h>
#define INF 2000000000
using namespace std;
struct nod{
int nr;
nod *st,*dr;
}*R;
int N,M;
int *V;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
nod * CreateNewPointer(){
nod *q=new nod;
q->nr=0;
q->st=q->dr=0;
return q;
}
int Maxim(int a,int b)
{
if(a>b)
{
return a;
}
return b;
}
int Insert(nod *p,int st,int dr)
{
if(st==dr){
p->nr=V[st];
return V[st];
}
int m=(st+dr)/2,nr1,nr2;
p->st=CreateNewPointer();
p->dr=CreateNewPointer();
nr1=Insert(p->st,st,m);
nr2=Insert(p->dr,m+1,dr);
p->nr=Maxim(nr1,nr2);
return p->nr;
}
int Search(nod *p,int st,int dr,int a,int b)
{
if(a<=st&&dr<=b)
{
return p->nr;
}
int m=(st+dr)/2,nr1=-INF,nr2=-INF;
if(a<=m&&p->st!=0)
nr1=Search(p->st,st,m,a,b);
if(b>m&&p->dr!=0)
nr2=Search(p->dr,m+1,dr,a,b);
return Maxim(nr1,nr2);
}
int Update(nod *p,int st,int dr,int a,int b)
{
if(st==dr)
{
p->nr=b;
return b;
}
int m=(st+dr)/2,nr1=-INF,nr2=-INF;
if(a<=m)
{
if(p->st==0)
p->st=CreateNewPointer();
nr1=Update(p->st,st,m,a,b);
if(p->dr)
nr2=p->dr->nr;
}
else
{
if(p->dr==0)
p->dr=CreateNewPointer();
nr1=Update(p->dr,m+1,dr,a,b);
if(p->st)
nr2=p->st->nr;
}
p->nr=Maxim(nr1,nr2);
return p->nr;
}
void Read()
{
fin>>N>>M;
int i,nr;
V=new int [N+5];
R=CreateNewPointer();
for(i=1;i<=N;i++)
{
fin>>nr;
Update(R,1,N,i,nr);
}
}
int main()
{
Read();
// Insert(R,1,N);
int i,a,b,c;
for(i=1;i<=M;i++)
{
fin>>c>>a>>b;
if(c==0)
{
// printf("%d\n",Search(R,1,N,a,b));
fout<<Search(R,1,N,a,b)<<'\n';
}
else
Update(R,1,N,a,b);
}
fout.close();
fin.close();
return 0;
}