#include <fstream>
#include <algorithm>
#include <vector>
#include <cstring>
#define oo 0x3f3f3f3f
#define NMAX 100005
#define get_max(a,b) ((a)>(b)?(a):(b))
#define get_min(a,b) ((a)<(b)?(a):(b))
using namespace std;
int Answer;
ifstream in ( "arbint.in" );
ofstream out ( "arbint.out" );
class AINT
{
private:
int V[4*NMAX] ;
public:
void Update ( int Node , int Left , int Right , int Pos , int Value )
{
if ( Left == Right )
{
this->V[Node] = Value ;
return ;
}
int Middle = ( Left + Right ) >> 1;
if ( Middle < Pos ) Update( 2*Node +1 , Middle +1 , Right , Pos , Value );
else Update ( 2* Node , Left , Middle , Pos , Value );
this->V[Node] = get_max ( this->V[2*Node+1] , this->V[2*Node] );
}
void Query ( int Node , int Left , int Right , int SearchLeft , int SearchRight )
{
if ( SearchLeft <= Left and Right <= SearchRight )
{
Answer = get_max ( Answer , this->V[Node] );
return ;
}
int Middle = ( Left + Right ) >> 1;
if ( SearchLeft <= Middle )
Query ( 2*Node , Left , Middle , SearchLeft , SearchRight );
if ( Middle < SearchRight )
Query ( 2*Node + 1 , Middle + 1 , Right , SearchLeft , SearchRight ) ;
}
};
int N , M ;
AINT A;
int main ( void )
{
int i , j , type , x , y;
in >> N >> M ;
for ( i = 1 ; i <= N ; ++i )
in >> x , A.Update ( 1 , 1 , N , i , x);
for ( i = 1 ; i <= M ; ++i )
{
in >> type >> x >> y ;
( type == 1 ? A.Update ( 1 , 1 , N , x , y ) : A.Query ( 1 , 1 , N , x , y ) );
if ( not type == 1 )out << Answer << "\n";
Answer = -oo;
}
in.close();
out.close();
return 0;
}