#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
using namespace std;
vector<int> vals, int_tree;
int construct_int_tree(int l, int r, int i){
if(l==r){
int_tree[i] = vals[l];
return vals[l];
}
int mid = l+(r-l)/2;
int_tree[i] = max(construct_int_tree(l, mid, i*2+1),construct_int_tree(mid+1, r, i*2+2));
return int_tree[i];
}
int maxi(int l, int r, int qs, int qe, int i){
if (qs <= l && qe >= r)
return int_tree[i];
if (r < qs || l > qe)
return -2;
int mid = l+(r-l)/2;
return max(maxi(l, mid, qs, qe, 2*i+1), maxi(mid+1, r, qs, qe, 2*i+2));
}
int change_element(int l, int r, int i, int k, int val){
if(l==r){
if(l==k)
int_tree[i] = val;
return int_tree[i];
}
int mid = l+(r-l)/2;
int_tree[i] = max(change_element(l, mid, i*2+1, k, val),change_element(mid+1, r, i*2+2, k, val));
return int_tree[i];
}
int main() {
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int n, m, x;
/// Read data
fin>>n>>m;
for(int i=0;i<n;++i){
fin>>x;
vals.push_back(x);
}
/// Resize and construct tree
x = 2*static_cast<int>(pow(2, ceil(log2(n))) - 1);
int_tree.resize(x);
construct_int_tree(0, n-1, 0);
/// Walk tree for every range
int a, b, op;
while(m--){
fin>>op>>a>>b;
if(op==0)
fout<<maxi(0, n-1,a-1, b-1, 0)<<'\n';
else
change_element(0,n-1,0,a-1, b);
}
return 0;
}