#include <stdio.h>
#define N_MAX 100000
typedef char bool;
int M, N, pos, val, beg, end, maximum;
int tree[ 4 * N_MAX + 1 ];
inline int lson( int x ) {
return 2 * x;
}
inline int rson( int x ) {
return 2 * x + 1;
}
inline int max( int a, int b ) {
return a > b ? a : b;
}
void update( int top, int l, int r ) {
if( r != l ) {
int m = ( l + r ) / 2;
if( pos > m ) {
update( rson( top ), m + 1, r );
} else {
update( lson( top ), l, m );
}
tree[ top ] = max( tree[ lson( top ) ], tree[ rson( top ) ] );
} else {
tree[ top ] = val;
}
}
void query( int top, int l, int r ) {
if( beg <= l && r <= end ) {
maximum = max( maximum, tree[ top ] );
} else {
int m = ( l + r ) / 2;
if( beg <= m ) {
maximum = max( maximum, query( lson( top ), l, m ) );
}
if( m < end ) {
maximum = max( maximum, query( rson( top ), m + 1, r ) );
}
}
}
int main( ) {
FILE * fin, * fout;
fin = fopen( "arbint.in", "r" );
fout = fopen( "arbint.out", "w" );
int N, M;
fscanf( fin, "%d%d", &N, &M );
int i;
for( i = 1; i <= N; i ++ ) {
int read;
fscanf( fin, "%d", &read );
pos = i;
val = read;
update( 1, 1, N );
}
for( i = 1; i <= M; i ++ ) {
int type, a, b;
fscanf( fin, "%d%d%d", &type, &a, &b );
if( type ) {
pos = a;
val = b;
update( 1, 1, N );
} else {
beg = a;
end = b;
maximum = -1;
query( 1, 1, N );
fprintf( fout, "%d\n", maximum );
}
}
fclose( fin );
fclose( fout );
}