#include <fstream>
#define NMAX 100005
using namespace std;
ifstream in("arbint.in");
ofstream out("arbint.out");
int v[NMAX];
int aint[2 * NMAX];
void build(int node, int nleft, int nright)
{
if (nleft == nright)
{
aint[node] = v[nleft];
return;
}
int nmid = (nleft + nright) / 2;
int leftson = node + 1;
int rightson = node + 2 * (nmid - nleft + 1);
build(leftson, nleft, nmid);
build(rightson, nmid + 1, nright);
aint[node] = max(aint[leftson], aint[rightson]);
}
int query(int node, int nleft, int nright, int qleft, int qright)
{
if (qleft <= nleft && nright <= qright)
return aint[node];
int nmid = (nleft + nright) / 2;
int leftson = node + 1;
int rightson = node + 2 * (nmid - nleft + 1);
int maxx = -1;
if (qleft <= nmid)
maxx = max(maxx, query(leftson, nleft, nmid, qleft, qright));
if (nmid < qright)
maxx = max(maxx, query(rightson, nmid + 1, nright, qleft, qright));
return maxx;
}
void update(int node, int nleft, int nright, int pos, int val)
{
if (nleft == nright)
{
aint[node] = val;
return;
}
int nmid = (nleft + nright) / 2;
int leftson = node + 1;
int rightson = node + 2 * (nmid - nleft + 1);
if (pos <= nmid)
update(leftson, nleft, nmid, pos, val);
else if (nmid < pos)
update(rightson, nmid + 1, nright, pos, val);
aint[node] = max(aint[leftson], aint[rightson]);
}
int main()
{
int n, m, i, j, op, a, b;
in >> n >> m;
for (i = 1; i <= n; ++i)
in >> v[i];
build(1, 1, n);
for (i = 1; i <= m; ++i)
{
in >> op >> a >> b;
if (op == 0)
out << query(1, 1, n, a, b) << '\n';
else if (op == 1)
update(1, 1, n, a, b);
}
return 0;
}