#include <iostream>
#include <fstream>
#define NMax 100005
#define INF 1 << 30
using namespace std;
ifstream f ("arbint.in" );
ofstream g ("arbint.out");
int a[NMax], segmTree[2 * NMax];
void recalc(int node){
segmTree[node] = max( segmTree[2*node+1], segmTree[2*node+2] );
}
void build(int node, int left, int right){
if(left == right){
segmTree[node] = a[left];
}
else{
int mid = (left + right) / 2;
build(2 * node + 1, left, mid);
build(2 * node + 2, mid + 1, right);
recalc(node);
}
}
void update(int node, int left, int right, int x, int y){
if(left == right){
segmTree[node] = y;
}
else{
int mid = (left + right) / 2;
if(x <= mid){
update(2 * node + 1, left, mid, x, y);
}
else{
update(2 * node + 2, mid + 1, right, x, y);
}
recalc(node);
}
}
int query(int node, int left, int right, int x, int y){
if( x <= left && right <= y ){
return segmTree[node];
}
else{
int ans = -INF;
int mid = (left + right) / 2;
if( x <= mid ){
ans = max(ans, query(2 * node + 1, left, mid, x, y));
}
if( y >= mid + 1){
ans = max(ans, query(2 * node + 2, mid + 1, right, x, y));
}
return ans;
}
}
int main()
{
int n, m, tip, x, y;
f >> n >> m;
for(int i = 1; i <= n; ++i) f >> a[i];
build(0, 1, n);
while(m--){
f >> tip >> x >> y;
if(tip == 0){
g << query(0, 1, n, x, y) << '\n';
}
else{
update(0, 1, n, x, y);
}
}
}