#include <fstream>
#include <cmath>
using namespace std;
size_t leftChild(size_t node) {
return (node << 1) + 1;
}
size_t rightChild(size_t node) {
return (node << 1) + 2;
}
void buildIntervalTree(int *tree, int node, int *v, int a, int b) {
tree[node] = v[a];
if (a < b) {
int mid = ((b - a) >> 1) + a;
buildIntervalTree(tree, leftChild(node), v, a, mid);
buildIntervalTree(tree, rightChild(node), v, mid + 1, b);
tree[node] = max(tree[leftChild(node)], tree[rightChild(node)]);
}
}
// leftBound e capatul stanga pentru informatia din intervalT[node]
// rightBound e capatul dreapta pentru informatia din intervalT[node]
// [a, b] e intervalul pentru care se face interogarea
int interogate(int *intervalT, size_t node, int leftBound, int rightBound,
const int a, const int b) {
if (a > b || (a <= leftBound && rightBound <= b)) {
return intervalT[node];
} else {
int mid = ((rightBound - leftBound) >> 1) + leftBound;
int leftMax, rightMax, both = 0;
if (a <= mid) {
leftMax = interogate(intervalT, leftChild(node), leftBound, mid,
a, b);
both |= 1;
}
if (mid < b) {
rightMax = interogate(intervalT, rightChild(node), mid + 1,
rightBound, a, b);
both |= 2;
}
if (both == 3)
return max(leftMax, rightMax);
else if (both == 1)
return leftMax;
else if (both == 2)
return rightMax;
else
return intervalT[node];
}
}
// pentru problema data la actualizare intervalul [a, b] e mereu [idx, idx]
void update(int *intervalTree, size_t node, int leftBound, int rightBound,
const int idx, const int newValue) {
if (leftBound == idx && rightBound == idx) {
intervalTree[node] = newValue;
} else {
int mid = ((rightBound - leftBound) >> 1) + leftBound;
if (idx <= mid) {
update(intervalTree, leftChild(node), leftBound, mid, idx,
newValue);
}
if (mid < idx) {
update(intervalTree, rightChild(node), mid + 1, rightBound, idx,
newValue);
}
intervalTree[node] = max(intervalTree[leftChild(node)],
intervalTree[rightChild(node)]);
}
}
int main(void) {
ifstream in("arbint.in");
ofstream out("arbint.out");
int n, m, i;
in >> n >> m;
int v[n];
for (i = 0; i < n; i++)
in >> v[i];
// k = [log2(n)] + 1
int k = (int) ceil(log2((double) n));
int treeCapacity = 1 << (k + 1);
int intervalTree[treeCapacity];
buildIntervalTree(intervalTree, 0, v, 0, n - 1);
int f, a, b;
for (i = 0; i < m; i++) {
in >> f >> a >> b;
if (f == 0)
out << interogate((int *) intervalTree, 0, 0, n - 1, a - 1, b - 1)
<< '\n';
else
update((int *) intervalTree, 0, 0, n - 1, a - 1, b);
}
in.close();
out.close();
return 0;
}