#include <fstream>
#include <iostream>
#include <map>
using namespace std;
ifstream in("arbint.in");
ofstream out("arbint.out");
void insert(map<int, int>& tree, int current_position, int left,
int right, int position, int value) {
if (left == right) {
tree[current_position] = value;
return;
}
int mid = left + ((right - left) / 2);
if (position <= mid) {
insert(tree, current_position * 2, left, mid, position, value);
} else {
insert(tree, current_position * 2 + 1, mid + 1, right, position, value);
}
tree[current_position] = max(tree[current_position * 2],
tree[2 * current_position + 1]);
}
int query(map<int, int>& tree, int current_position, int left,
int right, int a, int b) {
int mid = left + ((right - left) / 2);
if (left >= a && right <= b) {
return tree[current_position];
}
int result = 0;
if (mid >= a) {
result = max(result, query(tree, current_position * 2, left, mid, a, b));
}
if (mid + 1 <= b) {
result = max(result, query(tree, current_position * 2 + 1, mid + 1, right, a, b));
}
return result;
}
int main() {
int n, m;
in>>n>>m;
map<int, int> arbint;
for (int i = 1; i <= n; ++i) {
int x;
in >> x;
// On position i set to x for segment tree arbint.
// Left is 0, right is n and we start from position 0.
insert(arbint, 1, 1, n, i, x);
}
for (int i = 0; i < m; ++i) {
int op, a, b;
in >> op >> a >> b;
if (op == 1) {
insert(arbint, 1, 1, n, a, b);
} else {
out<<query(arbint, 1, 1, n, a, b)<<"\n";
}
}
return 0;
}