#include <bits/stdc++.h>
#define lim 100005
#define mx 10000000000
using namespace std;
ifstream in("arbint.in");
ofstream out("arbint.out");
int n, m, v[lim], q[lim*5];
void make_tree(int start, int stop, int position)
{
if(start==stop)
{
q[position]=v[start];
return;
}
int mid=(start+stop)/2;
make_tree(start, mid, 2*position);
make_tree(mid+1, stop, 2*position+1);
q[position]=max(q[2*position],q[2*position+1]);
}
void read()
{
in>>n>>m;
for(int i=1; i<=n; ++i)
{
in>>v[i];
}
}
int get_max_tree(int start, int stop, int interval_start, int interval_stop, int position)
{
if(interval_start<=start && interval_stop>=stop)
{
return q[position];
}
else if(interval_stop<start || interval_start>stop)
{
return -1;
}
int mid=(start+stop)/2;
return max(get_max_tree(start, mid, interval_start, interval_stop, 2*position), get_max_tree(mid+1, stop, interval_start, interval_stop, 2*position+1));
}
void update_tree(int start, int stop, int nod, int position)
{
if(start==stop)
{
q[position]=v[nod];
return;
}
int mid=(start+stop)/2;
if(nod<=mid)
{
update_tree(start, mid, nod, 2*position);
}
else
{
update_tree(mid+1, stop, nod, 2*position+1);
}
q[position]=max(q[2*position], q[2*position+1]);
}
void solve()
{
int operation, sta, fin;
make_tree(1, n, 1);
for(int i=1; i<=m; ++i)
{
in>>operation>>sta>>fin;
if(operation==0)
{
out<<get_max_tree(1, n, sta, fin, 1)<<'\n';
}
else if(operation==1)
{
v[sta]=fin;
update_tree(1, n, sta, 1);
}
}
}
int main()
{
read();
make_tree(1, n, 1);
solve();
return 0;
}