#include <bits/stdc++.h>
using namespace std;
class Treap
{
typedef struct _Node
{
int key;
int maxim;
int contor;
int priority;
_Node *l, *r;
_Node( const int _key, const int _priority, const int _nr_nodes, _Node *_st, _Node *_dr )
{
key = _key;
maxim = _key;
priority = _priority;
contor = _nr_nodes;
l = _st;
r = _dr;
}
void update()
{
this->maxim = this->key;
maxim = max( this->maxim, this->l->maxim );
maxim = max( this->maxim, this->r->maxim );
this->contor = 1;
this->contor += this->l->contor;
this->contor += this->r->contor;
}
} *Node;
void rotateRight( Node &T )
{
Node aux = T->l;
T->l = aux->r;
aux->r = T;
T->update();
aux->update();
T = aux;
}
void rotateLeft( Node &T )
{
Node aux = T->r;
T->r = aux->l;
aux->l = T;
T->update();
aux->update();
T = aux;
}
void balance( Node &T )
{
if ( T->l->priority > T->priority )
rotateRight( T );
if ( T->r->priority > T->priority )
rotateLeft( T );
T->update();
}
void insert( Node &T, int pos, int key, int p = rand() % INF )
{
if ( T == NIL )
{
T = new _Node( key, p, 1, NIL, NIL );
}
else
{
if ( pos <= T->l->contor + 1 )
insert( T->l, pos, key, p );
else
insert( T->r, pos - T->l->contor - 1, key, p );
balance( T );
}
if ( T != NIL )
T->update();
}
void erase( Node &T, int pos )
{
if ( T == NIL ) return;
if ( pos <= T->l->contor )
erase( T->l, pos );
else
if ( pos > T->l->contor + 1 )
erase( T->r, pos - T->l->contor - 1 );
else
{
if ( T->l == NIL && T->r == NIL )
{
delete T;
T = NIL;
}
else
{
if ( T->l->priority > T->r->priority )
{
rotateRight( T );
erase( T->r, pos - T->l->contor - 1 );
}
else
{
rotateLeft( T );
erase( T->l, pos );
}
}
}
if ( T != NIL )
T->update();
}
void split( Node &root, Node &L, Node &R, int pos )
{
insert( root, pos, 1, INF );
L = root->l;
R = root->r;
delete root;
root = NIL;
}
void merge( Node &root, Node &L, Node &R )
{
root = new _Node( 0, INF, 1, L, R );
root->update();
erase( root, root->l->contor + 1 );
}
Node root, NIL;
const static int INF = 1e9;
void afis(Node T)
{
if ( T == NIL ) return;
afis(T->l);
cout << T->key << " ";
afis(T->r);
}
public:
Treap()
{
srand( time(NULL) );
NIL = new _Node( -INF, 0, 0, NULL, NULL );
root = NIL;
}
void insert( int pos, int key )
{
insert( root, pos, key );
}
void erase( int pos )
{
erase( root, pos );
}
int query( int x, int y )
{
int sol = 0;
Node tmp, T1, T2, T3;
split( root, T1, T2, y + 1 );
split( T1, T3, tmp, x );
sol = tmp->maxim;
merge( T1, T3, tmp );
merge( root, T1, T2 );
return sol;
}
void update( int x, int value )
{
erase( root, x );
insert( root, x, value );
}
void afis()
{
afis(root);
}
};
int N, M, tip, a, b;
int main()
{
ifstream in("arbint.in");
ofstream out("arbint.out");
in >> N >> M;
Treap T;
for ( int i = 1; i <= N; ++i )
{
in >> a;
T.insert( i, a );
}
while ( M-- )
{
in >> tip >> a >> b;
if ( tip == 0 )
{
out << T.query( a, b ) << "\n";
}
else
{
T.update( a, b );
}
}
return 0;
}