#include<bits/stdc++.h>
using namespace std;
const int NMAX = 1e5 + 5;
int v[NMAX], aint[NMAX * 4];
void build_tree(int left, int right, int node){
if(left == right){
aint[node] = v[left];
return;
}
int middle = (left + right) / 2;
build_tree(left, middle, 2 * node);
build_tree(middle + 1, right, 2 * node + 1);
aint[node] = max(aint[2 * node], aint[2 * node + 1]);
}
void update(int left, int right, int node, int position, int new_value){
if(left == right){
aint[node] = new_value;
return;
}
int middle = (left + right) / 2;
if(position <= middle)
update(left, middle, 2 * node, position, new_value);
else
update(middle + 1, right, 2 * node + 1, position, new_value);
aint[node] = max(aint[2 * node], aint[2 * node + 1]);
}
int query(int left, int right, int node, int query_left, int query_right){
if(left == query_left && right == query_right){
return aint[node];
}
int middle = (left + right) / 2;
int left_son, right_son;
left_son = right_son = -1;
if(query_left <= middle)
left_son = query(left, middle, 2 * node, query_left, middle);
if(middle < query_right)
right_son = query(middle + 1, right, 2 * node + 1, middle + 1, query_right);
return max(left_son, right_son);
}
int main(){
freopen("arbint.in", "r", stdin);
freopen("arbint.out", "w", stdout);
int n, queries;
scanf("%d %d", &n, &queries);
for(int i = 1; i <= n; i++){
scanf("%d", &v[i]);
}
build_tree(1, n, 1);
for(; queries > 0; queries--){
int operation, a, b;
scanf("%d %d %d", &operation, &a, &b);
if(operation == 0){
printf("%d\n", query(1, n, 1, a, b));
}
else if(operation == 1){
update(1, n, 1, a, b);
}
}
return 0;
}