#include <bits/stdc++.h>
#define ii pair<int, int>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
class SegmentTree {
//Change return value from query function
//Change last line of update function
private:
vector<int> tree;
public:
SegmentTree(int n, int val) {
tree.resize(4 * n + 4, val);
}
void update(int node, int l, int r, int value, int pos) {
if (l == r) {
tree[node] = value;
return;
}
int mid = (l + r) / 2;
if (pos <= mid) {
update(2 * node, l, mid, value, pos);
} else {
update(2 * node + 1, mid + 1, r, value, pos);
}
tree[node] = max(tree[2 * node], tree[2 * node + 1]);
}
int query(int node, int l, int r, int st, int fi) {
if (st <= l and r <= fi) {
return tree[node];
}
int mid = (l + r) / 2, ans1 = 0, ans2 = 0;
if (st <= mid) {
ans1 = query(2 * node, l, mid, st, fi);
}
if (fi > mid) {
ans2 = query(2 * node + 1, mid + 1, r, st, fi);
}
return max(ans1, ans2);
}
};
int main() {
int elements, queries;
fin >> elements >> queries;
SegmentTree tree(elements, 0);
for (int i = 1; i <= elements; ++i) {
int value; fin >> value;
tree.update(1, 1, elements, value, i);
}
for (int i = 1; i <= queries; ++i) {
int code, a, b;
fin >> code >> a >> b;
if (code == 0) {
int ans = tree.query(1, 1, elements, a, b);
fout << ans << '\n';
} else {
tree.update(1, 1, elements, b, a);
}
}
return 0;
}