#include <iostream>
#include <fstream>
using namespace std;
ifstream f("arbint.in");
ofstream g("arbint.out");
class SegTree
{
private:
const static int NMAX=1000000;
int v[NMAX],n=0,m;
int buildTree(int *x,int l,int r,int k)
{
n=max(n,k);
if(l==r)
{
v[k]=x[l];
return v[k];
}
int m=(l+r)/2;
v[k]=max(buildTree(x,l,m,2*k),buildTree(x,m+1,r,2*k+1));
return v[k];
}
int getMax(int x,int y,int l,int r,int k)
{
if(l>=x && r<=y)
return v[k];
if(r<x || l>y)
return -1;
int m=(l+r)/2;
return max(getMax(x,y,l,m,2*k),getMax(x,y,m+1,r,2*k+1));
}
int getPos(int pos,int l,int r,int k)
{
if(l==r)
return k;
int m=(l+r)/2;
if(m<pos)
return getPos(pos,m+1,r,2*k+1);
else
return getPos(pos,l,m,2*k);
}
public:
SegTree(int *x,int len)
{
m=len;
buildTree(x,1,len,1);
}
int getMaxInterval(int x,int y)
{
return getMax(x,y,1,m,1);
}
void insert(int x)
{
if(!n)
{
v[++n]=x;
return;
}
v[++n]=v[n/2];
v[++n]=x;
int k=n/2;
while(k)
{
v[k]=max(v[k],x);
k/=2;
}
}
void setValue(int pos,int x)
{
int k=getPos(pos,1,m,1);
v[k]=x;
while(k)
{
v[k/2]=max(v[k],v[k+1]);
k/=2;
}
}
void print()
{
for(int i=1;i<=n;++i)
cout<<v[i]<<' ';
cout<<'\n';
}
};
int main()
{
int n,v[100000],m;
f>>n>>m;
for(int i=1;i<=n;++i)
f>>v[i];
SegTree st(v,n);
st.print();
while(m--)
{
int val,x,y;
f>>val>>x>>y;
if(val==0)
g<<st.getMaxInterval(x,y)<<'\n';
else
{
st.setValue(x,y);
//st.print();
}
}
return 0;
}