#include <bits/stdc++.h>
using namespace std;
class segment_tree {
vector<int> container;
size_t size;
void __update(size_t pos, int value, size_t node, size_t left, size_t right) {
if (left == right) {
container[node] = value;
return;
}
const size_t mid = left + (right - left) / 2;
if (pos <= mid)
__update(pos, value, 2 * node + 1, left, mid);
else
__update(pos, value, 2 * node + 2, mid + 1, right);
container[node] = max(container[2 * node + 1], container[2 * node + 2]);
}
int __query(size_t left, size_t right, size_t node, size_t node_left, size_t node_right) {
if (node_right < left || node_left > right)
return INT_MIN;
if (left <= node_left && node_right <= right)
return container[node];
int ans = INT_MIN;
const size_t mid = node_left + (node_right - node_left) / 2;
int ans_left = __query(left, right, 2 * node + 1, node_left, mid);
int ans_right = __query(left, right, 2 * node + 2, mid + 1, node_right);
return max(ans_left, ans_right);
}
public:
segment_tree(size_t n) : container(4 * n), size(n) {}
void update(size_t pos, int value) {
__update(pos, value, 0, 0, size - 1);
}
int query(size_t left, size_t right) {
return __query(left, right, 0, 0, size - 1);
}
};
int main() {
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int n, m;
fin >> n >> m;
segment_tree st(n);
for (int i = 0, x; i < n; ++i) {
fin >> x;
st.update(i, x);
}
for (int i = 0, code, x, y; i < m; ++i) {
fin >> code >> x >> y;
if (code == 0)
fout << st.query(x - 1, y - 1) << '\n';
else if (code == 1)
st.update(x - 1, y);
}
}