#include <cmath>
#include <fstream>
#include <vector>
using namespace std;
class IntervalTree
{
public:
IntervalTree(int nums) : vec_(nums * log(nums) / log(2), 0), nums_(nums) {}
void SetVal(int pos, int num)
{
SetVal(1, 1, nums_, pos, num);
}
int GetMax(int left, int right) const
{
return GetMax(1, 1, nums_, left, right);
}
private:
vector<int> vec_;
int nums_;
static int LeftSon(int node) { return (node << 1); }
static int RightSon(int node) { return (node << 1) + 1; }
void SetVal(int node, int x, int y, int pos, int val);
int GetMax(int node, int x, int y, int left, int right) const;
};
void IntervalTree::SetVal(int node, int x, int y, int pos, int val)
{
if (x == y) {
vec_[node] = val;
return;
}
auto mid = x + (y - x) / 2;
if (pos <= mid) {
SetVal(LeftSon(node), x, mid, pos, val);
} else {
SetVal(RightSon(node), mid + 1, y, pos, val);
}
vec_[node] = max(vec_[LeftSon(node)], vec_[RightSon(node)]);
}
int IntervalTree::GetMax(int node, int x, int y, int left, int right) const
{
if (left <= x && y <= right) {
return vec_[node];
}
auto mid = x + (y - x) / 2;
auto res = 0;
if (left <= mid) {
res = max(res, GetMax(LeftSon(node), x, mid, left, right));
}
if (mid < right) {
res = max(res, GetMax(RightSon(node), mid + 1, y, left, right));
}
return res;
}
int main()
{
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int nums, queries;
fin >> nums >> queries;
IntervalTree tree(nums);
for (int i = 1; i <= nums; i += 1) {
int val;
fin >> val;
tree.SetVal(i, val);
}
for (int i = 0; i < queries; i += 1) {
int type, a, b;
fin >> type >> a >> b;
if (type == 0) {
fout << tree.GetMax(a, b) << "\n";
} else {
tree.SetVal(a, b);
}
}
return 0;
}