#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
#define m_p make_pair
#define sz(x) (int)x.size()
#define out(x) cerr<<#x<<" = "<<x<<" "
#define outln(x) cerr<<#x<<" = "<<x<<endl
#define outarr(x,l,r) cerr<<#x"["<<l<<"-"<<r<<"] = "; for (int _i=l;_i<=r;++_i) cerr<<x[_i]<<" ";cerr<<endl;
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,int> pli;
#define gc() getchar()
//char buf[1<<23],*p1=buf,*p2=buf;
//#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
template <class T> void read(T &x)
{
    x=0; char c=gc(); int flag=0;
    while (c<'0'||c>'9') flag|=(c=='-'),c=gc();
    while (c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=gc();
    if (flag) x=-x;
}
template <class T> T _max(T a,T b){return a>b ? a : b;}
template <class T> T _min(T a,T b){return a<b ? a : b;}
template <class T> bool checkmax(T &a,T b){return b>a ? a=b,1 : 0;}
template <class T> bool checkmin(T &a,T b){return b<a ? a=b,1 : 0;}
const int N=200005;
int n,k;
vector <int> G[N];
int son[N],fa[N],sz[N],ans[N];
int a[N],b[N];
void add_edge(int x,int y)
{
	G[x].push_back(y);
}

void dfs(int x,int f)
{
	son[x]=0; sz[x]=1; fa[x]=f;
	for (int i=0;i<sz(G[x]);++i)
	{
		int to=G[x][i];
		if (to==f) continue;
		dfs(to,x);
		sz[x]+=sz[to];
		if (sz[to]>sz[son[x]]) son[x]=to;
	}
}

namespace dsu
{
	int sz[N],father[N],cnt[N],result;
	int top=0; pii S[N];
	void init(int x)
	{
		for (int i=1;i<=x;++i)
		{
			father[i]=i;
			sz[i]=1;
			cnt[i]=0;
		}
		top=result=0;
	}
	
	int getfather(int x)
	{
		return father[x]==x ? x : father[x]=getfather(father[x]);
	}
	
	void merge(int x,int y)
	{
		int A=getfather(x); int B=getfather(y);
		if (A!=B)
		{
			if (sz[A]>sz[B]) swap(A,B);
			father[A]=B;
			if (cnt[A]&&cnt[B]) --result;
			sz[B]+=sz[A]; cnt[B]+=cnt[A];
			S[++top]=m_p(A,B);
			++result; 
		}
		else
		{
			if (!cnt[A]) ++result;
			++cnt[A];
			S[++top]=m_p(-A,-B);
		}
	}
	
	void undo_till(int k)
	{
		while (k<top)
		{
			int x=S[top].first;
			int y=S[top].second;
			if (x<0)
			{
				x=-x;
				--cnt[x];
				if (!cnt[x]) --result;
			}
			else
			{
				sz[y]-=sz[x];
				cnt[y]-=cnt[x];
				if (cnt[x]&&cnt[y]) ++result;
				father[x]=x;
				--result;
			}
			--top;
		}
	}
}

void init()
{
	read(n); read(k);
	for (int i=1,u,v;i<n;++i)
	{
		read(u); read(v);
		add_edge(u,v);
		add_edge(v,u);
	}
	dfs(1,0);
	for (int i=1;i<=n;++i)
	{
		read(a[i]); read(b[i]);
	}
	dsu::init(k);
}

void undo(int x)
{
	dsu::merge(a[x],b[x]);
	for (int i=0;i<sz(G[x]);++i)
	{
		int to=G[x][i];
		if (to==fa[x]) continue;
		undo(to);
	}
}

void run(int x)
{
	for (int i=0;i<sz(G[x]);++i)
	{
		int to=G[x][i];
		if (to==fa[x]||to==son[x]) continue;
		int pre=dsu::top;
		run(to);
		dsu::undo_till(pre);
	}
	if (son[x])
	{
		run(son[x]);
	}
	dsu::merge(a[x],b[x]);
	for (int i=0;i<sz(G[x]);++i)
	{
		int to=G[x][i];
		if (to==fa[x]||to==son[x]) continue;
		undo(to);
	}
	ans[x]=dsu::result;
	return;
}

void solve()
{
	run(1);
	for (int i=1;i<=n;++i)	
	{
		printf("%d\n",ans[i]);
	}
}

int main()
{
	init();
	solve();
    return 0;
}


Measured memory_bytes: 24316