#include <fstream>
#include <cstring>
#define NN 100009
using namespace std;
ofstream out("arbint.out");
int arb[ 4 * NN ] , n , m , maxx;
int V[ NN ];
void read();
void build( int nod , int left , int right );
void update( int nod , int left , int right , int poz , int value );
void query( int nod , int left , int right , int start , int finish );
int main()
{
read();
return 0;
}
void read()
{
ifstream in("arbint.in");
in >> n >> m;
for( int i=1 ; i<=n ; i++)
{
int x;
in >> x;
V[i] = x;
}
build( 1 , 1 , n);
for( int i=1 ; i<=m ; i++)
{
int tip;
in >> tip;
if( tip == 0 )
{
int st , dr;
in >> st >> dr;
maxx = -1;
query( 1 , 1 , n , st , dr );
out << maxx << '\n';
}
else
{
int poz , val;
in >> poz >> val;
update(1 , 1 , n , poz , val );
}
}
}
void build( int nod , int left , int right )
{
if( left == right )
{
arb[nod] = V[left];
return;
}
int mid = ( left + right ) >> 1;
build( nod << 1 , left , mid );
build( ( nod << 1 ) + 1 , mid + 1 , right );
arb[nod] = max( arb[ nod << 1 ] , arb[ ( nod << 1 ) + 1 ]);
}
void update(int nod,int left,int right,int position,int value)
{
if ( left == right )
{
arb[nod] = value;
return;
}
int mid = (left + right ) >> 1;
if ( position <= mid )
update( nod << 1 ,left,mid,position,value);
else
update( ( nod << 1 ) + 1 , mid+1,right,position,value);
arb[nod] = max ( arb[ nod << 1] ,arb[ ( nod << 1 ) + 1] );
}
void query( int nod , int left , int right , int start , int finish )
{
if( start <=left && finish >=right )
{
maxx = max ( arb[nod] , maxx );
return;
}
int mid = ( left + right ) >> 1;
if( start <= mid )
query(( nod << 1 ) , left , mid , start , finish );
if( mid < finish )
query( ( nod << 1 ) + 1 , mid + 1, right , start , finish );
}