#include <fstream>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
const int NMAX = 100000;
const int ARBMAX = 2*NMAX + 10;
int arb[4*NMAX + 10];
int v[NMAX+1];
void insert(int nod, int left, int right, int pos, int newValue) {
if (left != right) {
int mid = (left + right)>>1;
if (pos <= mid) insert(nod<<1, left, mid, pos, newValue);
else insert((nod<<1) + 1, mid + 1, right, pos, newValue);
arb[nod] = max(arb[(nod<<1)], arb[(nod<<1)+1]);
} else arb[nod] = newValue;
}
void init(int nod, int left, int right) {
if (left != right) {
int mid = (left + right)>>1;
init(nod<<1, left, mid);
init((nod<<1) + 1, mid + 1, right);
arb[nod] = max(arb[(nod<<1)], arb[(nod<<1)+1]);
} else arb[nod] = v[left];
}
int query(int nod, int left, int right, int a, int b) {
if (a>right || b<left) return 0; // minvalue
if (a<=left && b>=right) {
return arb[nod];
}
else {
int mid = (left + right)>>1;
int maxim = 0;
if (mid >= left) maxim = max(query(nod<<1, left, mid, a, b), maxim);
if (mid+1 <= right) maxim = max(query((nod<<1) + 1, mid +1, right, a, b), maxim);
return maxim;
}
}
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++) {
int x;
scanf("%d", &v[i]);
//pos = i; newValue = x;
//insert(1, 0, n-1);
}
init(1, 0, n-1);
for (int i=0; i<m; i++) {
int op, aa, bb, maxim;
scanf("%d%d%d", &op, &aa, &bb);
switch (op) {
case 0:
maxim = query(1, 0, n-1, aa-1, bb-1);
printf("%d\n", maxim);
break;
case 1:
insert(1, 0, n-1, aa-1, bb);
break;
}
}
return 0;
}