#include <stdio.h>
#define MAX_N 100001
int v[MAX_N];
int aint[MAX_N*4];
void build(int node, int nLeft, int nRight) {
int nMid, leftSon, rightSon;
if (nLeft == nRight) {
aint[node] = v[nLeft];
return;
}
nMid = (nLeft+nRight)/2;
leftSon = node+1;
rightSon = node + 2*(nMid-nLeft+1);
build(leftSon, nLeft, nMid);
build(rightSon, nMid+1, nRight);
if (aint[leftSon] > aint[rightSon]) {
aint[node] = aint[leftSon];
} else {
aint[node] = aint[rightSon];
}
}
int query(int node, int nLeft, int nRight, int qLeft, int qRight) {
int nMid, leftSon, rightSon, leftMax, rightMax;
if (qLeft<=nLeft && qRight>=nRight) {
return aint[node];
}
nMid = (nLeft+nRight)/2;
leftSon = node+1;
rightSon = node + 2*(nMid-nLeft+1);
leftMax = 0;
rightMax = 0;
if (qLeft <= nMid) {
leftMax = query(leftSon, nLeft, nMid, qLeft, qRight);
}
if (nMid < qRight) {
rightMax = query(rightSon, nMid+1, nRight, qLeft, qRight);
}
if (leftMax > rightMax) {
return leftMax;
}
return rightMax;
}
void update(int node, int nLeft, int nRight, int pos, int value) {
int nMid, leftSon, rightSon;
if (nLeft == nRight) {
aint[node] = value;
return;
}
nMid = (nLeft+nRight)/2;
leftSon = node+1;
rightSon = node + 2*(nMid-nLeft+1);
if (pos <= nMid) {
update(leftSon, nLeft, nMid, pos, value);
} else {
update(rightSon, nMid+1, nRight, pos, value);
}
if (aint[leftSon] > aint[rightSon]) {
aint[node] = aint[leftSon];
} else {
aint[node] = aint[rightSon];
}
}
int main() {
FILE *fin, *fout;
fin = fopen("arbint.in", "r");
fout = fopen("arbint.out", "w");
int n, q, i, op, a, b;
fscanf(fin, "%d%d", &n, &q);
for (i=0; i<n; i++) {
fscanf(fin, "%d", &v[i]);
}
build (0, 0, n-1);
while (q>0) {
fscanf(fin, "%d%d%d", &op, &a, &b);
a--;
if (op == 1) {
v[a] = b;
update(0, 0, n-1, a, b);
} else if (op == 0) {
b--;
fprintf(fout, "%d\n", query(0, 0, n-1, a, b));
}
q--;
}
fclose(fin);
fclose(fout);
return 0;
}