#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
#define lim 100005
vector <int> G[lim], PATHS[lim];
int n, nrpaths, pos, aux;
int l, r;
int dad[lim], weight[lim], ini[lim], lvl[lim], path[lim], sum[lim], posInPath[lim], aint[4 * lim];
void dfs (int nod, int d)
{
dad[nod] = d;
lvl[nod] = 1 + lvl[d];
weight[nod] = 1;
int son = 0;
for (auto it:G[nod])
{
if (it == d) continue;
if (son==0) son=it;
dfs (it, nod);
if (weight[it] > weight[son]) son=it;
weight[nod] += weight[it];
}
if (son==0)
{
PATHS[++nrpaths].push_back(nod);
path[nod] = nrpaths;
posInPath[nod] = 0;
return;
}
path[nod] = path[son];
posInPath[nod] = PATHS[path[nod]].size();
PATHS[path[nod]].push_back(nod);
}
void update (int nod, int st, int dr, int val, int decalaj)
{
if (st == dr)
{
aint[decalaj+nod] = val;
return;
}
int mid = (st+dr)/2;
if (pos <= mid) update (2*nod, st, mid, val, decalaj);
else update (2*nod+1, mid+1, dr, val, decalaj);
aint[decalaj + nod] = max (aint[decalaj + 2 * nod], aint[decalaj + 2 * nod + 1]);
}
int query (int nod, int st, int dr, int decalaj)
{
if (l<=st && dr<=r)
{
return aint[decalaj + nod];
}
int mid = (st+dr)/2;
int rez = 0;
if (l<=mid) rez = max (rez, query (2*nod, st, mid, decalaj));
if (mid+1<=r) rez = max (rez, query (2*nod+1, mid+1, dr, decalaj));
return rez;
}
int main()
{
int m, x, y, t;
fin>>n>>m;
for (int i=1; i<=n; i++) fin>>ini[i];
for (int i=1; i<n; i++)
{
fin>>x>>y;
G[x].push_back(y);
G[y].push_back(x);
}
dfs (1, 0);
for (int i=1; i<=nrpaths; i++)
sum[i] = sum[i-1] + PATHS[i].size();
for (int i=1; i<=n; i++)
{
pos = posInPath[i] + 1;
update (1, 1, PATHS[path[i]].size(), ini[i], 4 * sum[path[i] - 1]);
}
while (m--)
{
fin>>t;
if (t==0)
{
fin>>x;
fin>>ini[x];
pos = posInPath[x] + 1;
update (1, 1, PATHS[path[x]].size(), ini[x], 4 * sum[path[x] - 1]);
}
else
{
fin>>x>>y;
int rez=0;
while (path[x] != path[y])
{
if (lvl[PATHS[path[x]][PATHS[path[x]].size()-1]] < lvl[PATHS[path[y]][PATHS[path[y]].size()-1]])
swap (x, y);
aux = x;
l = posInPath[aux] + 1;
r = PATHS[path[aux]].size();
rez = max (rez, query (1, 1, PATHS[path[aux]].size(), 4 * sum[path[aux]-1]));
x = dad [PATHS[path[x]][PATHS[path[x]].size() - 1]];
}
l = posInPath[x] + 1;
r = posInPath[y] + 1;
if (l > r)
swap (l, r);
rez = max (rez, query (1, 1, PATHS[path[x]].size(), 4 * sum[path[x] - 1]));
fout<<rez<<"\n";
}
}
fout.close();
return 0;
}