#include <cstdio>
#include <algorithm>
using namespace std;
int * A, * Arb;
int N, M;
void actualizare(int nod, int stanga, int dreapta, int poz_el, int val)
{
int mijloc = (stanga + dreapta) >> 1;
if (stanga == poz_el && dreapta == poz_el)
{
Arb[nod] = val;
}
else
{
if (poz_el <= mijloc)
actualizare(nod << 1, stanga, mijloc, poz_el, val);
else
actualizare((nod << 1)+1, mijloc+1, dreapta, poz_el, val);
Arb[nod] = max(Arb[nod<<1], Arb[(nod<<1)+1]);
}
}
int query(int nod, int stanga, int dreapta, int actualStanga, int actualDreapta)
{
if (actualStanga <= stanga && dreapta <= actualDreapta)
return Arb[nod];
int mijloc = (stanga + dreapta)/2;
int x, y;
x = y = 0;
if (actualStanga <= mijloc)
x = query(nod<<1, stanga, mijloc, actualStanga, actualDreapta);
if (mijloc+1<=actualDreapta)
y = query((nod<<1)+1, mijloc+1, dreapta, actualStanga, actualDreapta);
return max(x, y);
}
int main()
{
freopen("arbint.in", "r", stdin);
freopen("arbint.out", "w", stdout);
scanf("%d%d", &N, &M);
int i, lgArb;
int x, a, b;
A = new int[N+5];
for (lgArb=1; lgArb<=N; lgArb <<= 1);
lgArb <<= 1;
Arb = new int[lgArb+5];
for (i = 1; i <= N; i++)
{
scanf("%d", &A[i]);
actualizare(1, 1, N, i, A[i]);
}
for (i = 1; i <= M; i++)
{
scanf("%d%d%d", &x, &a, &b);
if (x == 0)
printf("%d\n", query(1, 1, N, a, b));
else if (x == 1)
actualizare(1, 1, N, a, b);
}
return 0;
}