#include <cstdio>
#include <algorithm>
FILE *fin, *fout;
#define MAXN 100000
int n, m;
int v[MAXN + 1];
int arb[3 * MAXN + 1];
int pos, val;
void update(int nod, int st, int dr) {
if (pos < st || pos > dr || st > dr)
return;
if (st == dr) {
arb[nod] = val;
return;
}
if (pos <= (st + dr) / 2)
update(nod * 2, st, (st + dr) / 2);
else
update(nod * 2 + 1, (st + dr) / 2 + 1, dr);
arb[nod] = std::max(arb[nod * 2], arb[nod * 2 + 1]);
}
int l1, r1, maxi;
void query(int nod, int st, int dr) {
if (st > dr) {
return;
}
if (st >= l1 && dr <= r1) {
maxi = std::max(maxi, arb[nod]);
return;
}
if (l1 <= (st + dr) / 2)
query(nod * 2, st, (st + dr) / 2);
if (r1 >= (st + dr) / 2 + 1)
query(nod * 2 + 1, (st + dr) / 2 + 1, dr);
}
int main() {
fin = fopen("arbint.in", "r");
fout = fopen("arbint.out", "w");
fscanf(fin, "%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
fscanf(fin, "%d", &v[i]);
pos = i, val = v[i];
update(1, 1, n);
}
for (int i = 1; i <= m; i++) {
int op, a, b;
fscanf(fin, "%d%d%d", &op, &a, &b);
if (op == 1) {
pos = a, val = b;
update(1, 1, n);
}
else {
l1 = a, r1 = b;
maxi = -1;
query(1, 1, n);
fprintf(fout, "%d\n", maxi);
}
}
fclose(fin);
fclose(fout);
return 0;
}