#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <cmath>
#define DIM 3666013
using namespace std;
char buffer[DIM];
int poz = DIM - 1;
void Scanf(int &A){
A = 0;
while('0' > buffer[poz] || buffer[poz] > '9')
if(++poz == DIM)
fread(buffer,1,DIM,stdin),poz = 0;
while('0' <= buffer[poz] && buffer[poz] <= '9')
{
A = A * 10 + buffer[poz] - 48;
if(++poz == DIM)
fread(buffer,1,DIM,stdin),poz = 0;
}
}
int answer,pos,_newX,A,B;
class SegmentTree{
public:
vector<int> range;
void Resize(int N)
{
range.resize(1<<((int)ceil(log2((double)N))+1));
}
void Build(int li,int lf,int pz)
{
if(li == lf){
Scanf(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(B > m )
Querry(m+1,lf,(pz<<1)|1);
}
};
int N,M;
SegmentTree Aint;
int main()
{
freopen("arbint.in","r",stdin);
freopen("arbint.out","w",stdout);
Scanf(N);Scanf(M);
Aint.Resize(N);
Aint.Build(1,N,1);
int Tip;
for(int i = 1; i <= M; ++i)
{
Scanf(Tip);
if(Tip == 0){
Scanf(A);Scanf(B);
answer = 0;
Aint.Querry(1,N,1);
printf("%d\n",answer);
}
else
{
Scanf(pos);Scanf(_newX);
Aint.Update(1,N,1);
}
}
return 0;
}