#include <iostream>
using namespace std;
const int MAXN = 1e5;
int v[MAXN+1];
int aint[2*MAXN];
void build( int left, int right, int node ) {
int mid, leftSon, rightSon;
if( left == right ) {
aint[node] = v[left];
return;
}
mid = ( left + right ) / 2;
leftSon = node + 1;
rightSon = node + 2 * ( mid - left + 1 );
build( left, mid, leftSon );
build( mid + 1, right, rightSon );
aint[node] = max( aint[leftSon], aint[rightSon] );
}
void update( int left, int right, int node, int x, int val ) {
int mid;
if( left == right ) {
aint[node] = val;
return;
}
mid = ( left + right ) / 2;
if( x <= mid )
update( left, mid, node + 1, x, val );
else
update( mid + 1, right, node + 2 * ( mid - left + 1 ), x, val );
aint[node] = max( aint[node+1], aint[node+2*(mid-left+1)] );
}
int query( int left, int right, int node, int qleft, int qright ) {
int maxi, mid;
if( left >= qleft && right <= qright ) {
return aint[node];
}
mid = ( left + right ) / 2;
maxi = 0;
if( qleft <= mid )
maxi = max( maxi, query( left, mid, node + 1, qleft, qright ) );
if( mid < qright )
maxi = max( maxi, query( mid + 1, right, node + 2 * ( mid - left + 1 ), qleft, qright ) );
return maxi;
}
int main() {
FILE *fin, *fout;
int n, m, op, a, b, i;
fin = fopen( "arbint.in", "r" );
fout = fopen( "arbint.out", "w" );
fscanf( fin, "%d%d", &n, &m );
for( i = 1; i <= n; i++ )
fscanf( fin, "%d", &v[i] );
build( 1, n, 1 );
/* for( i = 1; i <= 2 * n; i++ )
printf( "%d ", aint[i] ); */
for( i = 0; i < m; i++ ) {
fscanf( fin, "%d%d%d", &op, &a, &b );
if( op == 0 )
fprintf( fout, "%d\n", query( 1, n, 1, a, b ) );
else
update( 1, n, 1, a, b );
}
fclose( fin );
fclose( fout );
return 0;
}