#include <fstream>
using namespace std;
int values[100001],n,m,i;
int op, x1, x2;
struct node
{
int a,b;
int value;
node* st;
node* dr;
};
int maxim(int value1, int value2)
{
if( value1 > value2 )
return value1;
return value2;
}
void populateTree( node* aNode, int A, int B );
void updateValue( node* aNode, int aPosition, int aValue );
int interogateValue( node* aNode, int aLeft, int aRight );
int main()
{
ifstream f("arbint.in");
ofstream g("arbint.out");
f >> n >> m;
for( i = 1; i <= n; i++)
f >> values[i];
node* root = new node;
populateTree(root, 1, n);
for( i = 0; i < m; i++ )
{
f >> op >> x1 >> x2;
switch (op)
{
case 0:
g << interogateValue( root, x1, x2 ) << "\n";
break;
case 1:
updateValue( root, x1, x2 );
break;
default:
break;
}
}
f.close();
g.close();
return 0;
}
void populateTree(node* aNode, int A, int B)
{
aNode->a = A;
aNode->b = B;
if( A == B )
{
aNode->value = values[A];
aNode->st = NULL;
aNode->dr = NULL;
}
else
{
aNode->st = new node;
populateTree( aNode->st, A, (A + B) / 2 );
aNode->dr = new node;
populateTree( aNode->dr, (A + B) / 2 + 1, B );
aNode->value = maxim( aNode->st->value, aNode->dr->value );
}
}
void updateValue( node* aNode, int aPosition, int aValue )
{
if( aNode->a == aNode->b && aNode->a == aPosition )
{
aNode->value = aValue;
}
else if( aPosition >= aNode->st->a && aPosition <= aNode->st->b )
{
updateValue( aNode->st, aPosition, aValue );
aNode->value = maxim( aNode->st->value, aNode->dr->value );
}
else
{
updateValue( aNode->dr, aPosition, aValue );
aNode->value = maxim( aNode->st->value, aNode->dr->value );
}
}
int interogateValue( node* aNode, int aLeft, int aRight )
{
//1. intervalele sunt exacte
//2. intervalele sunt incluse in unul din subintervale
//3. intervalul este compus din din cele 2 subintervale
if( aNode->a == aLeft && aNode->b == aRight )
{
return aNode->value;
}
else if( aRight <= aNode->st->b )
{
return interogateValue( aNode->st, aLeft, aRight );
}
else if( aLeft >= aNode->dr->a )
{
return interogateValue( aNode->dr, aLeft, aRight );
}
else
{
return maxim( interogateValue( aNode->st, aLeft, aNode->st->b ), interogateValue( aNode->dr, aNode->dr->a, aRight) );
}
}