#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define ll long long
const int N=2e5+50,M=3700000,lg=18;
vector<int>E[N];//,G[M],G1[M];
struct Graph{
int head[M],to[3*M],ind[3*M],nc;
void Edge(int u,int v){
nc++;
to[nc]=head[u];
head[u]=nc;
ind[nc]=v;
}
vector<int>adj(int u){
vector<int>a;
for(int i=head[u];i;i=to[i])a.pb(ind[i]);
return a;
}
}G,G1;
int n,K,C[N];
int nc;
int in[N],tajm,par[N][lg+1],vtx[N][lg+1],depth[N];
void DFSsetup(int u,int p=0){
in[u]=++tajm;
depth[u]=depth[p]+1;
par[u][0]=p;
vtx[u][0]=u;
for(int i=1;i<=lg;i++){
par[u][i]=par[par[u][i-1]][i-1];
if(par[u][i]!=0){
vtx[u][i]=++nc;
G.Edge(vtx[u][i],vtx[u][i-1]);
//G[vtx[u][i]].pb(vtx[u][i-1]);
G.Edge(vtx[u][i],vtx[par[u][i-1]][i-1]);
//G[vtx[u][i]].pb(vtx[par[u][i-1]][i-1]);
}
}
for(auto i:E[u])if(i!=p)DFSsetup(i,u);
}
int LCA(int u,int v){
if(depth[u]<depth[v])swap(u,v);
for(int i=lg;i>=0;i--)if(depth[par[u][i]]>=depth[v])u=par[u][i];if(u==v)return u;
for(int i=lg;i>=0;i--)if(par[u][i]!=par[v][i])u=par[u][i],v=par[v][i];return par[u][0];
}
void AddPath(int u,int v){
int c=LCA(u,v);
G.Edge(u,c);
//G[u].pb(c);
G.Edge(v,c);
//G[v].pb(c);
for(int x=u,i=lg;i>=0;i--){
if(depth[par[x][i]]>=depth[c]){
G.Edge(u,vtx[x][i]);
//G[u].pb(vtx[x][i]);
G.Edge(v,vtx[x][i]);
//G[v].pb(vtx[x][i]);
x=par[x][i];
}
}
for(int x=v,i=lg;i>=0;i--){
if(depth[par[x][i]]>=depth[c]){
G.Edge(u,vtx[x][i]);
//G[u].pb(vtx[x][i]);
G.Edge(u,vtx[x][i]);
//G[v].pb(vtx[x][i]);
x=par[x][i];
}
}
}
bool was[M];
vector<int>stek;
vector<vector<int>>comps;
int comp[M];
void DFS(int u){
was[u]=true;
//for(auto i:G[u])if(!was[i])DFS(i);
for(auto i:G.adj(u))if(!was[i])DFS(i);
stek.pb(u);
}
void DFS1(int u,int ind){
comp[u]=ind;
//for(auto i:G1[u])if(!comp[i])DFS1(i,ind);
for(auto i:G1.adj(u))if(!comp[i])DFS1(i,ind);
}
int main(){
scanf("%i%i",&n,&K);
for(int i=1;i<n;i++){
int u,v;scanf("%i%i",&u,&v);
E[u].pb(v);E[v].pb(u);
}
nc=n+K;
DFSsetup(1);
vector<int>vts[K+1];
for(int i=1;i<=n;i++){
scanf("%i",&C[i]);
vts[C[i]].pb(i);
G.Edge(i,C[i]+n);
//G[i].pb(C[i]+n);
G.Edge(C[i]+n,i);
//G[C[i]+n].pb(i);
}
for(int k=1;k<=K;k++){
sort(vts[k].begin(),vts[k].end(),[&](int i,int j){return in[i]<in[j];});
int m=vts[k].size();
for(int i=0;i<m;i++)AddPath(vts[k][i],vts[k][(i+1)%m]);
}
//for(int i=1;i<=nc;i++)for(auto j:G[i])G1[j].pb(i);
for(int i=1;i<=nc;i++)for(auto j:G.adj(i))G1.Edge(j,i);
for(int i=1;i<=nc;i++)if(!was[i])DFS(i);
int cnt=0;
while(!stek.empty()){
int u=stek.back();stek.pop_back();
if(comp[u])continue;
cnt++;
DFS1(u,cnt);
}
comps.resize(cnt+1);
for(int i=1;i<=nc;i++)comps[comp[i]].pb(i);
int res=1e9;
for(int k=1;k<=cnt;k++){
bool moze=true;
//for(auto i:comps[k])for(auto j:G[i])if(comp[j]!=comp[i])moze=false;
for(auto i:comps[k])for(auto j:G.adj(i))if(comp[j]!=comp[i])moze=false;
if(!moze)continue;
int x=0;
for(auto i:comps[k])if(n+1<=i&&i<=n+K)x++;
if(x>0)res=min(res,x-1);
}
printf("%i\n",res);
return 0;
}