#include <fstream>
using namespace std;
ifstream in ("arbint.in");
ofstream out ("arbint.out");
const int NMAX = 100000;
int v[1 + NMAX];
int aint[1 + 4 * NMAX];
void build(int indexNod, int st, int dr)
{
if (st == dr)
{
aint[indexNod] = v[st]; // = v[dr];
return;
}
int indexFiuSt = 2 * indexNod;
int indexFiuDr = 2 * indexNod + 1;
int mij = (st + dr) / 2;
build(indexFiuSt, st, mij);
build(indexFiuDr, mij + 1, dr);
aint[indexNod] = max(aint[indexFiuSt], aint[indexFiuDr]);
}
void update(int indexNod, int st, int dr, int poz, int valNoua)
{
if (st == dr)
{
aint[indexNod] = valNoua;
return;
}
int indexFiuSt = 2 * indexNod;
int indexFiuDr = 2 * indexNod + 1;
int mij = (st + dr) / 2;
if (poz <= mij)
update(indexFiuSt, st, mij, poz, valNoua);
else
update(indexFiuDr, mij + 1, dr, poz, valNoua);
aint[indexNod] = max(aint[indexFiuSt], aint[indexFiuDr]);
}
int query(int indexNod, int st, int dr, int stQuery, int drQuery)
{
if (stQuery == st && dr == drQuery)
return aint[indexNod];
int indexFiuSt = 2 * indexNod;
int indexFiuDr = 2 * indexNod + 1;
int mij = (st + dr) / 2;
int sol = 0;
if (stQuery <= mij)
sol = max(sol, query(indexFiuSt, st, mij, stQuery, min(mij, drQuery)));
if (drQuery >= mij + 1)
sol = max(sol ,query(indexFiuDr, mij + 1, dr, max(stQuery, mij + 1), drQuery));
return sol;
}
int main()
{
int n, m;
in >> n >> m;
for(int i = 1; i <= n; i++)
in >> v[i];
build(1, 1, n);
for (int j = 1; j <= m; j++)
{
int tipOperatie, a, b;
in >> tipOperatie >> a >> b;
if (tipOperatie == 0)
out << query(1, 1, n, a, b) << '\n';
else
update(1, 1, n, a, b);
}
return 0;
}