#include <bits/stdc++.h>
using namespace std;
string __fname = "arbint"; ifstream in (__fname + ".in"); ofstream out (__fname + ".out");
#define cin in
#define cout out
const int maxn = 1e5 + 1;
int sgt[4 * maxn]; // sgt[x] -> valoarea nodului cu indicele x ||| muchie x -> 2 * x si x -> 2 * x + 1
// int update (int x, int l, int r, int pos, int newval) {
// if (r < pos || l > pos) return sgt[x];
// if (l == pos && r == pos) {
// sgt[x] = newval;
// return sgt[x];
// }
// int mid = (l + r) / 2; // [l, mid] : [mid + 1, r]
// update(x * 2, l, mid, pos, newval);
// update(x * 2 + 1, mid + 1, r, pos, newval);
// sgt[x] = max(sgt[x * 2], sgt[x * 2 + 1]);
// return sgt[x];
// }
int update (int x, int l, int r, int pos, int newval) {
if (r < pos || l > pos) return sgt[x];
if (l == pos && r == pos) return sgt[x] = newval;
int mid = (l + r) / 2;
return sgt[x] = max(update(x * 2, l, mid, pos, newval), update(x * 2 + 1, mid + 1, r, pos, newval));
}
int query (int x, int l, int r, int tl, int tr) {
// cout << x << " " << l << " " << r << " " << tl << " " << tr << "\n";
if (r < tl || l > tr) return 0;
if (l >= tl && r <= tr) return sgt[x];
int mid = (l + r) / 2;
return max(query(x * 2, l, mid, tl, tr), query(x * 2 + 1, mid + 1, r, tl, tr));
}
int main() {
ios_base::sync_with_stdio(0); cin.tie(0);
int n,m;
cin >> n >> m;
for (int i = 1; i <= n; i++){
int x;
cin >> x;
update(1, 1, n, i, x);
}
while (m--){
int t, x, y;
cin >> t >> x >> y;
if (t == 0) {
cout << query(1, 1, n, x, y) << "\n";
}
else {
update(1, 1, n, x, y);
}
}
return 0;
}