/*
! QUERY:
* 0 x y - afiseaza maximul din intervalul [x, y]
* 1 x y - valoarea elementului de pe pozitia x devine y
*/
#include <bits/stdc++.h>
using namespace std;
#define INFILE "arbint.in"
#define OUTFILE "arbint.out"
const int N_MAX = 1e5;
int n, queries;
int aint[4 * N_MAX + 1];
void update(int node, int left, int right, int position, int value){
if(left == right) {
aint[node] = value;
return;
}
int middle = (left + right) >> 1;
if(position <= middle){
update(node << 1, left, middle, position, value);
} else {
update(node << 1 | 1, middle + 1, right, position, value);
}
aint[node] = max(aint[node << 1], aint[node << 1 | 1]);
}
int query(int node, int left, int right, int queryLeft, int queryRight){
if(queryLeft <= left && right <= queryRight){
return aint[node];
}
int middle = (left + right) >> 1;
if(queryRight <= middle) return query(node << 1, left, middle, queryLeft, queryRight);
if(queryLeft > middle) return query(node << 1 | 1, middle + 1, right, queryLeft, queryRight);
return max(
query(node << 1, left, middle, queryLeft, queryRight),
query(node << 1 | 1, middle + 1, right, queryLeft, queryRight)
);
}
void solve(){
cin >> n >> queries;
for(int i = 1; i <= n; ++i){
int aux; cin >> aux;
update(1, 1, n, i, aux);
}
while(queries--){
bool type; cin >> type;
int x, y; cin >> x >> y;
if(!type){
cout << query(1, 1, n, x, y) << '\n';
}
else {
update(1, 1, n, x, y);
}
}
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
freopen(INFILE, "r", stdin);
freopen(OUTFILE, "w", stdout);
solve();
return 0;
}