#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream in("heavypath.in");
ofstream out("heavypath.out");
int n, m, q, cnt, nr;
int p[100005];
vector<int> v[100005];
pair<int, int> euler[200005];
int viz[100005];
int first[100005];
int rmq[18][200005];
int w[100005];
int lant[100005];
int roof[100005];
int sz[100005];
int loc[100005];
vector<int> segtree[100005];
vector<int> inv[100005];
void dfs(int node, int nivel)
{
cnt++;
euler[cnt] = {node, nivel};
viz[node] = 1;
w[node] = 1;
int wmax = -1;
int poz = -1;
for(auto it: v[node])
{
if(viz[it] == 0)
{
dfs(it, nivel + 1);
w[node] += w[it];
roof[lant[it]] = node;
if(w[it] > wmax)
{
wmax = w[it];
poz = it;
}
cnt++;
euler[cnt] = {node, nivel};
}
}
//out<<node<<" "<<w[node]<<'\n';
if(wmax == -1)
{
nr++;
lant[node] = nr;
sz[nr] = 1;
loc[node] = 1;
}
else
{
lant[node] = lant[poz];
sz[lant[node]]++;
loc[node] = sz[lant[node]];
}
}
void build_rmq()
{
int put = 1;
for(int i = 1; i<=m; i++)
{
if(i == 1)
{
for(int j = 1; j<=cnt; j++)
{
rmq[i][j] = j;
}
}
else
{
for(int j = 1; j<=cnt-put+1; j++)
{
if(euler[rmq[i - 1][j]].second <= euler[rmq[i - 1][j + (put / 2)]].second)
{
rmq[i][j] = rmq[i - 1][j];
}
else
{
rmq[i][j] = rmq[i - 1][j + (put / 2)];
}
}
}
put *= 2;
}
}
int query_rmq(int x, int y)
{
x = first[x];
y = first[y];
if(x > y)
{
swap(x, y);
}
int l = y - x + 1;
int k = log2(l);
int m1 = rmq[k + 1][x];
int r = l - (1 << k);
int m2 = rmq[k + 1][x + r];
if(euler[m1].second <= euler[m2].second)
{
return euler[m1].first;
}
else
{
return euler[m2].first;
}
}
void build_segtree(int tree, int node, int left, int right)
{
if(left == right)
{
segtree[tree][node] = p[inv[tree][left]];
}
else
{
int mij = (left + right) / 2;
build_segtree(tree, 2*node, left, mij);
build_segtree(tree, 2*node+1, mij + 1, right);
segtree[tree][node] = max(segtree[tree][2*node], segtree[tree][2*node + 1]);
}
}
void update_segtree(int tree, int node, int left, int right, int poz, int val)
{
if(left == right)
{
segtree[tree][node] = val;
}
else
{
int mij = (left + right) / 2;
if(poz <= mij)
{
update_segtree(tree, 2*node, left, mij, poz, val);
}
else
{
update_segtree(tree, 2*node+1, mij+1, right, poz, val);
}
segtree[tree][node] = max(segtree[tree][2*node], segtree[tree][2*node + 1]);
}
}
int query_segtree(int tree, int node, int left, int right, int qleft, int qright)
{
if(qleft <= left && right <= qright)
{
return segtree[tree][node];
}
else
{
int mij = (left + right) / 2;
if(qright <= mij)
{
return query_segtree(tree, 2*node, left, mij, qleft, qright);
}
else if(mij + 1 <= qleft)
{
return query_segtree(tree, 2*node+1, mij + 1, right, qleft, qright);
}
return max(query_segtree(tree, 2*node, left, mij, qleft, qright), query_segtree(tree, 2*node+1, mij + 1, right, qleft, qright));
}
}
int query(int a, int b)
{
int x = a;
int y = b;
int ans = -1;
while(1)
{
if(lant[x] == lant[y])
{
int st = min(loc[x], loc[y]);
int dr = max(loc[x], loc[y]);
ans = max(ans, query_segtree(lant[y], 1, 1, sz[lant[y]], st, dr));
break;
}
else
{
ans = max(ans, query_segtree(lant[y], 1, 1, sz[lant[y]], 1, loc[y]));
y = roof[lant[y]];
}
}
return ans;
}
int main()
{
in>>n>>q;
for(int i = 1; i<=n; i++)
{
in>>p[i];
}
int x, y;
for(int i = 1; i<n; i++)
{
in>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
dfs(1, 1);
//le fac crescatoare
for(int i = 1; i<=n; i++)
{
loc[i] = sz[lant[i]] - loc[i] + 1;
}
//out<<cnt;
m = log2(cnt) + 1;
for(int i = 1; i<=cnt; i++)
{
if(first[euler[i].first] == 0)
{
first[euler[i].first] = i;
}
}
build_rmq();
//out<<query_rmq(5, 8);
/*out<<nr<<'\n';
for(int i = 1; i<=n; i++)
{
out<<lant[i]<<" ";
}
out<<'\n';
for(int i = 1; i<=nr; i++)
{
out<<sz[i]<<" ";
}
out<<'\n';
for(int i = 1; i<=n; i++)
{
out<<loc[i]<<" ";
}
out<<'\n';
for(int i = 1; i<=nr; i++)
{
out<<roof[i]<<" ";
}*/
for(int i = 1; i<=nr; i++)
{
segtree[i].resize(4 * sz[i] + 5);
//inv[i].resize(sz[i] + 5);
}
for(int i = 1; i<=n; i++)
{
//inv[lant[i]][loc[i]] = i;
}
for(int i = 1; i<=nr; i++)
{
//build_segtree(i, 1, 1, sz[i]);
}
/*int t;
while(q--)
{
in>>t>>x>>y;
if(t == 0)
{
update_segtree(lant[x], 1, 1, sz[lant[x]], loc[x], y);
}
else
{
if(lant[x] == lant[y])
{
//out<<x<<" "<<y<<" -> ";
int st = min(loc[x], loc[y]);
int dr = max(loc[x], loc[y]);
out<<query_segtree(lant[x], 1, 1, sz[lant[x]], st, dr)<<'\n';
}
else
{
int lca = query_rmq(x, y);
//out<<lca<<" ";
int ans = max(query(lca, x), query(lca, y));
out<<ans<<'\n';
}
}
}*/
return 0;
}