#include <iostream>
#include <fstream>
using namespace std;
int max(int a, int b)
{
if (a > b) {
return a;
} else {
return b;
}
}
int construct(int value[100000], int elem[100000], int startInt, int endInt, int pos)
{
int middle = (startInt + endInt) / 2;
if (startInt == endInt) {
value[pos] = elem[middle];
return value[pos];
}
int first = construct(//start, end,
value, elem, startInt, middle, 2 * pos + 1);
int second = construct(//start, end,
value, elem, middle + 1, endInt, 2 * pos + 2);
value[pos] = max(first, second);
return value[pos];
}
void insert(int value[100000], int startInt, int endInt, int a, int b, int pos)
{
int middle = (startInt + endInt) / 2;
if (startInt == endInt) {
value[pos] = b;
return;
}
if (middle >= a) {
insert(value, startInt, middle, a, b, 2 * pos + 1);
} else {
insert(value, middle + 1, endInt, a, b, 2 * pos + 2);
}
value[pos] = max(value[2 * pos + 1], value[2 * pos + 2]);
}
int retrive(int value[100000], int startInt, int endInt, int a, int b, int pos)
{
int middle = (startInt + endInt) / 2;
int leftMax = 0, rightMax = 0;
if (startInt == endInt) {
return value[pos];
}
if (startInt == a && endInt == b) {
return value[pos];
}
if (middle >= b) {
return retrive(value, startInt, middle, a, b, 2 * pos + 1);
} else if (middle < a) {
return retrive(value, middle + 1, endInt, a, b, 2 * pos + 2);
} else {
leftMax = retrive(value, startInt, middle, a, middle, 2 * pos + 1);
rightMax = retrive(value, middle + 1, endInt, middle + 1, b, 2 * pos + 2);
return max(leftMax, rightMax);
}
}
int value[450001], elem[100001];
int main()
{
ifstream in("arbint.in");
ofstream out("arbint.out");
int n, m, type, a, b;
in >> n >> m;
for (int i = 0; i < n; i++) {
in >> elem[i];
}
construct(value, elem, 0, n - 1, 0);
for (int i = 0; i < m; i++) {
in >> type >> a >> b;
if (type == 0) {
out << retrive(value, 0, n - 1, a - 1, b - 1, 0) << '\n';
} else if (type == 1) {
insert(value, 0, n - 1, a - 1, b, 0);
}
}
return 0;
}