#include <stdio.h>
#define mij (((st) + (dr)) / 2)
#define fiu1 (nod * 2)
#define fiu2 ((nod * 2) + 1)
const int N_MAX = 100010;
const int A_MAX = 1 << 18;
int v[N_MAX], aint[A_MAX];
inline int MAX(int a, int b)
{
return (a > b ? a : b);
}
void update(int nod, int st, int dr, int poz, int val)
{
if (st == poz) aint[nod] = val;
else {
if (poz <= mij) update(fiu1, st, mij, poz, val);
else update(fiu2, mij + 1, dr, poz, val);
aint[nod] = MAX(aint[fiu1], aint[fiu2]);
}
}
int query(int nod, int st, int dr, int a, int b)
{
if (a <= st && dr <= b) return aint[nod];
else {
if (a <= mij) return query(fiu1, st, mij, a, b);
if (b > mij) return query(fiu2, mij + 1, dr, a, b);
}
}
void constr(int nod, int st, int dr)
{
if (st == dr) aint[nod] = v[st];
else {
constr(fiu1, st, mij);
constr(fiu2, mij + 1, dr);
aint[nod] = MAX(aint[fiu1], aint[fiu2]);
}
}
int main()
{
freopen("arbint.in", "r", stdin);
freopen("arbint.out", "w", stdout);
int N, M;
scanf("%d %d\n", &N, &M);
for (int i = 1; i <= N; i ++) {
scanf("%d ", &v[i]);
}
constr(1, 1, N);
int op, a, b;
for (int i = 1; i <= M; i ++) {
scanf("%d %d %d\n", &op, &a, &b);
if (op == 0) printf("%d\n", query(1, 1, N, a, b));
else update(1, 1, N, a, b);
}
return 0;
}