#include <iostream>
#include <fstream>
#include <vector>
#define N 100000
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int n, q;
vector <int> a;
int sol[4 * N + 1];
/// caut [x,y] in [st,dr]
int answer(int st, int dr, int x, int y, int nod)
{
if (st < dr)
{
int mij = (st + dr) / 2;
if (x <= mij && y >= mij + 1)
return max(answer(st, mij, x, mij, 2 * nod), answer(mij + 1, dr, mij + 1, y, 2 * nod + 1));
else if (y <= mij)
return answer(st, mij, x, y, 2 * nod);
else if (x >= mij + 1)
return answer(mij + 1, dr, x, y, 2 * nod + 1);
}
else return sol[nod];
}
void creare_arbore(int poz, int st, int dr)
{
if (st != dr)
{
int mij = (st + dr) / 2;
creare_arbore(poz * 2, st, mij);
creare_arbore(poz * 2 + 1, mij + 1, dr);
sol[poz] = max(sol[2 * poz], sol[2 * poz + 1]);
}
else sol[poz] = a[st];
}
void update(int a, int b, int x, int y, int nod)
{
if (x == y)
sol[nod] = b;
else
{
int mij = (x + y) / 2;
if (a <= mij)
update(a, b, x, mij, 2 * nod);
else if (a >= mij + 1)
update(a, b, mij + 1, y, 2 * nod + 1);
sol[nod] = max(sol[2 * nod], sol[2 * nod + 1]);
}
}
void citire()
{
int x, y;
bool op;
a.push_back(-1e9);
fin >> n >> q;
for (int i = 1; i <= n; i++)
fin >> x, a.push_back(x);
creare_arbore(1, 1, n);
for (int i = 1; i <= q; i++)
{
fin >> op >> x >> y;
if (!op) fout << answer(1, n, x, y, 1) << '\n';
else update(x, y, 1, n, 1);
}
}
int main()
{
citire();
return 0;
}