#include <cstdio>
#include <algorithm>
using namespace std;
const int NMAX = 100505;
const int LMAX = (1 << 18);
const int INF = 0x3f3f3f3f;
int M, N;
int A[NMAX], maxV[LMAX];
void cstrTree(int idx, int l, int r) {
if (l == r) {
maxV[idx] = A[l];
return;
}
int mid = l + (r - l) / 2;
cstrTree(idx * 2, l, mid);
cstrTree(idx * 2 + 1, mid + 1, r);
maxV[idx] = max(maxV[idx * 2], maxV[idx * 2 + 1]);
}
int getMax(int idx, int l, int r, int targetL, int targetR) {
if (targetL > r || targetR < l) {
return -INF;
}
if (targetL <= l && r <= targetR) {
return maxV[idx];
}
int mid = l + (r - l) / 2;
return max(
getMax(idx * 2, l, mid, targetL, targetR),
getMax(idx * 2 + 1, mid + 1, r, targetL, targetR));
}
void updateValue(int idx, int l, int r, int pos, int newV) {
if (l == r) {
maxV[idx] = newV;
return;
}
int mid = l + (r - l) / 2;
if (pos <= mid) {
updateValue(idx * 2, l, mid, pos, newV);
} else {
updateValue(idx * 2 + 1, mid + 1, r, pos, newV);
}
maxV[idx] = max(maxV[idx * 2], maxV[idx * 2 + 1]);
}
int main() {
freopen("arbint.in", "r", stdin);
freopen("arbint.out", "w", stdout);
scanf("%d%d", &N, &M);
for (int i = 1; i <= N; i++) {
scanf("%d", &A[i]);
}
cstrTree(1, 1, N);
int opType, x, y;
for (int operation = 0; operation < M; operation++) {
scanf("%d%d%d", &opType, &x, &y);
switch (opType) {
case 0:
printf("%d\n", getMax(1, 1, N, x, y));
break;
case 1:
updateValue(1, 1, N, x, y);
break;
}
}
return 0;
}