#include <stdio.h>
int arb[400005];
int v[100005];
int max(int a, int b) {
return (a > b) ? a : b;
}
void build(int nod, int st, int dr) {
if (st == dr) {
arb[nod] = v[st];
return;
}
int mij = (st + dr) / 2;
build(2 * nod, st, mij);
build(2 * nod + 1, mij + 1, dr);
arb[nod] = max(arb[2 * nod], arb[2 * nod + 1]);
}
void update(int nod, int st, int dr, int poz, int val) {
if (st == dr) {
arb[nod] = val;
return;
}
int mij = (st + dr) / 2;
if (poz <= mij) {
update(2 * nod, st, mij, poz, val);
} else {
update(2 * nod + 1, mij + 1, dr, poz, val);
}
arb[nod] = max(arb[2 * nod], arb[2 * nod + 1]);
}
int query(int nod, int st, int dr, int qa, int qb) {
if (qa <= st && dr <= qb) {
return arb[nod];
}
int mij = (st + dr) / 2;
int rez1 = -1, rez2 = -1;
if (qa <= mij) {
rez1 = query(2 * nod, st, mij, qa, qb);
}
if (qb > mij) {
rez2 = query(2 * nod + 1, mij + 1, dr, qa, qb);
}
return max(rez1, rez2);
}
int main() {
FILE *fin = fopen("arbint.in", "r");
FILE *fout = fopen("arbint.out", "w");
if (fin == NULL || fout == NULL) {
return 0;
}
int n, m;
if (fscanf(fin, "%d %d", &n, &m) == 2) {
for (int i = 1; i <= n; i++) {
fscanf(fin, "%d", &v[i]);
}
build(1, 1, n);
for (int i = 0; i < m; i++) {
int tip, a, b;
if (fscanf(fin, "%d %d %d", &tip, &a, &b) == 3) {
if (tip == 0) {
fprintf(fout, "%d\n", query(1, 1, n, a, b));
} else if (tip == 1) {
update(1, 1, n, a, b);
}
}
}
}
fclose(fin);
fclose(fout);
return 0;
}