#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
void update(int tree[], int node, int l, int r, int pos, int val) {
if (l == r) {
tree[node] = val;
return;
}
int m = (l + r) / 2;
if (pos <= m)
update(tree, node * 2, l, m, pos, val);
else
update(tree, node * 2 + 1, m + 1, r, pos, val);
tree[node] = (tree[node * 2] > tree[node * 2 + 1]) ? tree[node * 2] : tree[node * 2 + 1];
}
void query(int tree[], int node, int l, int r, int l_margin, int r_margin, int *max) {
if (l_margin <= l && r <= r_margin) {
if (*max < tree[node])
*max = tree[node];
return;
}
int m = (l + r) / 2;
if (l_margin <= m)
query(tree, node * 2, l, m, l_margin, r_margin, max);
if (r_margin > m)
query(tree, node * 2 + 1, m + 1, r, l_margin, r_margin, max);
}
int main(void)
{
FILE *in = fopen("arbint.in", "r");
FILE *out = fopen("arbint.out", "w");
int n, m;
fscanf(in, "%d %d", &n, &m);
int *tree = calloc(4 * n + 4, sizeof(int));
for (int i = 0; i < n; i++) {
int val;
fscanf(in, "%d", &val);
update(tree, 1, 1, n, i + 1, val);
}
for (int i = 0; i < m; i++) {
int op, l, r;
fscanf(in, "%d %d %d", &op, &l, &r);
if (op == 1) {
update(tree, 1, 1, n, l, r);
} else {
int max = -1;
query(tree, 1, 1, n, l, r, &max);
fprintf(out, "%d\n", max);
}
}
free(tree);
fclose(in);
fclose(out);
return 0;
}