#include <bits/stdc++.h>
using namespace std;
#define UPDATE 1
#define QUERY 0
#define dim 100001
vector<int> input_v;
int range_tree[4*dim+66];
int build_tree(int node, int l, int r)
{
if (l == r) {
range_tree[node] = input_v[l];
} else {
int m = (l + r) / 2;
range_tree[node] = max(build_tree(2 * node + 1, l, m),
build_tree(2 * node + 2, m + 1, r));
}
return range_tree[node];
}
void update(int node, int pos, int val, int l, int r)
{
if (l == r) {
if (l == pos) range_tree[node] = val;
return ;
}
int m = (l + r) / 2;
if (pos <= m) {
update(2 * node + 1, pos, val, l, m);
} else {
update(2 * node + 2, pos, val, m + 1, r);
}
range_tree[node] = max(range_tree[2 * node + 1], range_tree[2 * node + 2]);
}
int query(int node, int target_l, int target_r, int l, int r)
{
//cout << l << " " << r << " " << target_l << " " << target_r << endl;
if (target_l <= l && target_r >= r) {
return range_tree[node];
}
int m = (l + r) / 2;
int left = -1, right = -1;
if (target_l <= m) {
left = query(2 * node + 1, target_l, target_r, l, m);
}
if (target_r > m) {
right = query(2 * node + 2, target_l, target_r, m + 1, r);
}
return max(left, right);
}
int main() {
freopen("arbint.in", "r", stdin);
freopen("arbint.out", "w", stdout);
int n, m;
cin >> n >> m;
//range_tree.reserve(4 * n + 20);
input_v.reserve(n + 5);
for (int i = 0; i < n; i++) cin >> input_v[i];
build_tree(0, 0, n - 1);
for (int i = 0; i < m; i++) {
int op, a, b;
cin >> op >> a >> b;
if (op == QUERY) {
cout << query(0, a - 1, b - 1, 0, n - 1) << "\n";
} else if (op == UPDATE) {
update(0, a - 1, b, 0, n - 1);
}
}
return 0;
}