#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
#define MAX 100005
typedef vector <int> :: iterator iter;
vector <int> G[MAX], P[MAX];
int n, nrOfPaths, ind, l, r;
int dad[MAX], weight[MAX], v[MAX], lvl[MAX], path[MAX], sum[MAX], indInPath[MAX], aint[4 * MAX];
void df(int nod, int d)
{
dad[nod] = d;
lvl[nod] = 1 + lvl[dad[nod]];
weight[nod] = 1;
int son = 0;
for(iter it = G[nod].begin() ; it != G[nod].end() ; it++)
{
if(*it == d)
continue;
if(son == 0)
son = *it;
df(*it, nod);
if(weight[*it] > weight[son])
son = *it;
weight[nod] += weight[*it];
}
if(son == 0)
{
P[++nrOfPaths].push_back(nod);
path[nod] = nrOfPaths;
indInPath[nod] = 0;
return;
}
path[nod] = path[son];
indInPath[nod] = P[path[nod]].size();
P[path[nod]].push_back(nod);
}
void update(int nod, int st, int dr, int val, int dec)
{
if(st == dr)
{
aint[dec + nod] = val;
return;
}
int mij = (st + dr) >> 1;
if(ind <= mij)
update(2 * nod, st, mij, val, dec);
else
update(2 * nod + 1, mij + 1, dr, val, dec);
aint[dec + nod] = max(aint[dec + 2 * nod], aint[dec + 2 * nod + 1]);
}
int query(int nod, int st, int dr, int dec)
{
if(l <= st && dr <= r)
{
return aint[dec + nod];
}
int mij = (st + dr) >> 1;
int rez = 0;
if(l <= mij)
rez = max(rez, query(2 * nod, st, mij, dec));
if(mij + 1 <= r)
rez = max(rez, query(2 * nod + 1, mij + 1, dr, dec));
return rez;
}
int main()
{
int i, m, x, y, t;
fin >> n >> m;
for(i = 1 ; i <= n ; i++)
fin >> v[i];
for(int i = 1 ; i < n ; i++)
{
fin >> x >> y;
G[x].push_back(y);
G[y].push_back(x);
}
df(1, 0);
for(i = 1 ; i <= nrOfPaths ; i++)
sum[i] = sum[i - 1] + P[i].size();
for(i = 1 ; i <= n ; i++)
{
ind = indInPath[i] + 1;
//cout << i << " " << ind << " " << P[path[i]].size() << " " << 4 * sum[path[i] - 1] << "\n";
update(1, 1, P[path[i]].size(), v[i], 4 * sum[path[i] - 1]);
}
while(m--)
{
fin >> t;
if(t == 0)
{
fin >> i;
fin >> v[i];
ind = indInPath[i] + 1;
update(1, 1, P[path[i]].size(), v[i], 4 * sum[path[i] - 1]);
}
else
{
fin >> x >> y;
int rez = 0;
while(path[x] != path[y])
{
if(lvl[P[path[x]][P[path[x]].size() - 1]] < lvl[P[path[y]][P[path[y]].size() - 1]])
swap(x, y);
i = x;
l = indInPath[i] + 1;
r = P[path[i]].size();
rez = max(rez, query(1, 1, P[path[i]].size(), 4 * sum[path[i] - 1]));
x = dad[P[path[x]][P[path[x]].size() - 1]];
}
l = indInPath[x] + 1;
r = indInPath[y] + 1;
if(l > r)
swap(l, r);
// cout << l << " " << r << "\n" << rez << "\n";;
rez = max(rez, query(1, 1, P[path[x]].size(), 4 * sum[path[x] - 1]));
fout << rez << "\n";
}
}
}