#include <bits/stdc++.h>
using namespace std;
ifstream f("heavypath.in");
ofstream g("heavypath.out");
const int NMAX = 100005, MMAX = 100005, INF = 0x3f3f3f3f;
int n, m, value[NMAX], father[NMAX], niv[NMAX], w[NMAX];
int AI[4 * NMAX];
int lTata[NMAX], lNiv[NMAX], lDim[NMAX], lPoz[NMAX], nL, l[NMAX];
typedef vector<int>::iterator Iterator;
vector<int> a[NMAX], P[NMAX];
inline int max(const int & a, const int & b)
{
if (a < b) return b;
return a;
}
inline void DF(int nod)
{
int hN = -1, frunza = 1;
for (Iterator it = a[nod].begin(); it != a[nod].end(); it++)
{
if (niv[*it] != 0)
continue;
frunza = 0;
niv[*it] = niv[nod] + 1;
DF(*it);
w[nod] += w[*it];
if(hN == -1)
hN = *it;
else if (w[hN] < w[*it])
hN = *it;
}
if (frunza)
{
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 (Iterator it = a[nod].begin(); it != a[nod].end(); ++it)
{
if (*it == hN || niv[*it] < niv[nod])
continue;
lTata[l[*it]] = nod;
lNiv[l[*it]] = niv[nod];
}
}
void build(int nod, int left, int right, int decalaj, int lant)
{
if (left == right)
{
AI[nod + decalaj] = value[P[lant][left - 1]];
return;
}
int mij = (left + right) / 2;
build(2 * nod, left, mij, decalaj, lant);
build(2 * nod + 1, mij + 1, right, decalaj, lant);
AI[nod + decalaj] = max(AI[2 * nod + decalaj], AI[2 * nod + 1 + decalaj]);
}
inline void update(int nod, int left, int right, int poz, int val, int decalaj)
{
if (left == right)
{
AI[nod + decalaj] = val;
return;
}
int mij = (left + right) / 2;
if (poz <= mij)
update(2 * nod, left, mij, poz, val, decalaj);
else
update(2 * nod + 1, mij + 1, right, poz, val, decalaj);
AI[nod + decalaj] = max(AI[2 * nod + decalaj], AI[2 * nod + 1 + decalaj]);
}
inline int query(int nod, int left, int right, int qleft, int qright, int decalaj)
{
if (qleft <= left && qright >= right)
return AI[nod + decalaj];
int mij = (left + right) / 2;
int rez = 0;
if (qleft <= mij)
rez = max(rez, query(2 * nod, left, mij, qleft, qright, decalaj));
if (qright > mij)
rez = max(rez, query(2 * nod + 1, mij + 1, right, qleft, qright, decalaj));
return rez;
}
int main()
{
f>>n>>m;
for (int i = 1; i <= n; i++)
f>>value[i];
for (int x, y, i = 1; i < n; i++)
{
f>>x>>y;
a[x].push_back(y);
a[y].push_back(x);
}
niv[1] = 1;
DF(1);
for (int i = 1; i <= nL; i++)
{
reverse(P[i].begin(), P[i].end());
if (i > 1)
lPoz[i] = lPoz[i - 1] + lDim[i - 1] * 4;
build(1, 1, lDim[i], lPoz[i], i);
}
while(m--) {
int t, x, y;
f>>t>>x>>y;
if (t == 0)
update(1, 1, lDim[l[x]], niv[x] - lNiv[l[x]], y, lPoz[l[x]]);
else {
int sol = 0;
while(true) {
if (l[x] == l[y]) {
if (niv[x] > niv[y])
swap(x, y);
sol = max(sol, query(1, 1, lDim[l[x]], niv[x] - lNiv[l[x]], niv[y] - lNiv[l[x]], lPoz[l[x]]));
break;
}
if (lNiv[l[x]] < lNiv[l[y]])
swap(x, y);
sol = max(sol, query(1, 1, lDim[l[x]], 1, niv[x] - lNiv[l[x]], lPoz[l[x]]));
x = lTata[l[x]];
}
g<<sol<<'\n';
}
}
return 0;
}