#include <fstream>
#include <iostream>
#include <queue>
#include <cstring>
#include <vector>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
const int LMAX = 100005;
int aint[LMAX*3], v[LMAX];
int build(int nod, int st, int dr) {
if (st == dr) {
aint[nod] = v[st];
return aint[nod];
}
else {
int mij = ((st + dr)>>1);
aint[nod] = max(build(nod*2, st, mij), build(nod*2 + 1, mij+1, dr));
return aint[nod];
}
}
int query0(int nod, int st, int dr, int a, int b) {
if (st == a && dr == b) {
return aint[nod];
}
else {
int mij = ((st + dr)>>1);
if (b <= mij) {
return query0(nod*2, st, mij, a, b);
}
else if (a >= mij +1) {
return query0(nod*2 + 1, mij+1, dr, a, b);
}
else {
return max(query0(nod*2, st, mij, a, mij), query0(nod*2 + 1, mij+1, dr, mij+1, b));
}
}
}
int query1(int nod, int st, int dr, int a, int b) {
if (st == dr && st == a) {
aint[nod] = b;
return aint[nod];
}
else {
int mij = ((st + dr) >> 1);
if (mij >= a) {
aint[nod] = query1(nod*2, st, mij,a , b);
}
else {
aint[nod] = query1(nod*2 + 1, mij+1, dr, a, b);
}
return aint[nod];
}
}
int main() {
int n, m, i, a, b;
bool op;
fin >> n >> m;
for (i = 1; i <= n; i++) {
fin >> v[i];
}
build(1,1, n);
while (m--) {
fin >> op >> a >> b;
if (op == 0) {
fout<<query0(1, 1, n, a, b)<<endl;
}
else {
v[a] = b;
build(1,1,n);
}
}
fin.close();
fout.close();
return 0;
}