#include <fstream>
#include <iostream>
#define MAX 100010
using namespace std;
int arbint[300010];
int v[MAX];
int max_on_range(int l, int r, int node, int node_l, int node_r){
if(l == r)
return v[l];
if(l == node_l && r == node_r)
return arbint[node];
int mid;
mid = (node_l + node_r) / 2;
if(mid < l)
return max_on_range(l, r, 2*node + 2, mid + 1, node_r);
if(mid + 1 > r)
return max_on_range(l, r, 2*node + 1, node_l, mid);
else
return max(max_on_range(l, mid, 2*node + 1, node_l, mid), max_on_range(mid + 1, r, 2*node + 2, mid + 1, node_r));
}
void build(int node, int node_l, int node_r){
if(node_r == node_l)
arbint[node] = v[node_l];
else{
int mid;
mid = (node_l + node_r) / 2;
build(2*node + 1, node_l, mid);
build(2*node + 2, mid + 1, node_r);
arbint[node] = max(arbint[2*node + 1], arbint[2*node + 2]);
}
}
void update(int idx, int val, int node, int node_l, int node_r){
if(node_l == node_r){
arbint[node] = val;
v[idx] = val;
return;
}
int mid;
mid = (node_l + node_r) / 2;
if(mid < idx){
update(idx, val, 2*node + 2, mid + 1, node_r);
arbint[node] = max(arbint[2*node + 1], arbint[2*node + 2]);
}
else if(mid + 1 > idx){
update(idx, val, 2*node + 1, node_l, mid);
arbint[node] = max(arbint[2*node + 1], arbint[2*node + 2]);
}
}
string repeat(string s, int n){
if(n == 0)
return "";
else
return s + repeat(s, n - 1);
}
int main(){
ifstream fin;
ofstream fout;
fin.open("arbint.in");
fout.open("arbint.out");
int m, n, q, a, b;
fin >> n >> m;
for(int i=0; i < n; ++i)
fin >> v[i];
build(0, 0, n - 1);
for(int i=0; i < m; ++i){
fin >> q >> a >> b;
if(q){
update(a - 1, b, 0, 0, n - 1);
}
else{
fout << max_on_range(a - 1, b - 1, 0, 0, n - 1) << endl;
}
}
}