#include <fstream>
#include <vector>
using namespace std;
ifstream cin("arbint.in");
ofstream cout("arbint.out");
class Segment_tree {
public:
Segment_tree(int n): nod(n * 4 + 1, 0) {
this -> n = n;
}
void update(int poz, int val, int st, int dr, int nr_nod) {
if(st == dr) {
nod[nr_nod] = val;
return;
}
else {
if(poz <= (st + dr >> 1)) {
update(poz, val, st, (st + dr) / 2, (nr_nod << 1));
}
else {
update(poz, val, (st + dr) / 2 + 1, dr, (nr_nod << 1 | 1));
}
nod[nr_nod] = max(nod[nr_nod << 1], nod[nr_nod << 1 | 1]);
}
}
void query(int left_s, int right_s, int st, int dr, int nr_nod, int &sol) {
if(st == dr) {
sol = max(nod[nr_nod], sol);
return;
}
else {
if((left_s == st and right_s >= dr) or (right_s == dr and left_s <= st)) {
sol = max(nod[nr_nod], sol);
}
else {
if(left_s <= (st + dr) / 2) {
query(left_s, right_s, st, (st + dr) / 2, (nr_nod << 1), sol);
}
if(right_s >= (st + dr) / 2 + 1) {
query(left_s, right_s, (st + dr) / 2 + 1, dr, (nr_nod << 1 | 1), sol);
}
}
}
}
private:
int n;
vector< int > nod;
};
int main() {
int n, m;
cin >> n >> m;
vector< int > v(n + 1);
Segment_tree *tree = new Segment_tree(n);
for(int i = 1; i <= n; i ++) {
int val;
cin >> val;
tree -> update(i, val, 1, n, 1);
}
for(int i = 1; i <= m; i ++) {
int type;
cin >> type;
if(type) {
int poz;
int val;
cin >> poz >> val;
tree -> update(poz, val, 1, n, 1);
}
else {
int left_s;
int right_s;
cin >> left_s >> right_s;
int sol = 0;
tree -> query(left_s, right_s, 1, n, 1, sol);
cout << sol << '\n';
}
}
delete tree;
return 0;
}