#include <bits/stdc++.h>
#define MAXX 100000
using namespace std;
ifstream in ("arbint.in");
ofstream out ("arbint.out");
int v[MAXX];
int n, m;
int arbint[2 * MAXX];
int i, j, a, b, op;
void read(){
for (i = 0; i < n; i ++)
in >> v[i];
}
void build(int pos, int nLeft, int nRight) {
if (left == right) {
arbint[pos] = v[left];
return;
}
int nMid, leftSon, rChild;
mid = (left + right) / 2;
lChild = pos + 1;
rightSon = pos + 2 * (mid - left + 1);
build(lChild, left, mid);
build(rChild, mid + 1, right);
arbint[pos] = max(arbint[lChild], arbint[rChild]);
}
void update(int pos, int left, int right, int vpos, int value) {
if (left == right) {
arbint[pos] = value;
return;
}
int mid, lChild, rChild;
mid = (left + right) / 2;
lChild = pos + 1;
rChild = pos + 2 * (mid - left + 1);
if (vpos <= mid)
update(lChild, left, mid, vpos, value);
else
update(rChild, mid + 1, right, vpos, value);
arbint[pos] = max(arbint[lChild], arbint[rChild]);
}
int query(int pos, int left, int right, int qLeft, int qRight) {
if (qLeft <= left && qRight >= right)
return arbint[pos];
int mid, lChild, rChild;
int result;
mid = (left + right) / 2;
lChild = pos + 1;
rChild = pos + 2 * (mid - left + 1);
result = 0;
if (qLeft <= mid)
result = query(lChild, left, mid, qLeft, qRight);
if (mid < qRight)
result = max(result, query(rChild, mid + 1, right, qLeft, qRight));
return result;
}
int main()
{
in >> n >> m;
read();
build(0, 0, n - 1);
for (j = 0; j < m; j ++){
in >> op >> a >> b;
if (op == 0)
out << query(0, 0, n - 1, a - 1, b - 1) << '\n';
if (op == 1){
update (0, 0, n - 1, a - 1, b);
}
}
return 0;
}