#include <fstream>
#define NMax 200010
using namespace std;
ifstream f("arbint.in");
ofstream g("arbint.out");
int n, m, vals[NMax], intTree[NMax], elem, Max;
int getMax(int a, int b)
{
if (a > b)
return a;
return b;
}
void updateTree(int node, int left, int right, int pos, int elem)
{
if (left == right) {
intTree[node] = elem;
return;
}
else {
int mid = (left + right) / 2;
if (pos <= mid)
updateTree(2 * node, left, mid, pos, elem);
else
updateTree(2 * node + 1, mid + 1, right, pos, elem);
intTree[node] = getMax(intTree[2 * node], intTree[2 * node + 1]);
}
}
void queryTree(int node, int left, int right, int leftInt, int rightInt)
{
if (leftInt <= left && right <= rightInt) {
Max = getMax(Max, intTree[node]);
return;
}
else {
int mid = (left + right) / 2;
if (leftInt <= mid)
queryTree(2 * node, left, mid, leftInt, rightInt);
if (mid < rightInt)
queryTree(2 * node + 1, mid + 1, right, leftInt, rightInt);
}
}
int main()
{
f >> n >> m;
for (int i = 1; i <= n; i++) {
f >> vals[i];
updateTree(1, 1, n, i, vals[i]);
}
int cmd, first, second;
for (int i = 1; i <= m; i++) {
f >> cmd >> first >> second;
if (cmd == 0) {
Max = -1;
queryTree(1, 1, n, first, second);
g << Max << "\n";
}
else
updateTree(1, 1, n, first, second);
}
}