#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream fin("arbint.in");
ofstream fout("arbint.out");
#define cin fin
#define cout fout
struct segTree_
{
vector<int> tree_;
int elementsSize;
segTree_();
void resize(int n);
void build(vector<int>& elements);
void build_(vector<int>& elements, int node, int left, int right);
void update(int index, int val);
void update_(int index, int val, int node, int left, int right);
int rangeQuery(int leftQ, int rightQ);
int rangeQuery_(int leftQ, int rightQ, int node, int left, int right);
};
int main()
{
int n, q;
segTree_ segmentTree;
vector<int> elements;
cin >> n >> q;
elements.resize(n);
for(int i = 0; i < n; i++)
{
cin >> elements[i];
}
segmentTree.build(elements);
for(int i = 0, queryType, a, b; i < q; i++)
{
cin >> queryType >> a >> b;
if(queryType == 0)
{
a--;
b--;
cout << segmentTree.rangeQuery(a, b) << '\n';
}
else
{
a--;
segmentTree.update(a, b);
}
}
return 0;
}
segTree_::segTree_()
{
}
void segTree_::resize(int n)
{
this->tree_.clear();
this->tree_.shrink_to_fit();
this->tree_.resize(3 * n + 10);
this->elementsSize = n;
}
void segTree_::build(vector<int>& elements)
{
this->resize(elements.size());
this->build_(elements, 1, 0, this->elementsSize - 1);
}
void segTree_::build_(vector<int>& elements, int node, int left, int right)
{
if(left == right)
{
this->tree_[node] = elements[left];
return;
}
int middle = (left + right) / 2;
this->build_(elements, node * 2, left, middle);
this->build_(elements, node * 2 + 1, middle + 1, right);
this->tree_[node] = max(this->tree_[node * 2], this->tree_[node * 2 + 1]);
}
void segTree_::update(int index, int val)
{
this->update_(index, val, 1, 0, this->elementsSize - 1);
}
void segTree_::update_(int index, int val, int node, int left, int right)
{
if(left == right)
{
this->tree_[node] = val;
return;
}
int middle = (left + right) / 2;
if(index <= middle)
{
this->update_(index, val, node * 2, left, middle);
}
else
{
this->update_(index, val, node * 2 + 1, middle + 1, right);
}
this->tree_[node] = max(this->tree_[node * 2], this->tree_[node * 2 + 1]);
}
int segTree_::rangeQuery(int leftQ, int rightQ)
{
return this->rangeQuery_(leftQ, rightQ, 1, 0, this->elementsSize - 1);
}
int segTree_::rangeQuery_(int leftQ, int rightQ, int node, int left, int right)
{
if(leftQ <= left && right <= rightQ)
{
return this->tree_[node];
}
else if(left <= rightQ && right >= leftQ)
{
int middle = (left + right) / 2;
return max(this->rangeQuery_(leftQ, rightQ, node * 2, left, middle), this->rangeQuery_(leftQ, rightQ, node * 2 + 1, middle + 1, right));
}
return -1;
}