#include <bits/stdc++.h>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
#define NMAX 100005
int n, m, v[NMAX], arbore[NMAX * 4];
void build(int node, int left, int right)
{
if (left == right){
arbore[node] = v[left];
}else{
int middle = (left + right) / 2;
build(node*2, left, middle);
build(node*2+1, middle+1, right);
arbore[node] = max(arbore[node*2], arbore[node*2+1]);
}
}
void update(int node, int left, int right, int position, int new_value)
{
if (left == right){
arbore[node] = new_value;
}else{
int middle = (left + right) / 2;
if (position <= middle){
update(node*2, left, middle, position, new_value);
}else{
update(node*2+1, middle+1, right, position, new_value);
}
arbore[node] = max(arbore[node*2], arbore[node*2+1]);
}
}
int query(int node, int left, int right, int query_left, int query_right){
if (query_left <= left && right <= query_right){
return arbore[node];
}else{
int middle = (left + right) / 2;
if (query_right <= middle)
return query(node*2, left, middle, query_left, query_right);
if (middle + 1 <= query_left)
return query(node*2+1, middle+1, right, query_left, query_right);
return max(query(node*2, left, middle, query_left, query_right),
query(node*2+1, middle+1, right, query_left, query_right));
}
}
int main() {
fin >> n >> m;
for (int i=1;i<=n;i++){
fin >> v[i];
}
build(1, 1, n);
while(m --){
int t;
fin >> t;
if (t == 0){
int left, right;
fin >> left >> right;
fout << query(1, 1, n, left, right) << '\n';
}else{
int position, new_value;
fin >> position >> new_value;
update(1, 1, n, position, new_value);
}
}
return 0;
}