#include <bits/stdc++.h>
#define N (int)(1e5+5)
#define leftChild node<<1
#define rightChild node<<1 | 1
using namespace std;
int n, m, op, a, b;
int vec[N], aint[4*N];
void build(int node, int l, int r) {
if (l == r)
aint[node] = vec[l];
else {
int mid = (l + r) / 2;
build (leftChild, l, mid);
build (rightChild, mid+1, r);
aint[node] = max(aint[leftChild], aint[rightChild]);
}
}
void update(int node, int l, int r, int pos, int newVal) {
if (l == r) {
aint[node] = newVal;
return;
}
int mid = (l + r) / 2;
if (pos <= mid) update(leftChild, l, mid, pos, newVal);
else update(rightChild, mid+1, r, pos, newVal);
aint[node] = max(aint[leftChild], aint[rightChild]);
}
int query(int node, int l, int r, int x, int y) {
if (l >= x && r <= y) return aint[node];
int mid = (l + r) / 2;
int ret = 0;
if (mid >= x) ret = query(leftChild, l, mid, x, y);
if (mid+1 <= y) ret = max(ret, query(rightChild, mid+1, r, x, y));
return ret;
}
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", &vec[i]);
build(1, 1, n);
for (int i = 1; i <= m; ++i) {
scanf("%d %d %d", &op, &a, &b);
if (op == 0) printf("%d\n", query(1, 1, n, a, b));
else update(1, 1, n, a, b);
}
return 0;
}