#include <stdio.h>
#include <math.h>
#define NMAXX 100000
int v[NMAXX], arbint[NMAXX * 2];
int vSize;
int max( int a, int b ) {
return a < b ? b : a;
}
int min( int a, int b ) {
return a < b ? a : b;
}
void build( int nod, int leftn, int rightn ) {
int leftSon, rightSon, mij;
mij = (leftn + rightn) / 2;
leftSon = nod + 1;
rightSon = nod + 2 * (mij - leftn + 1);
if ( leftn == rightn )
arbint[nod] = v[leftn - 1];
else {
build( leftSon, leftn, mij );
build( rightSon, mij + 1, rightn );
arbint[nod] = max( arbint[leftSon], arbint[rightSon] );
}
}
void update( int nod, int leftn, int rightn, int a, int b ) {
int leftSon, rightSon, mij;
if ( leftn == rightn ) {
arbint[nod] = b;
return;
}
mij = (leftn + rightn) / 2;
leftSon = nod + 1;
rightSon = nod + 2 * (mij - leftn + 1);
if ( a <= mij )
update( leftSon, leftn, mij, a, b );
else
update( rightSon, mij + 1, rightn, a, b );
arbint[nod] = max( arbint[leftSon], arbint[rightSon] );
}
int query( int nod, int leftn, int rightn, int leftq, int rightq ) {
int mij, leftSon, rightSon, res;
if ( leftq <= leftn && rightq >= rightn )
return arbint[nod];
mij = (leftn + rightn) / 2;
leftSon = nod + 1;
rightSon = nod + 2 * (mij - leftn + 1);
res = 0;
if ( leftq <= mij )
res = query( leftSon, leftn, mij, leftq, min( mij, rightq ) );
if ( mij < rightq )
res = max( res, query( rightSon, mij + 1, rightn, max( mij, leftq ), rightq ) );
return res;
}
int main() {
FILE *fin, *fout;
int i, q, op, a, b;
fin = fopen( "arbint.in", "r" );
fout = fopen( "arbint.out", "w" );
fscanf( fin, "%d%d", &vSize, &q );
for ( i = 0; i < vSize; i++ )
fscanf( fin, "%d", &v[i] );
build( 0, 1, vSize );
for ( i = 0; i < q; i++ ) {
fscanf( fin, "%d%d%d", &op, &a, &b );
if ( op == 1 )
update( 0, 1, vSize, a, b );
else
fprintf( fout, "%d\n", query( 0, 1, vSize, a, b ) );
}
fclose( fin );
fclose( fout );
return 0;
}