#include <iostream>
#include <stdio.h>
using namespace std;
const int NMAX = 100005;
int v[NMAX], aint[4 * NMAX];
int n;
void build(int node, int l, int r) {
if (l > r)
return;
if (l == r) {
aint[node] = v[l];
return;
}
int mid = (l + r) / 2;
build(2 * node, l, mid);
build(2 * node + 1, mid + 1, r);
aint[node] = max(aint[2 * node], aint[2 * node + 1]);
}
void update(int node, int l, int r, int poz, int val) {
if (l > r || poz < l || poz > r)
return;
if (l == r) {
aint[node] = val;
return;
}
int mid = (l + r) / 2;
update(2 * node, l, mid, poz, val);
update(2 * node + 1, mid + 1, r, poz, val);
aint[node] = max(aint[2 * node], aint[2 * node + 1]);
}
int query(int node, int l, int r, int ql, int qr) {
if (l > r || qr < l || ql > r) //nu e inclus deloc
return -1; //nu infl val
if (ql <= l && qr >= r) //e inclus total
return aint[node];
int mid = (l + r) / 2;
int maxst = query(2 * node, l, mid, ql, qr);
int maxdr = query(2 * node + 1, mid + 1, r, ql, qr);
return max(maxst, maxdr);
}
int main() {
freopen ("arbint.in", "r", stdin);
freopen ("arbint.out", "w", stdout);
int m, i, op, a, b;
scanf ("%d%d", &n, &m);
for (i = 1; i <= n; i++)
scanf ("%d", &v[i]);
build(1, 1, n);
for (i = 1; i <= m; i++) {
scanf ("%d%d%d", &op, &a, &b);
if (op == 0)
printf ("%d\n", query(1, 1, n, a, b));
else
update(1, 1, n, a, b);
}
return 0;
}