#include <fstream>
#include <vector>
#include <cassert>
#include <iostream>
using namespace std;
ifstream f("arbint.in");
ofstream g("arbint.out");
static constexpr int INF = ((int)(1e9) + 1);
class Node
{
int val;
inline int my_max(const int x, const int y) const { return ((x > y) ? x : y); }
public:
Node() : val(-INF) {}
Node(const int x) : val(x) {}
Node operator+(const Node &other)
{
return Node(my_max((*this).val, other.val));
}
void set_val(const int x) { val = x; }
int get_val() const { return val; }
};
class SegmentTree
{
int n;
vector<Node> tree;
void build(const int node, const int left, const int right, const vector<int> &input = {}, const int pos = 0, const int val = 0)
{
if (left > right)
return;
if (left == right)
{
if (!input.empty())
tree[node].set_val(input[(left - 1)]);
else
tree[node].set_val(val);
return;
}
int mid = ((left + right) >> 1);
if (!input.empty())
{
build((node << 1), left, mid, input, pos, val),
build(((node << 1) + 1), (mid + 1), right, input, pos, val);
}
else
{
if (pos <= mid)
build((node << 1), left, mid, input, pos, val);
else
build(((node << 1) + 1), (mid + 1), right, input, pos, val);
}
tree[node] = tree[(node << 1)] + tree[((node << 1) + 1)];
return;
}
Node ask(const int node, const int left, const int right, const int ql, const int qr)
{
if (left > right)
return Node();
if (ql <= left && right <= qr)
return tree[node];
int mid = ((left + right) >> 1);
Node p_left, p_right;
if (ql <= mid)
p_left = ask((node << 1), left, mid, ql, qr);
if (qr > mid)
p_right = ask(((node << 1) + 1), (mid + 1), right, ql, qr);
return (p_left + p_right);
}
public:
SegmentTree(const int size, const vector<int> &input)
{
n = size;
tree.resize((n << 2) + 1);
assert(n == (int)input.size());
build(1, 1, n, input);
return;
}
void update(const int pos, const int val)
{
build(1, 1, n, {}, pos, val);
return;
}
int query(const int l, const int r)
{
return ask(1, 1, n, l, r).get_val();
}
void print()
{
for (int i = 1; i < (n << 1); ++i)
cout << tree[i].get_val() << ' ';
cout << '\n';
return;
}
};
int main()
{
int n(0), m(0);
f >> n >> m;
vector<int> v(n, 0);
for (int i = 0; i < n; ++i)
f >> v[i];
SegmentTree S(n, v);
for (int t = 0; t < m; ++t)
{
short int type = 0;
int a = 0, b = 0;
f >> type >> a >> b;
if (type == 0)
g << S.query(a, b) << '\n';
else
S.update(a, b);
}
g.close();
return 0;
}