#include<cstdio>
// #include<ctime>
#define max(a, b) (a > b ? a : b)
#define NMAX 100100
using namespace std;
int n, m, maxim;
int v[NMAX], h[2 * NMAX - 1];
void Actualizare(int i, int poz) {
h[i] = max(h[i], v[poz]);
if(i > 1) Actualizare(i / 2, poz);
}
void Arb(int i, int st, int dr, const bool &retMax, const int &a, const int &b) {
int mij = (st + dr) / 2;
if(st < dr) {
Arb(2 * i, st, mij, retMax, a, b);
Arb(2 * i + 1, mij + 1, dr, retMax, a, b);
}
else if(st == dr) {
if (retMax == 1 && a <= st && st <= b) maxim = max(maxim, h[i]);
else Actualizare(i, st);
}
}
int main() {
// clock_t start, stop;
// start = clock();
int i, j, a, b, tip;
freopen("arbint.in", "r", stdin), freopen("arbint.out", "w", stdout);
scanf("%d %d", &n, &m);
for(i = 1; i <= n; i++) scanf("%d", &v[i]);
Arb(1, 1, n, false, 0, 0);
for(i = 1; i <= m; i++) {
scanf("%d %d %d", &tip, &a, &b);
if(tip == 0) {
// Sa se determine maximul din intervalul [a,b]
maxim = -1;
Arb(1, 1, n, true, a, b);
printf("%d\n", maxim);
}
else if(tip == 1) {
// Valoarea elementului de pe pozita a va deveni b.
v[a] = b;
for(j = 1; j <= 2 * n - 1; j++) h[j] = 0;
Arb(1, 1, n, false, 0, 0);
}
}
// stop = clock();
// printf("\n------\n%.12f\n", 1.0 * (stop - start) / CLOCKS_PER_SEC);
return 0;
}