#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream f("../arbint.in");
ofstream g("../arbint.out");
int n, m, op, a, b;
vector<int> v, arbore;
int sol;
void construieste(int i_Nod, int st, int dr) {
if (st == dr) {
arbore[i_Nod] = v[st];
} else {
int mijloc = (st + dr) / 2;
construieste(2 * i_Nod, st, mijloc);
construieste(2 * i_Nod + 1, mijloc + 1, dr);
arbore[i_Nod] = max(arbore[2 * i_Nod], arbore[2 * i_Nod + 1]);
}
}
void actualizeaza(int i_Nod, int st, int dr, int poz, int val) {
if (st == dr)
arbore[i_Nod] = val;
else {
int mijloc = (st + dr) / 2;
if (poz <= mijloc)
actualizeaza(2 * i_Nod, st, mijloc, poz, val);
else
actualizeaza(2 * i_Nod + 1, mijloc + 1, dr, poz, val);
arbore[i_Nod] = max(arbore[2 * i_Nod], arbore[2 * i_Nod + 1]);
}
}
void interogare(int i_Nod, int st, int dr, int a, int b) {
if (a <= st && dr <= b)
sol = max(sol, arbore[i_Nod]);
else {
int mijloc = (st + dr) / 2;
if (a <= mijloc)
interogare(2 * i_Nod, st, mijloc, a, b);
if (b >= mijloc + 1)
interogare(2 * i_Nod + 1, mijloc + 1, dr, a, b);
}
}
int main() {
f >> n >> m;
v.resize(n + 1);
for (int i = 1; i <= n; i++) {
f >> v[i];
}
arbore.resize(4 * n + 5);
construieste(1, 1, n);
for (int i = 1; i <= m; i++) {
f >> op >> a >> b;
if (op == 1) {
v[a] = b;
actualizeaza(1, 1, n, a, b);
} else if (op == 0) {
sol = 0;
interogare(1, 1, n, a, b);
g << sol << "\n";
}
}
return 0;
}