#include <fstream>
#define NMax 100010
using namespace std;
ifstream f("arbint.in");
ofstream g("arbint.out");
int nE, queries, val[NMax], segTree[4*NMax];
int get_max(int a, int b)
{
if (a > b)
return a;
return b;
}
void build_seg_tree(int node, int left, int right)
{
if (left == right) {
segTree[node] = val[left];
return;
}
int mid = (left + right) / 2;
build_seg_tree(2 * node, left, mid);
build_seg_tree(2 * node + 1, mid + 1, right);
segTree[node] = get_max(segTree[2 * node], segTree[2 * node + 1]);
}
void update_seg_tree(int node, int left, int right, int pos, int val)
{
if (left == right) {
segTree[node] = val;
return;
}
int mid = (left + right) / 2;
if (pos <= mid)
update_seg_tree(2 * node, left, mid, pos, val);
else
update_seg_tree(2 * node + 1, mid + 1, right, pos, val);
segTree[node] = get_max(segTree[2 * node], segTree[2 * node + 1]);
}
int query_tree(int node, int left, int right, int rangeLeft, int rangeRight)
{
if (right < rangeLeft || left > rangeRight)
return -1;
if (rangeLeft <= left && right <= rangeRight)
return segTree[node];
int mid = (left + right) / 2;
int maxLeft = query_tree(2 * node, left, mid, rangeLeft, rangeRight);
int maxRight = query_tree(2 * node + 1, mid + 1, right, rangeLeft, rangeRight);
return get_max(maxLeft, maxRight);
}
int main()
{
f >> nE >> queries;
for (int i = 1; i <= nE; i++)
f >> val[i];
build_seg_tree(1, 1, nE);
int cmd, a, b;
for (int i = 1; i <= queries; i++) {
f >> cmd >> a >> b;
if (cmd == 1)
update_seg_tree(1, 1, nE, a, b);
else {
int q = query_tree(1, 1, nE, a, b);
g << q << '\n';
}
}
return 0;
}