/* arbori de intervale */
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define NMAX 400000
int tree[NMAX];
int v[NMAX];
// Funcția pentru calculul maximului dintre două numere
int mx(int a, int b) {
if (a > b)
return a;
else
return b;
}
// Funcția pentru construirea arborelui de intervale
void build(int nod, int st, int dr) {
int mij;
if (st == dr)
tree[nod] = v[st];
else {
mij = (st + dr) / 2;
build(2 * nod, st, mij);
build(2 * nod + 1, mij + 1, dr);
tree[nod] = mx(tree[2 * nod], tree[2 * nod + 1]);
}
}
// Funcția pentru actualizarea valorii unui element în arborele de intervale
void update(int nod, int st, int dr, int pos, int val) {
if (st == dr)
tree[nod] = val;
else {
int mij = (st + dr) / 2;
if (pos <= mij)
update(2 * nod, st, mij, pos, val);
else
update(2 * nod + 1, mij + 1, dr, pos, val);
tree[nod] = mx(tree[2 * nod], tree[2 * nod + 1]);
}
}
// Funcția pentru efectuarea unei interogări în arborele de intervale
void query(int nod, int st, int dr, int x, int y, int* ans) {
if (x <= st && dr <= y)
*ans = mx(*ans, tree[nod]);
else {
int mij = (st + dr) / 2;
if (x <= mij)
query(2 * nod, st, mij, x, y, ans);
if (y > mij)
query(2 * nod + 1, mij + 1, dr, x, y, ans);
}
}
int main() {
FILE *fin, *fout;
int M, N, o, a, b, ma;
fin = fopen("arbint.in", "rt");
fout = fopen("arbint.out", "wt");
fscanf(fin, "%d %d", &N, &M);
for (int i = 1; i <= N; ++i)
fscanf(fin, "%d", &v[i]);
build(1, 1, N);
for (int i = 0; i < M; ++i) {
fscanf(fin, "%d %d %d", &o, &a, &b);
if (o == 0) {
ma = -1;
query(1, 1, N, a, b, &ma);
fprintf(fout, "%d\n", ma);
}
else
update(1, 1, N, a, b);
}
fclose(fin);
fclose(fout);
getchar();
return 0;
}