#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream f ("arbint.in");
ofstream g ("arbint.out");
vector <int> tree;
void PowOf2(int &n)
{
int pow = 1;
while (pow < n)
{
pow = pow << 1;
}
n = pow;
}
int Maxim(int currentNode, int treeLeft, int treeRight,
int queryLeft, int queryRight)
{
if (queryLeft <= treeLeft && treeRight <= queryRight)
return tree[currentNode];
if (treeRight < queryLeft || queryRight < treeLeft)
return 0;
int middle = (treeLeft + treeRight) / 2;
return max(Maxim(currentNode*2, treeLeft, middle, queryLeft, queryRight),
Maxim(currentNode*2 + 1, middle + 1, treeRight, queryLeft, queryRight));
}
void Update(int currentNode, int treeLeft, int treeRight,
int value, int queryLeft, int queryRight)
{
if (queryLeft <= treeLeft && treeRight <= queryRight)
{
tree[currentNode] = value;
return;
}
if (treeRight < queryLeft || queryRight < treeLeft)
return;
int middle = (treeLeft + treeRight) / 2;
Update(currentNode*2, treeLeft, middle, value, queryLeft, queryRight);
Update(currentNode*2 + 1, middle + 1, treeRight, value, queryLeft, queryRight);
tree[currentNode] = max(tree[currentNode*2], tree[currentNode*2 + 1]);
}
int main()
{
int n, q;
f >> n >> q;
int temp = n;
PowOf2(n);
tree.resize(2 * n);
for (int i = 0; i < temp; i++)
{
f >> tree[n + i];
}
for (int i = n - 1; i >= 1; i--)
{
tree[i] = max(tree[i*2], tree[i*2 + 1]);
}
for (int i = 1; i <= q; i++)
{
int option;
f >> option;
switch (option)
{
case 0:
int left, right;
f >> left >> right;
g << Maxim(1, 1, n, left, right) << "\n";
break;
case 1:
int pos, value;
f >> pos >> value;
Update(1, 1, n, value, pos, pos);
break;
}
}
}