#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
#define nmax 100001
#define bucket_dim 320
int i, j, N, M;
int op, a, b, st, dr;
int v[nmax];
int cnt, pos_a, pos_b, dim, buckets;
int bucket[bucket_dim];
int I[bucket_dim];
inline void scrie(unsigned k){
char lin[30], *s;
s = lin + 29; s[0]=0;
do {
unsigned cat = k / 10;
s--;
s[0] = k - cat * 10 + '0';
k = cat;
}while (k);
puts(s);
}
inline void update(int a, int b) {
--a;
cnt = a / dim;
if (bucket[cnt] == v[a + 1]) {
v[a + 1] = bucket[cnt] = 0;
for (int k = 0, j = I[cnt]; k < dim; ++k, ++j) bucket[cnt] = max(bucket[cnt], v[j]);
}
v[a + 1] = b;
if (bucket[cnt] < b) bucket[cnt] = b;
}
inline void query(int a, int b) {
--a;
--b;
int t1, t2, vmax = 0, j;
t1 = a / dim;
t2 = b / dim;
pos_a = a % dim;
pos_b = b % dim;
if (t1 != t2) {
++t1;
--t2;
for (; t1 <= t2; ++t1)
vmax = max(vmax, bucket[t1]);
if (vmax < bucket[(a / dim)])
for (j = a + 1, cnt = pos_a; cnt <= dim; ++cnt, ++j) vmax = max(vmax, v[j]);
if (vmax < bucket[(b / dim)])
for (j = b + 1, cnt = pos_b; cnt >= 0; --cnt, --j) vmax = max(vmax, v[j]);
}
else {
for (j = a + 1, cnt = pos_a; cnt <= pos_b; ++cnt, ++j)
vmax = max(vmax, v[j]);
}
scrie(vmax);
}
int main() {
freopen("arbint.in","r",stdin);
freopen("arbint.out","w",stdout);
scanf("%i%i", &N, &M);
dim = sqrt(1.0 * N);
I[0] = 1;
for (i = 1; i <= N; ++i, ++j) {
scanf("%i", &v[i]);
if (j == dim) {
++cnt, j = 0;
I[cnt] = i;
}
bucket[cnt] = max(bucket[cnt], v[i]);
}
for (i = 1; i <= M; ++i) {
scanf("%i%i%i", &op, &a, &b);
if (op) update(a, b);
else
query(a, b);
}
return 0;
}