#include <cstdio>
#include <cstdlib>
#include <vector>
using namespace std;
class SegmentTree{
private:
int n,pos,val,start,finish,sol_query;
vector<int> arb;
private :void upp(int i,int l,int r,int ( * comparator ) ( int i, int j )){
int mid;
if (l==r){
arb[i]=val;
return;
}
mid=(l+r)>>1;
if (pos<=mid) upp(i<<1,l,mid,comparator);
else upp((i<<1)+1,mid+1,r,comparator);
arb[i]=comparator(arb[i<<1],arb[(i<<1)+1]);
}
public : void update(int poz,int value,int ( * comparator ) ( int i, int j )){
pos=poz;
val=value;
upp(1,1,n,comparator);
}
private :void que(int i,int l,int r,void ( * comparator ) ( int &max_val, int value )){
int mid;
if (start<=l && r<=finish){
comparator(sol_query,arb[i]);
return;
}
mid=(l+r)>>1;
if (start<=mid)que((i<<1),l,mid,comparator);
if (mid<finish)que((i<<1)+1,mid+1,r,comparator);
}
public : int query(int l,int r,void ( * comparator ) ( int &max_val, int value )){
start=l;
finish=r;
sol_query=0;
que(1,1,n,comparator);
return sol_query;
}
void init(int nn){
arb.resize(5*nn+1,0);
n=nn;
}
};
SegmentTree arb;
void cmp1(int &maxi,int val){
maxi=max(maxi,val);
}
int cmp2(int i,int j){
return max(i,j);
}
main(){
int n,m,i,a,b;
freopen("arbint.in","r",stdin);
freopen("arbint.out","w",stdout);
scanf("%d%d",&n,&m);
arb.init(n);
for (i=1;i<=n;++i){
scanf("%d",&a);
arb.update(i,a,cmp2);
}
while (m--){
scanf("%d%d%d",&i,&a,&b);
if (i==0)
printf("%d\n",arb.query(a,b,cmp1));
else
arb.update(a,b,cmp2);
}
}