#include <iostream>
#include <fstream>
using namespace std;
unsigned intArb[100001];
unsigned interogare(size_t nod, size_t st, size_t dr, size_t a, size_t b) {
if(a <= st && dr <= b)
return intArb[nod];
else {
size_t mij = (st+dr)>>1;
unsigned maxVal = 0;
if(a <= mij)
maxVal = max(maxVal, interogare(nod<<1, st, mij, a, b));
if(b > mij)
maxVal = max(maxVal, interogare((nod<<1)+1, mij+1, dr, a, b));
return maxVal;
}
}
void actualizare(size_t nod, size_t st, size_t dr, size_t i, unsigned val) {
if (st <= i && i <= dr) {
if (st != dr) {
size_t mij = (st+dr)>>1;
if(i <= mij)
actualizare(nod<<1, st, mij, i, val);
if(i > mij)
actualizare((nod<<1)+1, mij+1, dr, i, val);
intArb[nod] = max(intArb[nod<<1], intArb[(nod<<1)+1]);
}
else {
intArb[nod] = val;
}
}
}
int main() {
freopen("arbint.in", "r", stdin);
freopen("arbint.out", "w", stdout);
int n, m;
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++) {
unsigned t;
scanf("%d", &t);
actualizare(1, 0, n-1, i, t);
}
unsigned op, a, b, maxim;
for (int i = 0; i < m; i++) {
scanf("%d%d%d", &op, &a, &b);
if (op == 0) {
maxim = interogare(1, 0, n-1, a-1, b-1);
printf("%d\n", maxim);
} else if (op == 1) {
actualizare(1, 0, n-1, a-1, b);
}
}
return 0;
}