#include <fstream>
using namespace std;
ifstream cin("arbint.in");
ofstream cout("arbint.out");
const int NMAX = 1e5;
int tree[NMAX + 1], v[NMAX + 1], n, q;
void build(int node, int st, int dr){
if(st == dr){
tree[node] = v[st];
return;
}
int mid = ((st + dr) >> 1);
build(2 * node, st, mid);
build(2 * node + 1, mid + 1 , dr);
tree[node] = max(tree[2 * node], tree[2 * node + 1]);
}
int query(int node, int st, int dr, int x, int y){
// ma aflu in [st, dr]
// intervalul [x, y] cuprinde tot intervalul [st, dr]
if(x <= st && y >= dr)
return tree[node];
int mid = ((st + dr) >> 1);
int r1 = 0, r2 = 0;
if(x <= mid)
r1 = query(2 * node, st, mid, x, y);
if(y > mid)
r2 = query(2 * node + 1, mid + 1, dr, x, y);
return max(r1, r2);
}
void update(int node, int st, int dr, int pos, int val){
if(st == dr){
tree[node] = val;
return;
}
int mid = ((st + dr) >> 1);
if(pos <= mid)
update(2 * node, st, mid, pos, val);
else
update(2 * node + 1, mid + 1, dr, pos, val);
tree[node] = max(tree[2 * node], tree[2 * node + 1]);
}
int main(){
cin >> n >> q;
for(int i = 1; i <= n; i++)
cin >> v[i];
build(1, 1, n);
int x = 0, y = 0, task = 0;
for(int i = 0; i < q; i++){
cin >> task >> x >> y;
if(task == 0){
cout << query(1, 1, n, x, y) << "\n";
}else{
update(1, 1, n, x, y);
}
}
return 0;
}