#include <stdio.h>
#define MAX_N 100005
int arr[MAX_N];
int tree[4 * MAX_N];
int max(int a, int b) {
if ( a > b ) return a;
return b;
}
void build(int node, int left, int right) {
if (left == right) {
tree[node] = arr[left];
return;
}
int mid = left + (right - left) / 2;
int left_child = node << 1;
int right_child = (node << 1) | 1;
build(left_child, left, mid);
build(right_child, mid + 1, right);
tree[node] = max(tree[left_child], tree[right_child]);
}
void update(int node, int left, int right, int pos, int val) {
if (left == right) {
tree[node] = val;
return;
}
int mid = left + (right - left) / 2;
int left_child = node << 1;
int right_child = (node << 1) | 1;
if (pos <= mid) {
update(left_child, left, mid, pos, val);
} else {
update(right_child, mid + 1, right, pos, val);
}
tree[node] = max(tree[left_child], tree[right_child]);
}
int query(int node, int left, int right, int q_left, int q_right) {
if (q_left <= left && right <= q_right) {
return tree[node];
}
int mid = left + (right - left) / 2;
int left_child = node << 1;
int right_child = (node << 1) | 1;
int max_val = -1;
if (q_left <= mid) {
max_val = max(max_val, query(left_child, left, mid, q_left, q_right));
}
if (mid < q_right) {
max_val = max(max_val, query(right_child, mid + 1, right, q_left, q_right));
}
return max_val;
}
int main() {
freopen("arbint.in", "r", stdin);
freopen("arbint.out", "w", stdout);
int n, m;
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d", &arr[i]);
}
build(1, 1, n);
for (int i = 0; i < m; i++) {
int type, a, b;
scanf("%d %d %d", &type, &a, &b);
if (type == 0) {
printf("%d\n", query(1, 1, n, a, b));
}
else
{
update(1, 1, n, a, b);
}
}
return 0;
}