#include <bits/stdc++.h>
using namespace std;
ifstream in("arbint.in");
ofstream out("arbint.out");
const int NMAX = 100001;
int N, M, t[4 * NMAX];
int arr[NMAX];
void max_tree_build(int v, int tl, int tr)
{
if(tl == tr)
{
t[v] = arr[tl];
} else
{
int tm = (tl + tr) / 2;
max_tree_build(v * 2, tl, tm);
max_tree_build(v * 2 + 1, tm + 1, tr);
t[v] = max(t[v * 2], t[v * 2 + 1]);
}
}
int max_query(int v, int tl, int tr, int l, int r)
{
if(l > r)
return 0;
if(l == tl && r == tr)
{
return t[v];
}
int tm = (tl + tr) / 2;
return max(max_query(v * 2, tl, tm, l, min(r, tm)), max_query(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r));
}
void max_tree_update(int v, int tl, int tr, int pos, int val)
{
if(tl == tr)
{
t[v] = val;
} else
{
int tm = (tl + tr) / 2;
if(pos <= tm)
max_tree_update(v * 2, tl, tm, pos, val);
else
max_tree_update(v * 2 + 1, tm + 1, tr, pos, val);
t[v] = max(t[2 * v], t[2 * v + 1]);
}
}
int main()
{
in >> N >> M;
for(int i = 1; i <= N; i++)
in >> arr[i];
max_tree_build(1, 1, N);
int op, a, b;
for(int i = 1; i <= M; i++)
{
in >> op >> a >> b;
if(op == 0)
{
out << max_query(1, 1, N, a, b) << "\n";
} else if(op == 1)
{
max_tree_update(1, 1, N, a, b);
}
}
return 0;
}