#include <bits/stdc++.h>
using namespace std;
class SegmentTree {
private:
vector<int> tree;
int n;
void build(const vector<int>& arr, int node, int left, int right) {
if (left == right) {
tree[node] = arr[left];
} else {
int mid = (left + right) / 2;
build(arr, 2 * node + 1, left, mid);
build(arr, 2 * node + 2, mid + 1, right);
tree[node] = max(tree[2 * node + 1], tree[2 * node + 2]);
}
}
void update(int node, int left, int right, int index, int value) {
if (left == right) {
tree[node] = value;
} else {
int mid = (left + right) / 2;
if (index <= mid) {
update(2 * node + 1, left, mid, index, value);
} else {
update(2 * node + 2, mid + 1, right, index, value);
}
tree[node] = max(tree[2 * node + 1], tree[2 * node + 2]);
}
}
int query(int node, int left, int right, int L, int R) {
if (R < left || right < L) {
return INT_MIN;
}
if (L <= left && right <= R) {
return tree[node];
}
int mid = (left + right) / 2;
int leftMax = query(2 * node + 1, left, mid, L, R);
int rightMax = query(2 * node + 2, mid + 1, right, L, R);
return max(leftMax, rightMax);
}
public:
SegmentTree(const vector<int>& arr) {
n = arr.size();
tree.resize(4 * n);
build(arr, 0, 0, n - 1);
}
void update(int idx, int value) {
update(0, 0, n - 1, idx, value);
}
int query(int L, int R) {
return query(0, 0, n - 1, L, R);
}
};
int main() {
ifstream f("arbint.in");
ofstream g("arbint.out");
int N, M, x, y, z;
f >> N >> M;
vector<int> v(N);
for (int i = 0; i < N; i++) {
f >> v[i];
}
SegmentTree tree(v);
for (int i = 0; i < M; i++) {
f >> x >> y >> z;
y--;
if (x == 0) {
z--;
g << tree.query(y, z) << endl;
} else {
tree.update(y, z);
}
}
f.close();
g.close();
return 0;
}