#include <iostream>
#include<fstream>
using namespace std;
ifstream in("arbint.in");
ofstream out("arbint.out");
int value_count,query_count;
int values[100000];
int node_values[262144];
void read_values()
{
in>>value_count>>query_count;
for(int i=0; i<value_count; i++)
in>>values[i];
}
int create_tree(int left,int right,int index)
{
int middle=(left+right)/2;
if(left==right)
{
node_values[index]=values[left];
}
else
{
int here=max(create_tree(left,middle,2*index),create_tree(middle+1,right,2*index+1));
node_values[index]=here;
}
return node_values[index];
}
int get_max_in_interval(int a,int b,int left,int right,int index)
{
if(left>=a && right<=b)
{
return node_values[index];
}
int middle=(left+right)/2;
int to_return=-1;
if(a<=middle)
{
to_return=max(to_return,get_max_in_interval(a,b,left,middle,index*2));
}
if(b>middle)
{
to_return=max(to_return,get_max_in_interval(a,b,middle+1,right,index*2+1));
}
return to_return;
}
void set_value(int left,int right,int index,int value,int here)
{
if(left>=right)
{
node_values[here]=value;
}
else
{
int middle=(left+right)/2;
if(index<=middle)
{
set_value(left,middle,index,value,here*2);
}
else
{
set_value(middle+1,right,index,value,here*2+1);
}
node_values[here]=max(node_values[here*2+1],node_values[here*2]);
}
}
int get_max(int a,int b)
{
return get_max_in_interval(a,b,0,value_count-1,1);
}
void create_interval_tree()
{
create_tree(0,value_count-1,1);
}
void set_value_at(int index,int value)
{
set_value(0,value_count-1,index,value,1);
}
void solve_queries()
{
int query,a,b,to_return;
for(int i=0; i<query_count; i++)
{
in>>query>>a>>b;
if(query==0)
{
to_return=get_max(a-1,b-1);
out<<to_return<<'\n';
}
else
{
set_value_at(a-1,b);
}
}
}
int main()
{
read_values();
create_interval_tree();
solve_queries();
return 0;
}