#include <iostream>
#include <fstream>
#include <vector>
using namespace std ;
# define pb push_back
# define ll long long
ifstream f("arbint.in") ;
ofstream g("arbint.out") ;
const int MAX = 1e5 + 14 ;
class SegmentTree
{
public :
vector < long long > Sum ;
vector < long long > Tree ;
SegmentTree ( )
{
Sum.resize ( MAX << 2 ) ;
Tree.resize ( MAX << 2 ) ;
}
void Reset ()
{
fill ( Sum.begin() , Sum.end() , 0 ) ;
fill ( Tree.begin() , Tree.end() , 0 ) ;
}
void ElementUpdate ( int nod , int st , int dr , int pos , int val )
{
if ( st==dr )
{
Tree [ nod ] = val;
Sum [ nod ] = val;
return ;
}
int mijl = ( st + dr ) >> 1 ;
if ( pos <= mijl )
ElementUpdate( nod << 1 , st , mijl , pos , val ) ;
else
ElementUpdate( nod << 1 | 1 , mijl + 1 , dr , pos ,val) ;
Tree [ nod ] = max( Tree [ nod << 1 ] , Tree [ nod << 1 | 1 ] ) ;
Sum [ nod ] = Sum [ nod << 1 ] + Sum [ nod << 1 | 1 ] ;
}
ll RangeQuery ( int nod , int st , int dr , int a , int b )
{
if ( st >= a && dr <= b )
return Tree [ nod ] ;
int mijl = ( st + dr ) >> 1 ;
ll LeftMax = 0 ;
ll RightMax = 0 ;
if ( mijl >=a ) LeftMax = RangeQuery( nod << 1 , st , mijl , a, b ) ;
if ( mijl < b) RightMax = RangeQuery( nod << 1 | 1 , mijl + 1 , dr , a , b ) ;
Tree [ nod ] = max ( Tree [ nod << 1 ] , Tree [ nod << 1 | 1 ] ) ;
Sum [ nod ] = Sum [ nod << 1 ] + Sum [ nod << 1 | 1 ] ;
return max ( LeftMax , RightMax ) ;
}
};
int main ()
{
int n , m ;
f >> n >> m ;
SegmentTree Arbore ;
Arbore.Reset () ;
for ( int i = 1 ; i <= n ; ++i ) {
int Value ;
f >> Value ;
Arbore.ElementUpdate ( 1 , 1 , n , i , Value ) ;
}
while ( m -- )
{
int type;
f >> type ;
if ( !type )
{
int left , right ;
f >> left >> right ;
g << Arbore.RangeQuery ( 1 , 1 , n , left , right ) << "\n" ;
}
else
{
int position , value ;
f >> position >> value ;
Arbore.ElementUpdate( 1 , 1 , n , position , value ) ;
}
}
return 0;}