#include <cstdio>
#include <cstring>
#define nmax 100005
using namespace std;
int arbint [4 * nmax + 800];
int N, M, a, b, poz, val, in, fin, maxim , i, tip;
inline int max (int a, int b) {
if (a > b) return a;
return b;
}
void update (int node, int left , int right) {
int mid;
if (left == right) {
//capat de linie
arbint [node] = val;
return ;
}
else
{
mid = (left + right) >> 1;
if (poz <= mid)
update (2 * node, left, mid); // fiul din stanga
else update (2 * node + 1, mid + 1, right); //dreapta
}
arbint [node] = max (arbint [2 * node], arbint [2 * node + 1]);
//cand iesim din stiva sa avem valori pt toti tatii
}
void query (int node, int left, int right) {
if (in <= left && right <= fin) {
if (maxim < arbint [node])
maxim = arbint [node];
return ; //in......left......right.....fin
}
int mid = (left + right) >> 1;
if (in <= mid) query (2 * node, left, mid);
if (mid < fin) query (2 * node + 1, mid + 1, right);
}
int main () {
freopen ("arbint.in", "r", stdin);
freopen ("arbint.out", "w", stdout);
scanf ("%d%d\n", &N, &M);
for (i = 1; i <= N; i++) {
scanf ("%d", &a);
poz = i;
val = a;
update (1, 1, N);
}
for (i = 1; i <= M; i++) {
scanf ("%d%d%d\n", &tip, &a, &b);
if (tip == 0) {
in = a, fin = b;
maxim = -1;
query (1, 1, N);
printf ("%d\n", maxim);
}
else if (tip == 1) {
poz = a, val = b;
update (1, 1, N);
}
}
return 0;
}