// infoarena: problema/arbint //
#include <fstream>
using namespace std;
ifstream in("arbint.in");
ofstream out("arbint.out");
const int MAXN = 100010;
const int INF = 1<<30;
int arb[MAXN*10],i,j,n,m,a,b,x,op,y,f[MAXN],k;
void init_leaves(int nod=1, int st=1, int dr=-1)
{
if(dr == -1)
dr = n;
if(st == dr)
f[st] = nod;
else if(st < dr)
init_leaves(2*nod, st, (st+dr)/2),
init_leaves(2*nod+1, (st+dr)/2+1);
}
void update(int pos, int val, int nod=1, int st=1, int dr=-1)
{
if(dr == -1)
dr = n;
if(st > dr || pos < st || pos > dr)
return;
if(st == dr && st == pos)
arb[nod] = val;
else
{
update(pos, val, nod*2, st, (st+dr)/2);
update(pos, val, nod*2+1, (st+dr)/2+1, dr);
arb[nod] = max(arb[nod*2], arb[2*nod+1]);
}
}
int query(int a, int b, int nod=1, int st=1, int dr=-1)
{
if(dr == -1)
dr = n;
if(b < st || a > dr)
return -INF;
if(a <= st && dr <= b)
return arb[nod];
if(b < (st+dr)/2)
return query(a, b, 2*nod, st, (st+dr)/2);
else if(a > dr)
return query(a, b, 2*nod+1, (st+dr)/2+1, dr);
return max(query(a, b, 2*nod, st, (st+dr)/2),
query(a, b, 2*nod+1, (st+dr)/2+1, dr));
}
int main()
{
in>>n>>m;
for(i=1; i<=2*n; i++)
arb[i] = -INF;
init_leaves();
for(i=1; i<=n; i++)
{
in>>x;
arb[f[i]] = x;
k = f[i]/2;
while(k)
arb[k] = max(arb[k], x), k/=2;
}
for(i=1; i<=m; i++)
{
in>>op>>x>>y;
if(op == 0)
out<<query(x, y)<<'\n';
else
update(x, y);
}
return 0;
}