#include <cstdio>
#include <cassert>
#define MAX_N 100001
int n, m;
int v[MAX_N];
int aint[MAX_N * 4];
void read() {
assert(scanf("%d%d", &n, &m) == 2);
for (int i = 1; i <= n; ++i)
assert(scanf("%d", &v[i]) == 1);
}
inline int max(int x, int y) {
return (x > y) ? x : y;
}
void build(int node, int left, int right) {
if (left == right) {
aint[node] = v[left];
return;
}
int mid = (left + right) >> 1;
int left_son = (node << 1);
int right_son = (node << 1) + 1;
build(left_son, left, mid);
build(right_son, mid + 1, right);
aint[node] = max(aint[left_son], aint[right_son]);
}
void update(int node, int left, int right, int pos, int val) {
if (left == right) {
aint[node] = val;
return;
}
int mid = (left + right) >> 1;
int left_son = (node << 1);
int right_son = (node << 1) + 1;
if (pos <= mid)
update(left_son, left, mid, pos, val);
else
update(right_son, mid + 1, right, pos, val);
aint[node] = max(aint[left_son], aint[right_son]);
}
int query(int node, int left, int right, int a, int b) {
if (a <= left && right <= b)
return aint[node];
int mid = (left + right) >> 1;
int left_son = (node << 1);
int right_son = (node << 1) + 1;
int result = 0;
if (a <= mid)
result = query(left_son, left, mid, a, b);
if (b > mid)
result = max(result, query(right_son, mid + 1, right, a, b));
return result;
}
int main() {
assert(freopen("arbint.in","r", stdin));
assert(freopen("arbint.out", "w", stdout));
read();
build(1, 1, n);
for (int i = 1; i <= m; ++i) {
int type, a, b;
assert(scanf("%d%d%d", &type, &a, &b) == 3);
if (type == 1)
update(1, 1, n, a, b);
else
printf("%d\n", query(1, 1, n, a, b));
}
}