#include <fstream>
#include <memory>
#include <limits>
#include <algorithm>
#include <vector>
#include <iterator>
using namespace std;
const int INF = std::numeric_limits<int>::max();
struct Node
{
int v;
shared_ptr<Node> left;
shared_ptr<Node> right;
Node(int v = -INF, shared_ptr<Node> left = nullptr, shared_ptr<Node> right = nullptr)
: v {v}, left {left}, right {right}
{}
};
class IntervalTree
{
public:
IntervalTree(const vector<int>& V)
: root {make_shared<Node>()}, size {V.size()}
{
make_tree(root, 0, size - 1, V);
}
void update(int value, int position)
{
update(root, value, position, 0, size - 1);
}
int findMax(int left, int right)
{
return find(root, 0, size - 1, left, right);
}
private:
static void make_tree(
shared_ptr<Node> node,
int begin, int end,
const vector<int>& V)
{
if (begin == end)
{
node->v = V[begin];
return;
}
int middle = begin + (end - begin) / 2;
node->left = make_shared<Node>();
make_tree(node->left, begin, middle, V);
node->right = make_shared<Node>();
make_tree(node->right, middle + 1, end, V);
node->v = max(node->left->v, node->right->v);
}
void update(shared_ptr<Node> node, int v, int pos, int begin, int end)
{
if (begin == end)
{
node->v = v;
return;
}
int middle = begin + (end - begin) / 2;
if (pos <= middle)
update(node->left, v, pos, begin, middle);
else
update(node->right, v, pos, middle + 1, end);
node->v = max(node->left->v, node->right->v);
}
int find(shared_ptr<Node> node, int begin, int end, int l, int r) const
{
if (l <= begin && end <= r)
return node->v;
int middle = begin + (end - begin) / 2;
int u = -INF, v = -INF;
if (l <= middle)
u = find(node->left, begin, middle, max(l, begin), min(r, middle));
if (middle < r)
v = find(node->right, middle + 1, end, max(middle + 1, l), min(r, end));
return max(u, v);
}
private:
shared_ptr<Node> root;
int size;
};
int main()
{
std::ifstream fin("arbint.in");
std::ofstream fout("arbint.out");
int n, m;
fin >> n >> m;
vector<int> V;
copy_n(istream_iterator<int>(fin), n, back_inserter(V));
IntervalTree tree(V);
for (int q, a, b; m; --m)
{
fin >> q >> a >> b;
if (q == 0)
fout << tree.findMax(--a, --b) << '\n';
else
tree.update(b, --a);
}
return 0;
}