#include <fstream>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
const int N_MAX = 1e5;
const int SEGMENT_TREE_DIM = 2 * N_MAX;
template<typename T>
class SegmentTree{
private:
struct Node{
T data;
Node operator+(const Node& other) const{
return {max(data, other.data)};
}
friend void operator+=(Node& a, const Node& b){
a = a + b;
}
}segmentTree[SEGMENT_TREE_DIM];
public:
void build(int node, int left, int right, T v[]){
if(left == right)
segmentTree[node].data = v[left];
else{
int middle = (left + right) / 2;
int leftChild = node + 1;
int rightChild = node + 2 * (middle - left + 1);
build(leftChild, left, middle, v);
build(rightChild, middle + 1, right, v);
segmentTree[node] = segmentTree[leftChild] + segmentTree[rightChild];
}
}
void update(int node, int left, int right, int pos, T val){
if(left == right)
segmentTree[node].data = val;
else{
int middle = (left + right) / 2;
int leftChild = node + 1;
int rightChild = node + 2 * (middle - left + 1);
if(pos <= middle)
update(leftChild, left, middle, pos, val);
else
update(rightChild, middle + 1, right, pos, val);
segmentTree[node] = segmentTree[leftChild] + segmentTree[rightChild];
}
}
T query(int node, int left, int right, int qleft, int qright){
Node retval{};
if(left >= qleft && right <= qright)
retval = segmentTree[node];
else{
int middle = (left + right) / 2;
int leftChild = node + 1;
int rightChild = node + 2 * (middle - left + 1);
if(qleft <= middle)
retval += {query(leftChild, left, middle, qleft, qright)};
if(middle + 1 <= qright)
retval += {query(rightChild, middle + 1, right, qleft, qright)};
}
return retval.data;
}
};
int v[N_MAX];
SegmentTree<int> segtree;
int main(){
int n, queries;
fin >> n >> queries;
for(int i = 0; i < n; ++i)
fin >> v[i];
segtree.build(0, 0, n - 1, v);
for(int i = 0; i < queries; ++i){
int type, a, b;
fin >> type >> a >> b;
if(type)
segtree.update(0, 0, n - 1, a - 1, b);
else
fout << segtree.query(0, 0, n - 1, a - 1, b - 1) << '\n';
}
fin.close();
fout.close();
return 0;
}