#include <stdio.h>
#include <stdint.h>
void read_uint32_t(FILE *__restrict stream, uint32_t *__restrict nr) {
uint8_t ch;
*nr = 0;
while ((ch = fgetc(stream)) && ('0' <= ch && ch <= '9')) {
*nr *= 10;
*nr += ch - '0';
}
if (ch == '\r') {
fgetc(stream);
}
}
uint32_t __inline__ __attribute((pure)) max(uint32_t o1, uint32_t o2) {
return o1 > o2 ? o1 : o2;
}
uint32_t __inline__ __attribute((pure)) min(uint32_t o1, uint32_t o2) {
return o1 < o2 ? o1 : o2;
}
uint32_t a[100001];
uint32_t b[400001];
void build(uint32_t p, uint32_t tl, uint32_t tr) {
if (tl == tr) {
b[p] = a[tl];
} else {
uint32_t tm = (tl + tr) / 2;
build(p * 2 , tl , tm);
build(p * 2 + 1, tm + 1, tr);
b[p] = max(b[p * 2], b[p * 2 + 1]);
}
}
void update(uint32_t p, uint32_t tl, uint32_t tr, uint32_t pos, uint32_t v) {
if (tl == tr) {
b[p] = v;
} else {
uint32_t tm = (tl + tr) / 2;
if (pos <= tm) {
update(p * 2 , tl , tm, pos, v);
} else {
update(p * 2 + 1, tm + 1, tr, pos, v);
}
b[p] = max(b[p * 2], b[p * 2 + 1]);
}
}
uint32_t query(uint32_t p, uint32_t tl, uint32_t tr, uint32_t l, uint32_t r) {
if (l <= tl && tr <= r) {
return b[p];
}
uint32_t tm = (tl + tr) / 2;
uint32_t rs = 0;
uint32_t rd = 0;
if (l <= tm) {
rs = query(p * 2 , tl , tm, l, r);
}
if (tm + 1 <= r) {
rd = query(p * 2 + 1, tm + 1, tr, l, r);
}
return max(rs, rd);
}
uint32_t n, m;
int main(void) {
{
FILE *__restrict in = fopen("arbint.in", "r");
FILE *__restrict out = fopen("arbint.out", "w");
read_uint32_t(in, &n);
read_uint32_t(in, &m);
{
int32_t i;
for(i = 1; i <= n; ++i) {
read_uint32_t(in, a + i);
}
}
fgetc(in);
build(1, 1, n);
{
int32_t i;
uint32_t x, y, z;
for(i = 0; i < m; ++i) {
read_uint32_t(in, &x);
read_uint32_t(in, &y);
read_uint32_t(in, &z);
if (x == 0) {
fprintf(out, "%u\n", query(1, 1, n, y, z));
} else {
update(1, 1, n, y, z);
}
}
}
fclose(out);
fclose(in);
}
return 0;
}