#include <cstdio>
#include <bits/stdc++.h>
using namespace std;
#define N 100005
int n , m ;
int v[N] , niv[N] , use[N] , w[N] , nl , l[N] , ldim[N] , ltata[N] , lniv[N] ;
int lpoz[N] , aint[4*N] , sol ;
vector<int> g[N],p[N];
int a,b,c;
//////
/////
////
///
//
void dfs(int nod){
use[nod] = 1;
w[nod] = 1;
int hn = 100004 , fr = -1;
for(vector<int> :: iterator it = g[nod].begin() ; it != g[nod].end() ; ++it){
if( use[*it] ) continue;
fr = 0;
niv[*it] = niv[nod] + 1;
dfs(*it);
w[nod] += w[*it];
if( w[ hn ] < w[*it] )
hn = *it;
}
if( fr ){
l[nod] = ++nl;
ldim[ nl ] = 1;
p[nl].push_back(nod);
return ;
}
l[nod] = l[hn];
++ldim[ l[nod] ];
p[l[nod]].push_back(nod);
for(vector<int> :: iterator it = g[nod].begin() ; it != g[nod].end() ; ++it){
if( *it == hn || niv[*it] < niv[nod] ) continue;
ltata[ l[*it] ] = nod;
lniv[ l[*it] ] = niv[nod];
}
}
void build(int x,int l , int r , int dec,int lant){
if( l == r ){
aint[ x + dec ] = v[p[lant][l -1]];
return ;
}
int m = (l+r)>>1;
build( x*2 , l , m , dec , lant );
build( x*2+1, m+1 , r , dec , lant );
aint[dec + x] = max( aint[ dec + x*2 ] , aint[dec + x*2+1] );
}
void update(int x,int l,int r,int poz,int val,int dec){
if( l == r ){
aint[ x + dec ] = val;
return ;
}
int m = (l+r)>>1;
if( poz <= m )
update( x*2 , l , m , poz , val , dec );
else
update( x*2+1 , m+1 , r , poz , val , dec );
aint[dec + x] = max( aint[ dec + x*2 ] , aint[dec + x*2+1] );
}
int query(int x,int l,int r,int ql , int qr,int dec){
if( ql <= l && r <= qr )
return aint[dec + x];
int m = (l+r)>>1;
int rez = -1 ;
if( ql <= m )
rez = max( rez , query(x*2 , l , m , ql , qr , dec) );
if( m < qr)
rez = max( rez , query(x*2+1, m+1 , r , ql , qr , dec) );
return rez;
}
int main()
{
freopen("heavypath.in" , "r" , stdin);
freopen("heavypath.out", "w" , stdout);
scanf("%d %d",&n,&m);
for(int i =1; i<=n;++i){
scanf("%d",&v[i]);
}
for(int i=1; i< n;++i){
scanf("%d %d",&a,&b);
g[a] . push_back(b);
g[b] . push_back(a);
}
niv[1] = 1;
w[100004] = -1;
dfs(1);
for(int i=1;i <= nl; ++i){
reverse( p[i].begin() , p[i].end() );
lpoz[i] = lpoz[i-1] + ldim[i-1]*4;
build( 1 , 1 , ldim[i] , lpoz[i] , i );
}
for(int i=1;i<=m;++i){
scanf("%d %d %d",&c,&a,&b);
if( c == 0 ){
update( 1 , 1 , ldim[l[a]] , niv[a] - lniv[ l[a] ] , b , lpoz[l[a]] );
}else{
sol = 0;
while( true ){
if( l[a] == l[b] ){
if( niv[a] > niv[b] ) swap(a,b);
sol = max( sol , query(1 , 1 , ldim[l[a]] , niv[a] - lniv[l[a]], niv[b] - lniv[l[a]], lpoz[l[a]] ) );
break;
}
if( lniv[l[a]] < lniv[l[b]] ) swap(a,b);
sol = max(sol , query(1 , 1 , ldim[l[a]] , 1 , niv[a] - lniv[l[a]] , lpoz[l[a]] ));
a = ltata[l[a]];
}
printf("%d\n",sol);
}
}
return 0;
}