#include <bits/stdc++.h>
#define NMAX 100005
int n, t[4 * NMAX];
void build(int a[], int v, int tl, int tr) {
if (tl == tr) {
t[v] = a[tl];
} else {
int tm = (tl + tr) / 2;
build(a, v * 2, tl, tm);
build(a, v * 2 + 1, tm + 1, tr);
t[v] = std::max(t[v * 2], t[v * 2 + 1]);
}
}
int find_max(int v, int tl, int tr, int l, int r) {
if (l > r) {
return 0;
}
if (l == tl && r == tr) {
return t[v];
}
int tm = (tl + tr) / 2;
return std::max(
find_max(2 * v, tl, tm, l, std::min(r, tm)),
find_max(2 * v + 1, tm + 1, tr, std::max(l, tm + 1), r));
}
void update(int v, int tl, int tr, int new_index, int new_value) {
if (tl == tr) {
t[v] = new_value;
return;
}
int tm = (tl + tr) / 2;
if (new_index <= tm) {
update(2 * v, tl, tm, new_index, new_value);
} else {
update(2 * v + 1, tm + 1, tr, new_index, new_value);
}
t[v] = std::max(t[2 * v], t[2 * v + 1]);
}
int main() {
std::ifstream fin("arbint.in");
std::ofstream fout("arbint.out");
int n, m;
fin >> n >> m;
int a[NMAX] = {};
for (int i = 0; i < n; ++i) {
fin >> a[i];
}
build(a, 1, 0, n - 1);
for (int i = 0; i < m; ++i) {
int query_type;
fin >> query_type;
if (query_type == 0) {
int l, r;
fin >> l >> r;
fout << find_max(1, 0, n - 1, l - 1, r - 1) << "\n";
} else if (query_type == 1) {
int new_index, new_val;
fin >> new_index >> new_val;
update(1, 0, n - 1, new_index - 1, new_val);
}
}
return 0;
}