#include <vector>
#include <fstream>
#include <iostream>
class SegmentTree{
struct Node{
int value;
Node operator+(const Node & node){
return Node{std::max(node.value, value)};
}
friend std::ostream& operator<<(std::ostream& os, const Node& n){
os<<n.value;
}
};
std::vector<Node> v;
int noNodes;
void build(int currentNode, int left, int right, std::vector<int>& list){
if(left == right){
v[currentNode].value = list[left];
return;
}
int mid = (left + right) / 2,
leftChild = currentNode + 1,
rightChild = currentNode + 2 * (mid - left + 1);
build(leftChild, left, mid, list);
build(rightChild, mid + 1, right, list);
v[currentNode] = v[leftChild] + v[rightChild];
}
void innerReplace(int index, int value, int currentNode, int left, int right){
if(left == right){
v[currentNode].value = value;
return;
}
int mid = (left + right) / 2,
leftChild = currentNode + 1,
rightChild = currentNode + 2 * (mid - left + 1);
if(index <= mid)
innerReplace(index, value, leftChild, left, mid);
else
innerReplace(index, value, rightChild, mid + 1, right);
v[currentNode] = v[leftChild] + v[rightChild];
}
Node innerQuery(int currentNode, int left, int right, int queryLeft, int queryRight){
if(left == queryLeft && right == queryRight){
return v[currentNode];
}
int mid = (left + right) / 2,
leftChild = currentNode + 1,
rightChild = currentNode + 2 * (mid - left + 1);
if(queryRight <= mid)
return innerQuery(leftChild, left, mid, queryLeft, queryRight);
if(mid < queryLeft)
return innerQuery(rightChild, mid + 1, right, queryLeft, queryRight);
return innerQuery(leftChild, left, mid, queryLeft, mid) +
innerQuery(rightChild, mid + 1, right, mid + 1, queryRight);
}
public:
SegmentTree(std::vector<int>& list){
noNodes = list.size();
v.resize(2 * noNodes - 1);
build(0, 0, noNodes - 1, list);
}
void replace(int index, int value){
innerReplace(index, value, 0, 0, noNodes - 1);
}
int query(int left, int right){
if(left < 0 || right >= noNodes){
std::cout<<"Out of bounds query\n";
return 0;
}
if(left > right){
std::cout<<"Invalid query\n";
return 0;
}
Node a = innerQuery(0, 0, noNodes - 1, left, right);
return a.value;
}
void show(){
for(auto node : v){
std::cout<<node<<' ';
}
std::cout<<std::endl;
}
};
int main(){
int n, m, op, op1, op2;
std::ifstream in("arbint.in");
std::ofstream out("arbint.out");
std::vector<int> x;
in>>n>>m;
x.resize(n);
for(int i = 0; i < n; i++){
in>>x[i];
}
SegmentTree v(x);
for(int i = 0; i < m; i++){
in>>op>>op1>>op2;
if(op == 0){
out<<v.query(op1 - 1, op2 - 1)<<std::endl;
}else{
v.replace(op1 - 1, op2);
}
}
}