#include <iostream>
#include <fstream>
using namespace std;
int v[100005];
struct nod
{
int val;
};
nod aint[400005];
int query(int cr, int ql, int qr, int l, int r)
{
if (ql<=l&&r<=qr)
return aint[cr].val;
int mid = (l+r)/2;
if (qr<=mid)
return query(2*cr, ql, qr, l, mid);
if (mid<ql)
return query(2*cr+1, ql, qr, mid+1, r);
return max(query(2*cr, ql, mid, l, mid), query(2*cr+1, mid+1, qr, mid+1, r));
}
nod join (nod a, nod b)
{
nod c;
c.val=max(a.val, b.val);
return c;
}
void update(int cr, int trg, int a, int l, int r)
{
if (l==r)
{aint[cr].val=a; return;}
int mid=(l+r)/2;
if (trg<=mid)
update(2*cr, trg, a, l, mid);
if (trg>mid)
update(2*cr+1, trg, a, mid+1, r);
aint[cr]=join(aint[2*cr], aint[2*cr+1]);
}
void build(int cr, int l, int r)
{
if (l==r)
{
aint[cr].val=v[l];
return;
}
int mid=(l+r)/2;
build(2*cr, l, mid);
build(2*cr+1, mid+1, r);
aint[cr]=join(aint[2*cr], aint[2*cr+1]);
}
int main()
{
ifstream cin ("arbint.in");
ofstream cout ("arbint.out");
int n, m, tip, a, b;
cin>>n>>m;
for (int i=1; i<=n; i++)
{
cin>>v[i];
}
build(1, 1, n);
for (int i=1; i<=m; i++)
{
cin>>tip>>a>>b;
if (tip==0)
{
cout<<query(1, a, b, 1, n)<<'\n';
}
else
{
update(1, a, b, 1, n);
}
}
}