#include <stdio.h>
typedef struct _node_t {
int info;
}node_t;
typedef struct _tree_t {
node_t nodes[100001 * 4 + 66];
}tree_t;
tree_t t;
int max;
int update_tree(int node, int value, int pos, int left, int right)
{
if (left == pos && right == pos)
{
t.nodes[node].info = value;
return;
}
int middle = left + (right - left) / 2;
if (pos <= middle)
update_tree(node * 2, value, pos, left, middle);
if (pos > middle)
update_tree(node * 2 + 1, value, pos, middle + 1, right);
t.nodes[node].info = (t.nodes[2*node].info > t.nodes[2 *node+1].info)?
t.nodes[2*node].info : t.nodes[2*node+1].info;
}
void max_interval(int node, int left, int right, int a, int b)
{
int m1 = -1, m2 = -1;
if (a <= left && right <= b)
{
max = max > t.nodes[node].info ? max : t.nodes[node].info;
return;
}
int middle = left + (right - left) / 2;
if (a <= middle)
max_interval(node * 2, left, middle, a, b);
if (middle < b)
max_interval(node * 2 + 1, middle + 1, right, a, b);
}
void print_tree(int node, int left, int right)
{
if (left == right)
{
printf("[%d %d %d] ", left, right, t.nodes[node].info);
return;
}
int middle = left + (right - left) / 2;
print_tree(node * 2, left, middle);
printf("[%d %d %d] ", left, right, t.nodes[node].info);
print_tree(node * 2 + 1, middle + 1, right);
}
int main()
{
int m, n, i, x;
freopen("arbint.in", "r", stdin);
freopen("arbint.out", "w", stdout);
scanf("%d %d", &n, &m);
for (i = 1; i <= n; i++)
{
scanf("%d", &x);
update_tree(1, x, i, 1, n);
}
for (i = 0; i < m; i++)
{
int code, a, b;
scanf("%d", &code);
switch (code)
{
case 0:
scanf("%d %d", &a, &b);
max = 0;
max_interval(1, 1, n, a, b);
printf("%d\n", max);
break;
case 1:
scanf("%d %d", &a, &b);
update_tree(1, b, a, 1, n);
break;
default:
break;
}
}
return 0;
}