#include <bits/stdc++.h>
#define maxn 100000
#define maxl2 17
#define fi first
#define se second
using namespace std;
struct nod
{
int st, dr, _M;
};
nod aint[maxn*maxl2+5];
int v[maxn+5];
int ans;
void build ( int i, pair<int,int> itv )
{
aint[i].st = itv.fi;
aint[i].dr = itv.se;
aint[i]._M = 0;
if ( itv.fi == itv.se )
aint[i]._M = v[itv.fi];
else if ( itv.fi < itv.se )
{
int mid = (itv.fi+itv.se) / 2;
build ( i * 2, {itv.fi,mid} );
build ( i * 2 + 1, {mid+1,itv.se} );
aint[i]._M = max ( aint[i*2]._M, aint[i*2+1]._M );
}
}
void update ( int poz, int i, pair<int,int> itv )
{
if ( poz < itv.fi || poz > itv.se ) return;
if ( itv.fi == itv.se )
aint[i]._M = v[poz];
int mid = (itv.fi+itv.se) / 2;
if ( itv.fi < itv.se )
{
update ( poz, i * 2, {itv.fi, mid} );
update ( poz, i * 2 + 1, {mid+1, itv.se} );
}
aint[i]._M = max ( aint[i*2]._M, aint[i*2+1]._M );
}
void query ( int i, pair<int,int> cur, pair<int,int> itv )
{
if ( cur.fi > cur.se || cur.se < itv.fi || cur.fi > itv.se ) return;
if ( cur.fi >= itv.fi && cur.se <= itv.se )
{
ans = max ( ans, aint[i]._M );
return;
}
if ( cur.fi < cur.se )
{
int mid = (cur.fi+cur.se) / 2;
query ( i * 2, {cur.fi,mid}, itv );
query ( i * 2 + 1, {mid+1,cur.se}, itv );
}
}
int main ()
{
ifstream fin ( "arbint.in" );
ofstream fout ( "arbint.out" );
int n, t;
fin >> n >> t;
int i;
for ( i = 1; i <= n; i++ )
fin >> v[i];
build ( 1, {1,n} );
int id, a, b;
while (t--)
{
fin >> id >> a >> b;
if ( id == 0 )
{
ans = 0;
query ( 1, {1,n}, {a,b} );
fout << ans << '\n';
}
else
{
v[a-1] = b;
update ( a, 1, {1,n} );
}
}
fin.close ();
fout.close ();
return 0;
}