#include <fstream>
using namespace std;
const int NMAX = 100000;
int v[1 + NMAX];
int aint[3 * NMAX];
struct nod
{
int idx;
int st;
int dr;
int mij;
/*
nod(int idx, int st, int dr)
{
this->idx = idx;
this->st = st;
this->dr = dr;
this->mij = (st + dr) / 2;
}
*/
nod(int idx, int st, int dr):
idx(idx), st(st), dr(dr)
{
this->mij = (st + dr) / 2;
};
};
void build(nod &x)
{
if (x.st == x.dr)
{
aint[x.idx] = v[x.st];
return;
}
nod fiu_st(2 * x.idx, x.st, x.mij);
nod fiu_dr(2 * x.idx + 1, x.mij + 1, x.dr);
build(fiu_st);
build(fiu_dr);
aint[x.idx] = max(aint[fiu_st.idx], aint[fiu_dr.idx]);
}
int query(nod &x, int st, int dr)
{
if (x.st == x.dr)
{
return aint[x.idx];
}
int sol = 0;
nod fiu_st(2 * x.idx, x.st, x.mij);
nod fiu_dr(2 * x.idx + 1, x.mij + 1, x.dr);
if (st <= x.mij)
{
sol = max(sol, query(fiu_st, st, dr));
}
if (dr > x.mij)
{
sol = max(sol ,query(fiu_dr, st, dr));
}
return sol;
}
void update(nod &x, int poz, int val)
{
if (x.st == x.dr)
{
aint[x.idx] = val;
return;
}
nod fiu_st(2 * x.idx, x.st, x.mij);
nod fiu_dr(2 * x.idx + 1, x.mij + 1, x.dr);
if (poz <= x.mij)
{
update(fiu_st, poz, val);
}
else
{
update(fiu_dr, poz, val);
}
aint[x.idx] = max(aint[fiu_st.idx], aint[fiu_dr.idx]);
}
int main()
{
ifstream in("arbint.in");
ofstream out("arbint.out");
int n, m;
int op, a, b;
in >> n >> m;
for (int i = 1; i <= n; i++)
{
in >> v[i];
}
nod radacina(1, 1, n);
build(radacina);
for (int i = 1; i <= m; i++)
{
in >> op >> a >> b;
if (op == 0)
{
int sol = query(radacina, a, b);
out << sol << '\n';
}
else
{
update(radacina, a, b);
}
}
return 0;
}