#include <iostream>
using namespace std;
#define DIM 100005
int arb[DIM * 5];
inline int max (int a, int b)
{
return (a > b) ? a : b;
}
void update (int nod, int left, int right, int pos, int val)
{
if (left == right) {
arb[nod] = val;
} else {
int mij = left + ((right - left) >> 1);
if (pos <= mij) {
update (nod << 1, left, mij, pos, val);
}
if (pos > mij) {
update ((nod << 1) + 1, mij + 1, right, pos, val);
}
arb[nod] = max(arb[nod << 1], arb[(nod << 1) + 1]);
}
}
int query (int nod, int left, int right, int a, int b)
{
if (a <= left && right <= b) {
return arb[nod];
}
int mij = left + ((right - left) >> 1);
int maxv;
if (a <= mij) {
maxv = query (nod << 1, left, mij, a, b);
}
if (b > mij) {
maxv = max(maxv, query ((nod << 1) + 1, mij + 1, right, a, b));
}
return maxv;
}
FILE* fin = fopen ("arbint.in", "r");
FILE* fout = fopen ("arbint.out", "w");
int main ()
{
int n, m;
fscanf (fin, "%d %d\n", &n, &m);
for (int i = 1, val; i <= n; ++i) {
fscanf (fin, "%d ", &val);
update (1, 1, n, i, val);
}
for (int i = 1, op, a, b; i <= m; ++i) {
fscanf (fin, "%d %d %d\n", &op, &a, &b);
if (!op) {
fprintf (fout, "%d\n", query (1, 1, n, a, b));
} else {
update (1, 1, n, a, b);
}
}
fclose (fin);
fclose (fout);
return 0;
}