#include <iostream>
#include <fstream>
using namespace std;
ifstream f("arbint.in");
ofstream g("arbint.out");
int n , m , t , a , b;
int v[100001];
int tree[400001];
int constructTree(int left , int right , int index){
if(left == right){
tree[index] = v[left];
return tree[index];
}
else{
int m = (left + right) / 2;
int a = constructTree(left , m , 2 * index + 1);
int b = constructTree(m + 1 , right , 2 * index + 2);
tree[index] = max(a , b);
return tree[index];
}
}
void update(int left , int right , int index , int poz , int val){
if(poz < left or poz > right)
return;
else if(left == right){
if(left == poz)
tree[index] = val;
}
else{
int m = (left + right) / 2;
update(left , m , 2 * index + 1 , poz , val);
update(m + 1 , right , 2 * index + 2 , poz , val);
tree[index] = max(tree[2 * index + 1] , tree[2 * index + 2]);
}
}
int query(int left , int right , int index , int a , int b){
if(a > right or b < left)
return 0;
else if(a <= left && b >= right)
return tree[index];
else{
int m = (left + right) / 2;
int x = query(left , m , 2 * index + 1 , a , b);
int y = query(m + 1 , right , 2 * index + 2 , a , b);
return max(x , y);
}
}
int main()
{
f >> n >> m;
for(int i = 1 ; i <= n ; ++i)
f >> v[i];
constructTree(1 , n , 0);
for(int i = 1 ; i <= m ; ++i){
f >> t >> a >> b;
if(t == 0) g << query(1 , n , 0 , a , b) << "\n";
else if(t == 1) update(1 , n , 0 , a , b);
}
return 0;
}