#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int NMAX = 100003;
vector <int> A[NMAX], C[NMAX];
int V[NMAX], n[NMAX], t[NMAX], cl[NMAX], sa[NMAX], aint[NMAX << 2], d[NMAX], L, k, _l, _r, rv;
bool viz[NMAX];
void DFS (const int nod) {
viz[nod] = 1;
int mn;
bool f = 1;
for (vector <int> :: iterator i = A[nod].begin (); i != A[nod].end (); ++i) {
if (viz[*i])
continue;
n[*i] = n[nod] + 1;
t[*i] = nod;
DFS (*i);
if (f)
mn = *i,
f = 0;
else
if (sa[*i] > sa[mn])
mn = *i;
sa[nod] += sa[*i];
}
if (f) {
++sa[nod];
cl[nod] = ++L;
C[L].push_back (nod);
return;
}
C[cl[mn]].push_back (nod);
cl[nod] = cl[mn];
}
void AINT_build (const int l, const int r, const int nod) {
if (l == r) {
aint[nod + d[k]] = V[C[k][l]];
return;
}
int m = l + r >> 1;
AINT_build (l, m, nod << 1);
AINT_build (m + 1, r, (nod << 1) + 1);
aint[nod + d[k]] = max (aint[(nod << 1) + d[k]], aint[(nod << 1) + 1 + d[k]]);
}
void build () {
DFS (1);
int i;
for (k = 1; k <= L; ++k) {
i = C[k].size ();
reverse (C[k].begin (), C[k].end ());
d[k + 1] = d[k] + (i << 1) - 1;
AINT_build (0, i - 1, 1);
}
}
void AINT_query (const int l, const int r, const int nod) {
if (_r < l || _l > r)
return;
if (_l <= l && _r >= r) {
if (aint[nod + d[k]] > rv)
rv = aint[nod + d[k]];
return;
}
int m = l + r >> 1;
AINT_query (l, m, nod << 1);
AINT_query (m + 1, r, (nod << 1) + 1);
}
void AINT_update (const int l, const int r, int const nod) {
if (l == r) {
aint[nod + d[k]] = _r;
return;
}
int m = l + r >> 1;
if (_l <= m)
AINT_update (l, m, nod << 1);
else
AINT_update (m + 1, r, (nod << 1) + 1);
aint[nod + d[k]] = max (aint[(nod << 1) + d[k]], aint[(nod << 1) + 1 + d[k]]);
}
int main () {
freopen ("heavypath.in", "r", stdin);
freopen ("heavypath.out", "w", stdout);
int i, N, M, a, b, mt, w;
scanf ("%d%d", &N, &M);
for (i = 1; i <= N; ++i)
scanf ("%d", &V[i]);
for (i = 1; i < N; ++i)
scanf ("%d%d", &a, &b),
A[a].push_back (b),
A[b].push_back (a);
n[1] = 1;
build ();
while (M--) {
scanf ("%d%d%d", &w, &a, &b);
if (w) {
mt = 0;
while (cl[a] != cl[b]) {
if (n[C[cl[a]][0]] < n[C[cl[b]][0]])
swap (a, b);
k = cl[a];
rv = 0;
_l = 0;
_r = n[a] - n[C[cl[a]][0]];
AINT_query (0, C[k].size () - 1, 1);
a = t[C[cl[a]][0]];
if (rv > mt)
mt = rv;
}
if (n[a] > n[b])
swap (a, b);
k = cl[a];
rv = 0;
_l = n[a] - n[C[cl[a]][0]];
_r = n[b] - n[C[cl[b]][0]];
AINT_query (0, C[k].size () - 1, 1);
if (rv > mt)
mt = rv;
printf ("%d\n", mt);
continue;
}
k = cl[a];
_l = n[a] - n[C[cl[a]][0]];
_r = b;
AINT_update (0, C[k].size () - 1, 1);
}
}