#include <fstream>
#include <vector>
#define pb push_back
using namespace std;
using pii = pair<int,int>;
ifstream cin("heavypath.in");
ofstream cout("heavypath.out");
const int MAX = 1e5 + 1;
int n , q , aint[4*MAX] , nrd[MAX] , v[MAX] , wo[MAX] , hn , x , y , lift[18][MAX] , depth[MAX];
int poz[MAX] , ind;
vector <int> f(MAX);
vector <pii> in(MAX);
vector <int> st;
vector <int> g[MAX];
void update( int nod , int st , int dr ,int &poz , int &val){
if(st==dr){
aint[nod] = val;
}else{
int mij = (st+dr)/2;
if(poz <= mij) update(nod*2,st,mij,poz,val);
else update(nod*2+1,mij+1,dr,poz,val);
aint[nod] = max(aint[nod*2],aint[nod*2+1]);
}
}
int query( int nod , int st , int dr , int &qst , int &qdr){
if(qst<=st && dr<=qdr){
return aint[nod];
}else{
int val = -1;
int mij = (st+dr)/2;
if(qst <= mij) val = max(val,query(nod*2,st,mij,qst,qdr));
if(qdr > mij) val = max(val,query(nod*2+1,mij+1,dr,qst,qdr));
return val;
}
}
void dfs( int x , int p ){
depth[x] = depth[p]+1;
lift[0][x] = p;
for(int i = 1 ; i <= 17 ; i++){
lift[i][x] = lift[i-1][lift[i-1][x]];
}
for(auto it : g[x]){
if(it!=p){
dfs(it,x);
nrd[x]+=nrd[it];
}
}
nrd[x]++;
bool is = 0;
for(auto it : g[x]){
if(it!=p){
if(nrd[it]>=nrd[x]/2){
is = 1;
}
}
}
if(!is) st.push_back(x);
}
int lca( int a , int b ){
if(depth[a] > depth[b]){
swap(a,b);
}
int val = depth[b]-depth[a];
int i = 0;
while(val){
if(val%2) b = lift[i][b];
val = val/2;
i++;
}
if(a==b) return a;
int pw = 17;
while(pw>=0){
if(lift[pw][a]!=lift[pw][b]){
a = lift[pw][a];
b = lift[pw][b];
}
pw--;
}
return lift[0][a];
}
signed main(){
cin >> n >> q;
for(int i = 1 ; i <= n ; i++){
cin >> v[i];
}
for(int i = 1 ; i < n ; i++){
cin >> x >> y;
g[x].pb(y);
g[y].pb(x);
}
dfs(1,0);
for(auto it : st){
int k = 0;
++hn;
while(it>0 && nrd[it] >= nrd[lift[0][it]]/2){
wo[it] = hn;
f[hn] = it;
k++;
ind++;
update(1,1,n,ind,v[it]);
poz[it] = ind;
it = lift[0][it];
}
if(it!=0){
wo[it] = hn;
f[hn] = it;
k++;
ind++;
update(1,1,n,ind,v[it]);
poz[it] = ind;
}
in[hn] = make_pair(ind - k + 1,ind);
}
int op , a , b;
while(q--){
cin >> op >> a >> b;
if(!op){
update(1,1,n,poz[a],b);
}else{
int c = lca(a,b);
int mx = -1;
while(wo[a]!=wo[c]){
mx = max(mx,query(1,1,n,poz[a],poz[f[wo[a]]]));
a = lift[0][f[wo[a]]];
}
mx = max(mx,query(1,1,n,poz[a],poz[c]));
while(wo[b]!=wo[c]){
mx = max(mx,query(1,1,n,poz[b],poz[f[wo[b]]]));
b = lift[0][f[wo[b]]];
}
mx = max(mx,query(1,1,n,poz[b],poz[c]));
cout << mx << '\n';
}
}
return 0;
}