#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int *tree;
int size;
} segtree_t;
static inline int max(int a, int b)
{
return (a > b) ? a : b;
}
void segtree_build(segtree_t *st, int *arr, int node, int left, int right)
{
if (left == right)
{
st->tree[node] = arr[left];
return;
}
int mid = (left + right) / 2;
segtree_build(st, arr, node * 2, left, mid);
segtree_build(st, arr, node * 2 + 1, mid + 1, right);
st->tree[node] = max(st->tree[node * 2], st->tree[node * 2 + 1]);
}
void segtree_update(segtree_t *st, int node, int left, int right, int index, int new_val)
{
if (left == right)
{
st->tree[node] = new_val;
return;
}
int mid = (left + right) / 2;
if (index <= mid)
segtree_update(st, node * 2, left, mid, index, new_val);
else
segtree_update(st, node * 2 + 1, mid + 1, right, index, new_val);
st->tree[node] = max(st->tree[node * 2], st->tree[node * 2 + 1]);
}
int segtree_query(const segtree_t *st, int node, int left, int right, int q_left, int q_right)
{
if (q_left <= left && right <= q_right)
return st->tree[node];
if (right < q_left || q_right < left)
return 0;
int mid = (left + right) / 2;
int left_max = segtree_query(st, node * 2, left, mid, q_left, q_right);
int right_max = segtree_query(st, node * 2 + 1, mid + 1, right, q_left, q_right);
return max(left_max, right_max);
}
int main(void)
{
int N, M;
int *arr = NULL;
segtree_t st;
scanf("%d %d", &N, &M);
if ((arr = (int *)malloc((N + 1) * sizeof(arr))) == NULL)
{
perror(NULL);
exit(-1);
}
for (int i = 1; i <= N; i++)
{
scanf("%d", &arr[i]);
}
st.size = N;
if ((st.tree = (int *)malloc(4 * N * sizeof(st.tree))) == NULL)
{
perror(NULL);
exit(-1);
}
segtree_build(&st, arr, 1, 1, N);
for (int op = 0; op < M; op++)
{
int type, a, b;
scanf("%d %d %d", &type, &a, &b);
if (type == 0)
{
printf("%d\n", segtree_query(&st, 1, 1, N, a, b));
}
else
{
segtree_update(&st, 1, 1, N, a, b);
}
}
free(st.tree);
free(arr);
return 0;
}