#include <bits/stdc++.h>
#define BUFFER_SIZE 1 << 8
#define DIM 100005
int a[4 * DIM];
inline __attribute__((optimize("-O3"))) int read() {
int n = 0;
char c = getchar_unlocked();
while (!('0' <= c && c <= '9')) {
c = getchar_unlocked();
}
while ('0' <= c && c <= '9') {
n = (n << 3) + (n << 1) + (c - '0');
c = getchar_unlocked();
}
return n;
}
inline __attribute__((optimize("-O3"))) void print(int n) {
char snum[BUFFER_SIZE];
int i = 0;
do {
snum[i++] = n % 10 + '0';
n /= 10;
} while (n);
--i;
while (i >= 0) {
putchar(snum[i--]);
}
putchar('\n');
}
void update(int node, int left, int right, int value, int position) {
if (left == right) {
a[node] = value;
return;
}
int mid = left + (right - left) / 2;
if (position <= mid) {
update(node << 1, left, mid, value, position);
} else {
update((node << 1) | 1, mid + 1, right, value, position);
}
a[node] = std::max(a[node << 1], a[(node << 1) | 1]);
}
void query(int node, int left, int right, int start, int end, int &maxim) {
if (start <= left && right <= end) {
if (maxim < a[node]) {
maxim = a[node];
}
return;
}
int mid = left + (right - left) / 2;
if (start <= mid) {
query(node << 1, left, mid, start, end, maxim);
}
if (mid < end) {
query((node << 1) | 1, mid + 1, right, start, end, maxim);
}
}
int main() {
freopen("arbint.in", "r", stdin);
freopen("arbint.out", "w", stdout);
int N, M, X, A, B, position, value, maxim, start, end;
N = read(), M = read();
for (int i = 1 ; i <= N ; ++i) {
X = read();
position = i;
value = X;
update(1, 1, N, value, position);
}
for (; M ; --M) {
X = read(), A = read(), B = read();
if (X == 0) {
maxim = -1;
start = A, end = B;
query(1, 1, N, start, end, maxim);
print(maxim);
} else {
position = A, value = B;
update(1, 1, N, value, position);
}
}
return 0;
}