#include<stdio.h>
#include<vector>
#include<algorithm>
#define Nmax 100010
#define st nod<<1
#define dr 1 + (nod<<1)
#define mij ((s+d)>>1)
using namespace std ;
int T[Nmax],Lant[Nmax],Tata[Nmax],viz[Nmax],heavy[Nmax],Lungime[Nmax],key[Nmax],poz_in_lant[Nmax];
int a,b,x,y,new_val,ret_val,N,M,i,lanturi,op,poz;
vector<int> Arb[Nmax],AINT[Nmax];
int cmp ( int a, int b )
{
return heavy[a] > heavy[b] ;
}
void update ( int L, int nod, int s, int d )
{
if ( s == d )
{
AINT[L][nod] = new_val ;
return ;
}
if ( poz <= mij ) update( L , st, s, mij ) ;
else update( L , dr, mij+1, d ) ;
AINT[L][nod] = AINT[L][st] ;
if( key[ AINT[L][st] ] < key[ AINT[L][dr] ] )
AINT[L][nod] = AINT[L][dr] ;
}
void query ( int L, int nod, int s, int d )
{
if ( a <= s && d <= b )
{
if ( key[AINT[L][nod]] > ret_val )
ret_val = key[AINT[L][nod]] ;
return ;
}
if ( a <= mij ) query ( L, st, s, mij ) ;
if ( mij < b ) query ( L, dr, mij+1, d ) ;
}
void dfs ( int nod )
{
int N = Arb[nod].size(), fiu ;
viz[nod] = 1 ;
for( int i = 0 ; i < N ; i++ )
{
fiu = Arb[nod][i] ;
if( !viz[fiu] )
{ Tata[fiu] = nod , dfs( fiu ) ;
heavy[nod] += heavy[ fiu ] ;
}
}
heavy[nod]++;
sort(Arb[nod].begin(),Arb[nod].end(),cmp);
}
void decomp ( int nod, int poz )
{
int N = Arb[nod].size(), fiu ;
if( !T[lanturi] ) T[lanturi] = nod ;
Lant[nod] = lanturi ;
poz_in_lant[nod] = poz ;
Lungime[lanturi] = poz ;
// taraneala
AINT[lanturi].push_back(0) ;
AINT[lanturi].push_back(0) ;
AINT[lanturi].push_back(0) ;
AINT[lanturi].push_back(0) ;
int primul = 1 ;
for ( int i = 0 ; i < N ; i++ )
{
fiu = Arb[nod][i] ;
if( nod != Tata[fiu] ) continue ;
if ( !primul )
{
lanturi++;
decomp( fiu , 1 ) ;
T[Lant[fiu]] = nod ;
}
else
primul = 0, decomp( fiu , poz + 1 ) ;
}
}
int get_max ( int x, int y )
{
int r = 0 ;
while ( Lant[x] != Lant[y] )
{
ret_val = 0 ; a = 1 ;
if( Lant[x] < Lant[y] )
{
b = poz_in_lant[y];
query(Lant[y],1,1,Lungime[Lant[y]]);
if( ret_val > r )
r = ret_val ;
y = T[Lant[y]];
}
else
{
b = poz_in_lant[x];
query(Lant[x],1,1,Lungime[Lant[x]]);
if( ret_val > r )
r = ret_val ;
x = T[Lant[x]];
}
}
a = poz_in_lant[x];
b = poz_in_lant[y];
if( a > b ) a = a+b - (b=a);
ret_val = 0 ;
query(Lant[x],1,1,Lungime[Lant[x]]);
if( ret_val > r ) r = ret_val ;
return r ;
}
int main()
{
freopen("heavypath.in","r",stdin);
freopen("heavypath.out","w",stdout);
scanf("%d %d",&N,&M);
for( i = 1 ; i <= N ; i++ )
scanf("%d",&key[i]);
for( i = 1 ; i < N ; i++ )
{
scanf("%d %d",&a,&b);
Arb[a].push_back(b);
Arb[b].push_back(a);
}
Tata[1] = 1 ;
dfs(1);
lanturi = 1 ;
decomp(1,1);
for( i = 1 ; i <= N ; i++ )
{
new_val = i ;
poz = poz_in_lant[i];
update(Lant[i],1,1,Lungime[Lant[i]]) ;
}
for( i = 1 ; i <= M ; i++ )
{
scanf("%d",&op);
if( op )
{
scanf("%d %d",&x,&y);
printf("%d\n",get_max(x,y));
}
else
{
scanf("%d %d",&x,&new_val);
key[x] = new_val;
new_val = x ;
poz = poz_in_lant[x];
update(Lant[x],1,1,Lungime[Lant[x]]);
}
}
return 0 ;
}