#include <cstdio>
#include <vector>
#include <algorithm>
#define Nmax 100005
using namespace std;
int N, M, nrp = 1;
int V[Nmax], Place[Nmax], Poz[Nmax];
int Viz[Nmax], W[Nmax], H[Nmax], Used[Nmax], T[Nmax];
vector <int> G[Nmax], Lant[Nmax], Arb[Nmax];
struct Comp
{
bool operator()(int a, int b)
{
if (W[a] > W[b])
return true;
return false;
}
};
void Citire()
{
int x, y;
scanf("%d %d", &N, &M);
for (int i = 1; i <= N; ++i)
{
scanf("%d", &V[i]);
W[i] = 1;
}
for (int i = 1; i <= N - 1; ++i)
{
scanf("%d %d", &x, &y);
G[x].push_back(y);
G[y].push_back(x);
}
}
void DFS(int nod, int h)
{
vector <int> :: iterator it;
Viz[nod] = 1;
H[nod] = h;
for (it = G[nod].begin(); it != G[nod].end(); ++it)
if (!Viz[*it])
{
DFS(*it, h + 1);
W[nod] += W[*it];
}
}
void Lanturi(int nod, int nr)
{
vector <int> :: iterator it;
Viz[nod] = 0;
Lant[nr].push_back(nod);
Poz[nod] = Lant[nr].size();
Place[nod] = nr;
for (it = G[nod].begin(); it != G[nod].end(); ++it)
if (Viz[*it])
{
if (!Used[nod])
{
Used[nod] = 1;
Lanturi(*it, nr);
}
else
{
T[++nrp] = nod;
Lanturi(*it, nrp);
}
}
}
void Update(int nod, int st, int dr, int val, int poz, int ind)
{
if (st == dr)
{
while (nod + 1 > Arb[ind].size())
Arb[ind].push_back(0);
Arb[ind][nod] = val;
return;
}
int mij = (st + dr) / 2;
if (poz <= mij)
Update(2 * nod, st, mij, val, poz, ind);
else
Update(2 * nod + 1, mij + 1, dr, val, poz, ind);
Arb[ind][nod] = max(Arb[ind][2 * nod], Arb[ind][2 * nod + 1]);
}
int main()
{
freopen("heavypath.in", "r", stdin);
freopen("heavypath.out", "w", stdout);
Citire();
DFS(1, 1);
for (int i = 1; i <= N; ++i)
sort(G[i].begin(), G[i].end(), Comp());
Lanturi(1, 1);
for (int i = 1; i <= nrp; ++i)
for (vector <int> :: iterator it = Lant[i].begin(); it != Lant[i].end(); ++it)
Update(1, 1, Lant[i].size(), V[*it], Poz[*it], i);
return 0;
}