#include <cstdio>
#include <algorithm>
#define Nmax (1<<18)+666
using namespace std;
int _newX,answer,pos,A,B;
int N,M;
#define DIM 500000
char buff[DIM];
int poz=DIM-1;
void citeste(int &numar)
{
numar = 0;
while (buff[poz] < '0' || buff[poz] > '9')
if (++poz == DIM)
fread(buff,1,DIM,stdin),poz=0;
while ('0'<=buff[poz] && buff[poz]<='9')
{
numar = numar*10 + buff[poz] - '0';
if (++poz == DIM)
fread(buff,1,DIM,stdin),poz=0;
}
}
class SegmentTree{
private:
int range[Nmax];
public:
void Build(int li,int lf,int pz)
{
if(li == lf)
{
scanf("%d",&range[pz]);
return;
}
int m = li +((lf-li)>>1);
Build(li,m,pz<<1);
Build(m+1,lf,(pz<<1)|1);
range[pz] = max(range[pz<<1],range[(pz<<1)|1]);
}
void Update(int li,int lf,int pz)
{
if(li == lf)
{
range[pz] = _newX;
return;
}
int m = li+((lf-li)>>1);
if(pos <= m)Update(li,m,pz<<1);
else Update(m+1,lf,(pz<<1)|1);
range[pz] = max(range[pz<<1],range[(pz<<1)|1]);
}
void Querry(int li,int lf,int pz)
{
if(A <= li && lf <= B)
{
answer = max(answer,range[pz]);
return;
}
int m = li +((lf-li)>>1);
if(A <= m) Querry(li,m,pz<<1);
if(m < B) Querry(m+1,lf,(pz<<1)|1);
}
}Aint;
void read()
{
scanf("%d%d",&N,&M);
Aint.Build(1,N,1);
}
void querries()
{
int tip,a,b;
while(M--)
{
scanf("%d%d%d",&tip,&a,&b);
if(tip == 0)
{
A = a;
B = b;
answer = 0;
Aint.Querry(1,N,1);
printf("%d\n",answer);
}
else
{
pos = a;
_newX = b;
Aint.Update(1,N,1);
}
}
}
int main()
{
freopen("arbint.in","r",stdin);
freopen("arbint.out","w",stdout);
read();
querries();
return 0;
}