#include <bits/stdc++.h>
using namespace std;
const int nmax = 100009;
const int lgmax = 19;
int dad[lgmax][nmax];
int st[4 * nmax];
int add[nmax] , whr[nmax] , label[nmax] , lvl[nmax];
int w[nmax] , len[nmax] , roof[nmax] , x[nmax];
int answer , n , q , a , b , v , t , cnt , i , j;
vector < int > g[nmax];
void dfs(int act , int up)
{
dad[0][act] = up;
lvl[act] = lvl[up] + 1;
w[act] = 1;
for (int i = 0 ; i < g[act].size() ; ++i)
if (g[act][i] == up)
{
g[act].erase(g[act].begin() + i);
break;
}
for (int i = 0 ; i < g[act].size() ; ++i)
{
dfs(g[act][i] , act);
w[act] += w[g[act][i]];
}
}
void getChains(int act)
{
label[act] = cnt;
whr[act] = ++len[cnt];
int p = 0;
for (int i = 0 ; i < g[act].size() ; ++i)
if (w[g[act][i]] > w[p]) p = g[act][i];
if (p) getChains(p);
else cnt++;
for (int i = 0 ; i < g[act].size() ; ++i)
if (g[act][i] - p)
{
roof[cnt] = act;
getChains(g[act][i]);
}
}
int kanc(int x , int p)
{
for (int i = 0 ; (1 << i) <= p ; ++i)
if ((1 << i) & p) x = dad[i][x];
return x;
}
int lca(int a , int b)
{
if (lvl[a] < lvl[b]) swap(a , b);
a = kanc(a , lvl[a] - lvl[b]);
if (a == b) return a;
for (int i = 0 ; (1 << i) <= lvl[a] ; ++i)
if (dad[i][a] != dad[i][b]) a = dad[i][a] , b = dad[i][b];
return dad[0][a];
}
void update(int x , int l , int r , int p , int v , int add)
{
if (l == r)
{
st[x + add] = v;
return;
}
int c = (l + r) / 2;
if (p <= c) update(2 * x , l , c , p , v , add);
else update(2 * x + 1 , c + 1 , r , p , v , add);
st[x + add] = max(st[2 * x + add] , st[2 * x + 1 + add]);
}
void query(int x , int l , int r , int lq , int rq , int add)
{
if (lq <= l && r <= rq)
{
answer = max(answer , st[x + add]);
return;
}
int c = (l + r) / 2;
if (lq <= c) query(2 * x , l , c , lq , rq , add);
if (c < rq) query(2 * x + 1 , c + 1 , r , lq , rq , add);
}
void walk(int x , int up)
{
if (label[x] == label[up])
{
query(1 , 1 , len[label[x]] , whr[up] , whr[x] , add[label[x]]);
return ;
}
query(1 , 1 , len[label[x]] , 1 , whr[x] , add[label[x]]);
walk(roof[label[x]] , up);
}
int main()
{
freopen("heavypath.in" , "r" , stdin);
freopen("heavypath.out" , "w" , stdout);
scanf("%d" , &n);
scanf("%d" , &q);
for (i = 1 ; i <= n ; ++i)
scanf("%d" , &x[i]);
for (i = 2 ; i <= n ; ++i)
{
scanf("%d" , &a);
scanf("%d" , &b);
g[a].push_back(b);
g[b].push_back(a);
}
dfs(1 , 0);
for (i = 1 ; (1 << i) <= n ; ++i)
for (j = 1 ; j <= n ; ++j)
dad[i][j] = dad[i - 1][dad[i - 1][j]];
cnt = 1;
getChains(1);
cnt--;
for (i = 2 ; i <= cnt ; ++i)
add[i] = add[i - 1] + 4 * len[i - 1];
for (i = 1 ; i <= n ; ++i)
update(1 , 1 , len[label[i]] , whr[i] , x[i] , add[label[i]]);
for (i = 1 ; i <= q ; ++i)
{
scanf("%d" , &t);
scanf("%d" , &a);
scanf("%d" , &b);
if (t == 0)
update(1 , 1 , len[label[a]] , whr[a] , b , add[label[a]]);
else
{
v = lca(a , b);
answer = 0;
walk(a , v);
walk(b , v);
printf("%d\n" , answer);
}
}
return 0;
}