#include <cstdio>
#define SIZE 100005
using namespace std;
int n, m, i, int_tree[4 * SIZE];
int index, value, start, finish, MAX;
inline void update(int, int, int);
inline void query(int, int, int);
inline int max(int a, int b)
{
if( a > b)
return a;
return b;
}
int main()
{
freopen("arbint.in", "r", stdin);
freopen("arbint.out", "w", stdout);
scanf("%d%d", &n, &m);
for(int i=1; i<=n; ++i)
{
int x;
scanf("%d", &x);
index = i;
value = x;
update(1, 1, n);
}
while( m-- )
{
int op, a, b;
scanf("%d%d%d", &op, &a, &b);
if( !op )
{
start = a;
finish = b;
MAX = -1;
query(1, 1, n);
printf("%d\n", MAX);
}
else
{
index = a;
value = b;
update(1, 1, n);
}
}
return 0;
}
inline void update(int node, int left, int right)
{
if( left == right)
{
int_tree[ node ] = value;
return ;
}
int middle = (left + right) / 2;
if( index <= middle)
update( 2 * node, left, middle);
else
update( 2 * node + 1, middle + 1, right);
int_tree[ node ] = max( int_tree[ 2 * node ], int_tree[ 2 * node + 1] );
}
inline void query(int node, int left, int right)
{
if( start <= left && right <= finish)
{
if( MAX < int_tree[ node ])
MAX = int_tree[ node ];
return ;
}
int middle = (left + right) / 2;
if( start <= middle)
query( 2 * node, left, middle);
if( middle < finish )
query( 2 * node + 1, middle + 1, right);
}