#include <fstream>
#include <iostream>
#include <cmath>
using namespace std;
int query(int index, int left, int right, int cLeft, int cRight, int a[], int tree[])
{
if (left <= cLeft && right >= cRight)
return tree[index];
if (cLeft > right || cRight < left)
return -1;
int leftMax = query(index * 2 + 1, left, right, cLeft, (cLeft + cRight) / 2, a, tree);
int rightMax = query(index * 2 + 2, left, right, (cLeft + cRight) / 2 + 1, cRight, a, tree);
return max(leftMax, rightMax);
}
void update(int index, int pos, int left, int right, int a[], int tree[])
{
if (left == right && pos == left)
{
tree[index] = a[pos];
return;
}
if (pos >= left && pos <= right)
{
update(index * 2 + 1, pos, left, (left + right) / 2, a, tree);
update(index * 2 + 2, pos, (left + right) / 2 + 1, right, a, tree);
tree[index] = max(tree[index * 2 + 1], tree[index * 2 + 2]);
}
}
int main()
{
int N, M, i, length;
ifstream f("arbint.in");
f >> N >> M;
length = (1 << ((int)log2(N) + 2)) - 1;
int a[N], tree[length];
fill(tree, tree + length, -1);
for (i = 0; i < N; i++)
{
f >> a[i];
update(0, i, 0, N - 1, a, tree);
}
int op, x, y;
ofstream g("arbint.out");
for (i = 0; i < M; i++)
{
f >> op >> x >> y;
if (op == 0)
g << query(0, x - 1, y - 1, 0, N - 1, a, tree) << '\n';
else if (op == 1)
{
a[x - 1] = y;
update(0, x - 1, 0, N - 1, a, tree);
}
}
f.close();
g.close();
return 0;
}