#include <cstdio>
#define MAX_N 100000
int N, M, ret;
int val[MAX_N + 1];
int tree[MAX_N << 2];
int MAX(int X, int Y) {
return X > Y ? X : Y;
}
void build(int u, int left, int right) {
if (left == right) {
tree[u] = val[left];
return;
}
int mid = (left + right) / 2;
build(2 * u, left, mid);
build(2 * u + 1, mid + 1, right);
tree[u] = MAX(tree[2 * u], tree[2 * u + 1]);
}
void update(int u, int left, int right, const int a, const int b) {
if (left == right) {
tree[u] = b;
return;
}
int mid = (left + right) / 2;
if (a <= mid) {
update(2 * u, left, mid, a, b);
} else {
update(2 * u + 1, mid + 1, right, a, b);
}
tree[u] = MAX(tree[2 * u], tree[2 * u + 1]);
}
void query(int u, int left, int right, const int a, const int b) {
if (a <= left && right <= b) {
ret = MAX(ret, tree[u]);
return;
}
int mid = (left + right) / 2;
if (a <= mid) {
query(2 * u, left, mid, a, b);
}
if (b > mid) {
query(2 * u + 1, mid + 1, right, a, b);
}
}
int main(void) {
FILE *f = fopen("arbint.in", "r");
int i;
fscanf(f, "%d %d", &N, &M);
for (i = 1; i <= N; i++) {
fscanf(f, "%d", &val[i]);
}
build(1, 1, N);
freopen("arbint.out", "w", stdout);
int task, a, b;
while (M) {
fscanf(f, "%d %d %d", &task, &a, &b);
if (task == 0) {
ret = 0;
query(1, 1, N, a, b);
fprintf(stdout, "%d\n", ret);
} else {
update(1, 1, N, a, b);
}
M--;
}
fclose(f);
fclose(stdout);
return 0;
}