#include <iostream>
#include <fstream>
using namespace std;
#define MAX 100000
int v[MAX], arb[MAX * 4];
void carb(/*int v[], int arb[], */int nod, int st, int dr) {
if (st == dr) {
arb[nod] = v[st];
} else {
int mid = (st + dr) / 2;
carb(/*v, arb, */nod << 1, st, mid);
carb(/*v, arb,*/(nod << 1) + 1, mid + 1, dr);
arb[nod] = max(arb[nod << 1], arb[(nod << 1) + 1]);
}
}
void update(/*int arb[], */int poz, int val, int nod, int st, int dr) {
if (st == dr) {
arb[nod] = val;
return;
}
int mid = (st + dr) >> 1;
if (poz <= mid) {
update(/*arb, */poz, val, nod << 1, st, mid);
} else {
update(/*arb, */poz, val, (nod << 1) + 1, mid + 1, dr);
}
arb[nod] = max(arb[nod << 1], arb[(nod << 1) + 1]);
}
/*
void update(int arb[], int poz, int val, int n) {
int mid, nod = 1, st = 1, dr = n;
while (st < dr) {
mid = (st + dr) / 2;
if (mid < poz) {
st = mid + 1;
nod = 2 * nod + 1;
} else {
dr = mid;
nod = 2 * nod;
}
}
arb[nod] = val;
nod /= 2;
while (nod > 0) {
arb[nod] = max(arb[nod * 2], arb[nod * 2 + 1]);
nod /= 2;
}
}*/
int query(/*int arb[], */int a, int b, int nod, int st, int dr) {
if (a <= st && dr <= b) {
return arb[nod];
}
if (st > b || dr < a) {
return 0;
}
int mid = (st + dr) >> 1;
int s = 0, d = 0;
if (a <= mid) {
s = query(/*arb, */a, b, nod << 1, st, mid);
}
if (b > mid) {
d = query(/*arb, */a, b, (nod << 1) + 1, mid + 1, dr);
}
return max(s, d);
}
int main()
{
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int /*v[MAX], */n, m, /*arb[MAX * 4], */op, a, b;
fin >> n >> m;
for (int i = 1; i <= n; i++) {
fin >> v[i];
}
carb(/*v, arb, */1, 1, n);
for (int i = 0; i < m; i++) {
fin >> op >> a >> b;
if (op == 0) {
fout << query(/*arb, */a, b, 1, 1, n) << endl;
} else {
update(/*arb, */a, b, 1, 1, n);
}
}
fin.close();
fout.close();
return 0;
}