#include <bits/stdc++.h>
using namespace std;
ifstream f("arbint.in");
ofstream g("arbint.out");
struct Nod
{
Nod *st,*dr;
int val,Max,prior,sz;
};
Nod nil;
Nod *Treap = &nil;
Nod* mod_fiu(Nod* N, int care, Nod* f)
{
if(care==0)
{
N->st=f;
}
else
{
N->dr=f;
}
N->sz = N->st->sz+1+N->dr->sz;
N->Max = max(N->val,max(N->st->Max,N->dr->Max));
return N;
}
pair<Nod*,Nod*> split(Nod *N, int k)
{
if(N==&nil)
{
return {&nil,&nil};
}
if(N->st->sz>=k)
{
auto t = split(N->st,k);
return {t.first,mod_fiu(N,0,t.second)};
}
else
{
auto t = split(N->dr,k - N->st->sz - 1);
return {mod_fiu(N,1,t.first),t.second};
}
}
Nod* join(Nod* st, Nod* dr)
{
if(st==&nil)
{
return dr;
}
if(dr==&nil)
{
return st;
}
if(st->prior>=dr->prior)
{
return mod_fiu(st,1,join(st->dr,dr));
}
else
{
return mod_fiu(dr,0,join(st,dr->st));
}
}
Nod* Update(int poz, int val)
{
auto N = split(Treap,poz);
auto T = split(N.first,poz-1);
return join(T.first,join(new Nod{&nil,&nil,val,val,rand(),1},N.second));
}
Nod* Query(int a, int b, int &rez)
{
auto N = split(Treap,b);
auto T = split(N.first,a-1);
rez = T.second->Max;
return join(join(T.first,T.second),N.second);
}
int main()
{
int n,m;
f>>n>>m;
srand(time(NULL));
for(int i=1;i<=n;i++)
{
int x;
f>>x;
Treap = Update(i,x);
}
for(int i=1;i<=m;i++)
{
int t;
f>>t;
if(t==0)
{
int a,b;
f>>a>>b;
int rez=0;
Treap = Query(a,b,rez);
g<<rez<<'\n';
}
else if(t==1)
{
int poz,val;
f>>poz>>val;
Treap = Update(poz,val);
}
}
return 0;
}