#include <iostream>
#include <vector>
#include <queue>
#include <set>
#include <cassert>
#include <algorithm>
using namespace std;
#pragma warning (disable: 4996)

// 入力部
int N, A[1 << 19], B[1 << 19], C[1 << 19];
int M;
vector<int> X[1 << 19];

// 中心を求めるのに使うやつ
int dist[1 << 19];
int dist1[1 << 19], dist2[1 << 19];
bool iscentroid[1 << 19];

// 中心を外したグラフに関連する変数
int verdist[1 << 19];
int maxdist[1 << 19], label[1 << 19];
vector<int> Y[1 << 19];

void getdist(int pos) {
	for (int i = 1; i <= N; i++) dist[i] = (1 << 30);
	queue<int> Q; dist[pos] = 0; Q.push(pos);
	while (!Q.empty()) {
		int from = Q.front(); Q.pop();
		for (int i : X[from]) {
			if (dist[i] > dist[from] + 1) {
				dist[i] = dist[from] + 1;
				Q.push(i);
			}
		}
	}
}

vector<int> calc() {
	getdist(1);
	pair<int, int> maxn1 = make_pair(-(1 << 30), -1);
	for (int i = 1; i <= N; i++) maxn1 = max(maxn1, make_pair(dist[i], i));

	getdist(maxn1.second);
	pair<int, int> maxn2 = make_pair(-(1 << 30), -1);
	for (int i = 1; i <= N; i++) maxn2 = max(maxn2, make_pair(dist[i], i));
	for (int i = 1; i <= N; i++) dist1[i] = dist[i];

	getdist(maxn2.second);
	for (int i = 1; i <= N; i++) dist2[i] = dist[i];

	vector<pair<int, int>> V;
	for (int i = 1; i <= N; i++) {
		if (dist1[i] + dist2[i] == dist1[maxn2.second]) V.push_back(make_pair(max(dist1[i], dist2[i]), i));
	}
	sort(V.begin(), V.end());

	if (V[0].first == V[1].first) return vector<int>{ V[0].second, V[1].second };
	return vector<int>{ V[1].second, V[0].second, V[2].second };
}

void dfs1(int pos, int num) {
	maxdist[pos] = 0; label[pos] = num;
	for (int i : X[pos]) {
		if (maxdist[i] >= 0 || iscentroid[i] == true) continue;
		verdist[i] = verdist[pos] + 1;
		dfs1(i, num);
		Y[pos].push_back(i);
		maxdist[pos] = max(maxdist[pos], maxdist[i] + 1);
	}
}

// ここからはライブラリ
class BIT {
public:
	int size_ = 1;
	vector<int> bit;

	void init(int sz) {
		size_ = sz + 2;
		bit.resize(size_ + 2, 0);
		for (int i = 0; i < bit.size(); i++) bit[i] = 0;
	}
	void add(int pos, int x) {
		pos++;
		while (pos <= size_) {
			bit[pos] += x;
			pos += (pos & -pos);
		}
	}
	int sum(int pos) {
		int s = 0; pos++;
		while (pos >= 1) {
			s += bit[pos];
			pos -= (pos & -pos);
		}
		return s;
	}
};

class SegmentTree {
public:
	int size_ = 1;
	vector<int> counts;
	vector<int> idx;
	set<int> Tokusan[1 << 19];
	BIT Z;
	void init(int sz) {
		size_ = sz;
		idx.resize(size_ * 2 + 2, 0);
		counts.resize(size_ * 2 + 2, 0);
		Z.init(size_ * 2 + 2);
		for (int i = 0; i < counts.size(); i++) counts[i] = 0;
		for (int i = 0; i < counts.size(); i++) idx[i] = 0;
		for (int i = 0; i < size_ * 2 + 2; i++) Tokusan[i].clear();
	}
	int gettokusan(int x) {
		auto itr = Tokusan[x].begin();
		if (itr == Tokusan[x].end()) return -(1 << 30);
		return (*itr);
	}
	void dels(int pos) {
		counts[pos + size_]--;
		if (counts[pos + size_] == 0) {
			int val1 = gettokusan(idx[pos + size_]);
			if (val1 >= -(1 << 29)) Z.add(val1 + size_, -1);
			Tokusan[idx[pos + size_]].erase(pos);
			int val2 = gettokusan(idx[pos + size_]);
			if (val2 >= -(1 << 29)) Z.add(val2 + size_, 1);
			idx[pos + size_] = 0;
		}
	}
	void adds(int pos, int x) {
		counts[pos + size_]++;
		if (counts[pos + size_] == 1) {
			idx[pos + size_] = x;
			int val1 = gettokusan(idx[pos + size_]);
			if (val1 >= -(1 << 29)) Z.add(val1 + size_, -1);
			Tokusan[idx[pos + size_]].insert(pos);
			int val2 = gettokusan(idx[pos + size_]);
			if (val2 >= -(1 << 29)) Z.add(val2 + size_, 1);
		}
	}
	int getans(int pos) {
		return Z.sum(pos + size_);
	}
};

// ここからは個数を厳密に求めるやつ
int Answer[1 << 19], Fukasa[1 << 19];
SegmentTree Z0;

void dfs2(int pos, bool melee) {
	Fukasa[verdist[pos] + N] = pos;
	Answer[pos] = Z0.getans(verdist[pos] - maxdist[pos] - 1);

	// ランキングを求める
	vector<pair<int, int>> Ranking;
	for (int i : Y[pos]) Ranking.push_back(make_pair(maxdist[i], i));
	sort(Ranking.begin(), Ranking.end());

	// 再帰をする
	if (Ranking.size() >= 1) {
		int eval = -1;
		if (Ranking.size() >= 2) eval = Ranking[Ranking.size() - 2].first;
		for (int j = verdist[pos] - eval - 1; j <= verdist[pos] - 1; j++) Z0.dels(j);
		Z0.adds(verdist[pos], C[pos]);
		dfs2(Ranking[Ranking.size() - 1].second, true);
		Z0.dels(verdist[pos]);
		for (int j = verdist[pos] - eval - 1; j <= verdist[pos] - 1; j++) Z0.adds(j, C[Fukasa[j + N]]);
	}
	if (Ranking.size() >= 2) {
		for (int i = 0; i < (int)Ranking.size() - 1; i++) {
			Z0.adds(verdist[pos], C[pos]);
			dfs2(Ranking[i].second, false);
			Z0.dels(verdist[pos]);
		}
	}

	// 補正をする
	if (melee == false) {
		int eval = -1;
		if (Ranking.size() >= 1) eval = Ranking[Ranking.size() - 1].first;
		for (int i = verdist[pos] - eval - 1; i <= verdist[pos] - 1; i++) {
			Z0.adds(i, C[Fukasa[i + N]]);
		}
	}
	if (melee == true) {
		int v1 = verdist[pos] - 1;
		int v2 = verdist[pos] - maxdist[pos] - 1;
		int v3 = verdist[pos] - maxdist[pos] - 2;
		Z0.adds(v1, C[Fukasa[v1 + N]]);
		Z0.dels(v2);
		Z0.dels(v3);
	}
}

int main() {
	// ステップ 1. 入力
	scanf("%d%d", &N, &M);
	for (int i = 1; i <= N - 1; i++) scanf("%d%d", &A[i], &B[i]);
	for (int i = 1; i <= N; i++) scanf("%d", &C[i]);

	// ステップ 2. グラフの構成
	for (int i = 1; i <= N - 1; i++) {
		X[A[i]].push_back(B[i]);
		X[B[i]].push_back(A[i]);
	}

	// ステップ 3. 中心を求める
	vector<int> centroid = calc();
	for (int i : centroid) iscentroid[i] = true;

	// ステップ 4. 中心をグラフから外したグラフを考える
	for (int i = 1; i <= N; i++) maxdist[i] = -1;
	for (int i = 0; i < centroid.size(); i++) {
		int num = i;
		if (centroid.size() == 3) { if (i >= 1) num = 3 - i; }
		dfs1(centroid[i], num);
	}

	// ステップ 5. 珍しい都市の候補を判定する
	vector<int> cnt0(N, 0);
	vector<pair<int, int>> unique0;
	for (int i = 1; i <= N; i++) {
		if (label[i] != 0) continue;
		cnt0[verdist[i]]++;
	}
	for (int i = 1; i <= N; i++) {
		if (label[i] != 0 || cnt0[verdist[i]] >= 2) continue;
		unique0.push_back(make_pair(verdist[i], i));
	}
	vector<int> cnt1(N, 0);
	vector<pair<int, int>> unique1;
	for (int i = 1; i <= N; i++) {
		if (label[i] != 1) continue;
		cnt1[verdist[i]]++;
	}
	for (int i = 1; i <= N; i++) {
		if (label[i] != 1 || cnt1[verdist[i]] >= 2) continue;
		unique1.push_back(make_pair(verdist[i], i));
	}

	// ステップ 6. 深さ優先探索の前準備
	int offset = 1;
	if (centroid.size() == 3) offset = 2;
	int damage = 0;
	if (centroid.size() == 3) damage = maxdist[centroid[1]];

	// ステップ 7. 左側について、深さ優先探索を行う
	Z0.init(N);
	for (int i = 0; i < unique1.size(); i++) {
		Z0.adds(-unique1[i].first - offset, C[unique1[i].second]);
		Fukasa[-unique1[i].first - offset + N] = unique1[i].second;
	}
	if (offset == 2) { Z0.adds(-1, C[centroid[1]]); }
	for (int i = -offset + 1 - damage; i <= -offset; i++) Z0.dels(i);
	dfs2(centroid[0], false);

	// ステップ 8. 右側について、深さ優先探索を行う
	Z0.init(N);
	for (int i = 0; i < unique0.size(); i++) {
		Z0.adds(-unique0[i].first - offset, C[unique0[i].second]);
		Fukasa[-unique0[i].first - offset + N] = unique0[i].second;
	}
	if (offset == 2) { Z0.adds(-1, C[centroid[1]]); }
	for (int i = -offset + 1 - damage; i <= -offset; i++) Z0.dels(i);
	dfs2(centroid[offset], false);

	// ステップ 9. 中側について、深さ優先探索を行う
	if (offset == 2) {
		Z0.init(N);
		dfs2(centroid[1], false);
	}

	// ステップ 9. 出力する
	for (int i = 1; i <= N; i++) {
		if (M == 1) printf("%d\n", min(1, Answer[i]));
		else printf("%d\n", Answer[i]);
	}
	return 0;
}


Measured memory_bytes: 108976