#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
ifstream fin( "arbint.in" );
ofstream fout( "arbint.out" );
struct Node {
int value;
Node* leftChild;
Node* rightChild;
Node() {
value = -INF;
leftChild = rightChild = NULL;
}
};
void f( Node* node ) {
int maxLeft = -INF, maxRight = -INF;
if( node->leftChild != NULL )
maxLeft = node->leftChild->value;
if( node->rightChild != NULL )
maxRight = node->rightChild->value;
node->value = max( maxLeft, maxRight );
}
void update( Node* node, int left, int right, int pos, int val ) {
if( left == right )
node->value = val;
else {
int mid = left + ( right - left ) / 2;
if( pos <= mid ) {
if( node->leftChild == NULL )
node->leftChild = new Node;
update( node->leftChild, left, mid, pos, val );
}
else {
if( node->rightChild == NULL )
node->rightChild = new Node;
update( node->rightChild, mid + 1, right, pos, val );
}
f( node );
}
}
int query( Node* node, int left, int right, int qleft, int qright ) {
if( qleft <= left && qright >= right )
return node->value;
if( qleft > right || qright < left )
return 0;
int mid = left + ( right - left ) / 2;
int max1 = -INF, max2 = -INF;
if( qleft <= mid ) {
if( node->leftChild == NULL )
node->leftChild = new Node;
max1 = query( node->leftChild, left, mid, qleft, qright );
}
if( qright > mid ) {
if( node->rightChild == NULL )
node->rightChild = new Node;
max2 = query( node->rightChild, mid + 1, right, qleft, qright );
}
return max( max1, max2 );
}
int main() {
int n, q, i, val, l, r, poz, op;
Node* root = new Node;
fin >> n >> q;
for( i = 1; i <= n; i++ ) {
fin >> val;
update( root, 1, n, i, val );
}
for( i = 0; i < q; i++ ) {
fin >> op;
if( op == 0 ) {
fin >> l >> r;
fout << query( root, 1, n, l, r ) << "\n";
}
else {
fin >> poz >> val;
update( root, 1, n, poz, val );
}
}
return 0;
}