#include <fstream>
#include <algorithm>
class Tree {
int *myArr;
int nV;
void update(int node, int left, int right, int &wut, int &val) {
if(left == right) {
myArr[node] = val;
return;
}
int m = (left + right) >> 1;
if(wut <= m) {
update(node << 1, left, m, wut, val);
} else {
update((node << 1) + 1, m + 1, right, wut,val);
}
myArr[node] = std::max(myArr[node << 1], myArr[(node << 1) + 1]);
}
int query(int node, int left, int right, int &a, int &b) {
if(a <= left && right <= b) {
return myArr[node];
}
int m = (left + right) >> 1, m1 = -1, m2 = -1;
if(a <= m) {
m1 = query(node << 1, left, m, a, b);
}
if(m < b) {
m2 = query((node << 1) + 1, m + 1, right, a, b);
}
return std::max(m1, m2);
}
public:
Tree(int a) : myArr(new int[(a << 2) + 66]), nV(a) {
int n = (a << 2) + 66;
for(int i = 0; i < n; i++) {
myArr[i] = -1;
}
}
~Tree() {
nV = 0;
delete[] myArr;
}
void update(int &a, int &b) {
update(1, 1, nV, a, b);
}
int query(int &a, int &b) {
return query(1, 1, nV, a, b);
}
};
int main() {
std::ifstream in("arbint.in");
std::ofstream out("arbint.out");
int nV, oP, o, b, d;
in >> nV >> oP;
Tree a(nV);
for(int i = 1; i <= nV; i++) {
in >> b;
a.update(i, b);
}
for(int i = 0; i < oP; i++) {
in >> o >> b >> d;
if(o == 0) {
out << a.query(b, d) << '\n';
} else {
a.update(b, d);
}
}
return 0;
}