#include <cstdio>
#include <algorithm>
#define Nmax (1<<18)+666
#define INF 0x3f3f3f3f
using namespace std;
int N,M,A,B,x,pos,answer;
char Buffer;
void scan(int &A,int endline)
{
A = 0;
do
{
Buffer = fgetc(stdin);
if('0' <= Buffer && Buffer <='9')
A = A*10 + Buffer-48;
}while('0' <= Buffer && Buffer <='9');
if(!endline)
while(Buffer != '\n')
Buffer = fgetc(stdin);
}
class SegmentTree{
private:
int range[ Nmax ];
public:
void Build(const int li,const int lf,const int pz)
{
if(li == lf)
{
scan(x,li^N);
range[pz] = x;
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(const int li,const int lf,const int pz)
{
if(li == lf)
{
range[ pz ] = x;
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(const int li,const int lf,const 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(B > m) Querry(m+1,lf,(pz<<1)|1);
}
};
SegmentTree aint;
void Read()
{
scan(N,1),scan(M,0);
aint.Build(1,N,1);
}
void Solve()
{
int op;
for(int i = 1; i<= M;++i)
{
scan(op,1);
if(!op)
{
answer = -INF;
scan(A,1),scan(B,0);
aint.Querry(1,N,1);
printf("%d\n",answer);
}
else
{
scan(pos,1),scan(x,0);
aint.Update(1,N,1);
}
}
}
int main()
{
freopen("arbint.in","r",stdin);
freopen("arbint.out","w",stdout);
Read();
Solve();
return 0;
}