#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx2")
using namespace std;
ifstream in("heavypath.in");
ofstream out("heavypath.out");
int n,q,v[200005];
vector<int> g[200005],f[200005];
int t[200005],h[200005],sz[200005];
int szheavy[200005],heavyson[200005];
int ord[200005],pos[200005],curord;
int vord[200005];
bool isheavy[200005];
int lastheavy[200005];
void dfs(int nod)
{
sz[nod] = 1;
for (auto vecin : g[nod])
{
if (vecin != t[nod])
{
t[vecin] = nod;
f[nod].push_back(vecin);
h[vecin] = 1 + h[nod];
dfs(vecin);
sz[nod] += sz[vecin];
if (sz[vecin] > szheavy[nod])
{
szheavy[nod] = sz[vecin];
heavyson[nod] = vecin;
}
}
}
}
void dfs2(int nod)
{
if (!isheavy[nod])
lastheavy[nod] = nod;
else
lastheavy[nod] = lastheavy[t[nod]];
ord[++curord] = nod;
pos[nod] = curord;
if (!f[nod].empty())
{
isheavy[heavyson[nod]] = true;
dfs2(heavyson[nod]);
for (auto vecin : f[nod])
{
if (vecin != heavyson[nod])
dfs2(vecin);
}
}
}
int bl[20][200005];
int lca(int x,int y)
{
if (h[x] < h[y])
swap(x,y);
for (int pas = 17; pas >= 0; pas--)
if (h[x] - (1 << pas) >= h[y])
x = bl[pas][x];
if (x == y)
return x;
for (int pas = 17; pas >= 0; pas--)
if (bl[pas][x] != bl[pas][y])
x = bl[pas][x],y = bl[pas][y];
return t[x];
}
int aint[800005];
void build(int nod,int l,int r)
{
if (l == r)
aint[nod] = vord[l];
else
{
int mij = (l + r) / 2;
build(2 * nod,l,mij);
build(2 * nod + 1,mij + 1,r);
aint[nod] = max(aint[2 * nod],aint[2 * nod + 1]);
}
}
void update(int nod,int l,int r,int pos,int val)
{
if (l == r)
aint[nod] = val;
else
{
int mij = (l + r) / 2;
if (pos <= mij)
update(2 * nod,l,mij,pos,val);
else
update(2 * nod + 1,mij + 1,r,pos,val);
aint[nod] = max(aint[2 * nod],aint[2 * nod + 1]);
}
}
int query(int nod,int l,int r,int st,int dr)
{
if (dr < l or r < st)
return 0;
if (st <= l and r <= dr)
return aint[nod];
int mij = (l + r) / 2;
return max(query(2 * nod,l,mij,st,dr),query(2 * nod + 1,mij + 1,r,st,dr));
}
int getans(int x,int y)
{
int ans = 0;
while (h[x] >= h[y])
{
int urm = lastheavy[x];
if (h[urm] < h[y])
urm = y;
ans = max(ans,query(1,1,n,pos[urm],pos[urm] + h[x] - h[urm]));
x = t[urm];
}
return ans;
}
int main()
{
in >> n >> q;
for (int i = 1; i <= n; i++)
in >> v[i];
for (int i = 1; i < n; i++)
{
int x,y;
in >> x >> y;
g[x].push_back(y);
g[y].push_back(x);
}
h[0] = -1;
dfs(1);
dfs2(1);
/*for (int i = 1; i <= n; i++)
cout << pos[i] << ' ';
cout << endl;*/
/*for (int i = 1; i <= curord; i++)
cout << ord[i] << ' ';
cout << endl;*/
for (int i = 1; i <= n; i++)
bl[0][i] = t[i];
for (int j = 1; j <= 17; j++)
for (int i = 1; i <= n; i++)
bl[j][i] = bl[j - 1][bl[j - 1][i]];
for (int i = 1; i <= n; i++)
vord[pos[i]] = v[i];
build(1,1,n);
for (int i = 1; i <= q; i++)
{
int tip,x,y;
in >> tip >> x >> y;
if (tip == 1)
update(1,1,n,pos[x],y);
else
{
int l = lca(x,y);
out << max(getans(x,l),getans(y,l)) << '\n';
}
}
return 0;
}