#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
int N, M;
vector<int> tree(4 * MAXN);
vector<int> A(MAXN);
void build(int node, int l, int r) {
if (l == r) {
tree[node] = A[l];
} else {
int mid = (l + r) / 2;
build(2 * node, l, mid);
build(2 * node + 1, mid + 1, r);
tree[node] = max(tree[2 * node], tree[2 * node + 1]);
}
}
int query(int node, int l, int r, int ql, int qr) {
if (qr < l || r < ql)
return INT_MIN;
if (ql <= l && r <= qr)
return tree[node];
int mid = (l + r) / 2;
return max(
query(2 * node, l, mid, ql, qr),
query(2 * node + 1, mid + 1, r, ql, qr)
);
}
void update(int node, int l, int r, int pos, int val) {
if (l == r) {
tree[node] = val;
} else {
int mid = (l + r) / 2;
if (pos <= mid)
update(2 * node, l, mid, pos, val);
else
update(2 * node + 1, mid + 1, r, pos, val);
tree[node] = max(tree[2 * node], tree[2 * node + 1]);
}
}
int main() {
freopen("arbint.in", "r", stdin);
freopen("arbint.out", "w", stdout);
scanf("%d %d", &N, &M);
for (int i = 1; i <= N; ++i)
scanf("%d", &A[i]);
build(1, 1, N);
for (int i = 0; i < M; ++i) {
int type, a, b;
scanf("%d %d %d", &type, &a, &b);
if (type == 0) {
printf("%d\n", query(1, 1, N, a, b));
} else {
update(1, 1, N, a, b);
}
}
return 0;
}