This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll; typedef pair<int, int> pii;
#define ff first
#define ss second
#define pb emplace_back
#define AI(x) begin(x),end(x)
#ifdef OWO
#define debug(args...) LKJ("\033[1;32m[ " + string(#args) + " ]\033[0m", args)
template <class I> void LKJ(I&&x) { cerr << x << endl; }
template <class I, class...T> void LKJ(I&&x, T&&...t) { cerr << x << ", "; LKJ(t...); }
template <class I> void OI(I a, I b) { while (a != b) cerr << *a << " \n"[(a = next(a)) == b]; }
#else
#define debug(...) 0
#define OI(...) 0
#endif
const int kN = 200002;
const int kL = 18;
int N, K, C[kN];
vector<int> adj[kN], town[kN];
int cityLCA[kN];
namespace LCA {
int dep[kN], anc[kL][kN];
void dfs(int u, int p) {
	anc[0][u] = p;
	for (const int& v: adj[u]) {
		if (v == p) continue;
		dep[v] = dep[u] + 1;
		dfs(v, u);
	}
}
void init() {
	dfs(1, 1);
	for (int l = 1; l < kL; ++l)
		for (int i = 1; i <= N; ++i)
			anc[l][i] = anc[l - 1][anc[l - 1][i]];
}
int getLCA(int u, int v) {
	if (dep[u] < dep[v]) swap(u, v);
	for (int d = dep[u] - dep[v], l = kL - 1; l >= 0; --l)
		if (d >> l & 1) u = anc[l][u];
	if (u == v) return u;
	for (int l = kL - 1; l >= 0; --l)
		if (anc[l][u] != anc[l][v]) {
			u = anc[l][u];
			v = anc[l][v];
		}
	return anc[0][u];
}
} // namespace LCA
namespace HLD {
int siz[kN], in[kN], ou[kN], tot;
int par[kN], head[kN], at[kN];
void dfs_siz(int u, int p) {
	par[u] = p;
	siz[u] = 1;
	for (int &v: adj[u]) {
		if (v == p) continue;
		dfs_siz(v, u);
		siz[u] += siz[v];
		if (siz[v] > siz[adj[u][0]])
			swap(v, adj[u][0]);
	}
}
void dfs_chain(int u, int h) {
	in[u] = ++tot;
	head[u] = h;
	for (const int& v: adj[u]) {
		if (v == par[u]) continue;
		dfs_chain(v, (v == adj[u][0] ? h : v));
	}
	ou[u] = tot;
}
void init() {
	dfs_siz(1, 1);
	dfs_chain(1, 1);
	for (int i = 1; i <= N; ++i)
		at[in[i]] = i;
}
vector<pii> get(int u, int v) {
	// go from u to v, v is par of u
	vector<pii> ans;
	while (head[u] != head[v]) {
		ans.pb(in[head[u]], in[u]);
		u = par[head[u]];
	}
	ans.pb(in[v], in[u]);
	return ans;
}
} // namespace HLD
struct SGT {
	int n, tot; vector<int> val;
	vector<vector<int>> adj;
	void init(int i, int l, int r) {
		if (l == r) {
			val[i] = C[HLD::at[l]];
			debug(l, r, val[i]);
			return;
		}
		val[i] = ++tot;
		debug(l, r, val[i]);
		int m = (l + r) / 2;
		init(i * 2, l, m);
		init(i * 2 + 1, m + 1, r);
	}
	void build(int i, int l, int r) {
		if (l == r) {
			return;
		}
		adj[val[i]].pb(val[i * 2]);
		adj[val[i]].pb(val[i * 2 + 1]);
		int m = (l + r) / 2;
		build(i * 2, l, m);
		build(i * 2 + 1, m + 1, r);
	}
	SGT (int _n): n(_n), val(n * 4 + 4), tot(K) {
		init(1, 1, n);
		adj.assign(tot + 1, vector<int>());
		build(1, 1, n);
	}
	void add(int i, int l, int r, int qv, int ql, int qr) {
		if (ql <= l and r <= qr) {
			adj[qv].pb(val[i]);
			return;
		}
		int m = (l + r) / 2;
		if (ql <= m) add(i * 2, l, m, qv, ql, qr);
		if (m < qr) add(i * 2 + 1, m + 1, r, qv, ql, qr);
	}
	void add(int qv, int ql, int qr) { add(1, 1, n, qv, ql, qr); }
};
struct SCC {
	int n, tot, sccnt, top;
	vector<vector<int>> adj;
	vector<int> pre, low;
	vector<int> ins, stk;
	vector<int> scc;
	vector<set<int>> has;
	SCC (const vector<vector<int>>& init):
		n(init.size()), tot(0), sccnt(0), top(0), adj(init), pre(n, 0), low(n, 0),
		ins(n, 0), stk(n, 0), scc(n, 0), has(n) {}
	void tarjan(int u) {
		low[u] = pre[u] = ++tot;
		ins[u] = true; stk[++top] = u;
		for (const int& v: adj[u]) {
			if (pre[v] == 0) {
				tarjan(v);
				low[u] = min(low[u], low[v]);
			} else if (ins[v])
				low[u] = min(low[u], pre[v]);
		}
		if (low[u] == pre[u]) {
			++sccnt;
			int v;
			do {
				v = stk[top--];
				scc[v] = sccnt;
				ins[v] = false;
				if (v <= K)
					has[sccnt].insert(v);
			} while (v != u);
		}
	}
	int solve() {
		for (int i = 1; i < n; ++i)
			if (pre[i] == 0) tarjan(i);
		vector<int> oudeg(n, 0);
		for (int i = 1; i < n; ++i)
			for (const int& j: adj[i])
				if (scc[i] != scc[j])
					++oudeg[scc[i]];
		int ans = n + n;
		for (int i = 1; i <= sccnt; ++i)
			if (oudeg[i] == 0)
				ans = min(ans, (int) has[i].size());
		return ans;
	}
};
signed main() {
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> N >> K;
	for (int A, B, i = 1; i < N; ++i) {
		cin >> A >> B;
		adj[A].pb(B);
		adj[B].pb(A);
	}
	for (int i = 1; i <= N; ++i) {
		cin >> C[i];
		town[C[i]].pb(i);
	}
	LCA::init();
	for (int i = 1; i <= K; ++i) {
		cityLCA[i] = town[i][0];
		for (int j = 1; j < town[i].size(); ++j)
			cityLCA[i] = LCA::getLCA(cityLCA[i], town[i][j]);
		//debug(i, cityLCA[i]);
	}
	HLD::init();
	for (int i = 1; i <= N; ++i) {
		debug(i, HLD::at[i]);
	}
	SGT sgt(N);
	for (int i = 1; i <= N; ++i) {
		int c = C[i];
		int u = HLD::at[i];
		int v = HLD::at[cityLCA[c]];
		debug(i, c, u, v);
		vector<pii> rs = HLD::get(i, cityLCA[c]);
		for (const auto& [l, r]: rs) {
			sgt.add(c, l, r);
			debug(l, r);
		}
	}
	for (int i = 1; i <= sgt.tot; ++i) {
		debug(i);
		auto &v = sgt.adj[i];
		sort(AI(v));
		v.erase(unique(AI(v)), end(v));
		OI(AI(sgt.adj[i]));
	}
	SCC scc(sgt.adj);
	cout << scc.solve() - 1 << '\n';
	return 0;
}
Compilation message (stderr)
capital_city.cpp: In member function 'void SGT::init(int, int, int)':
capital_city.cpp:14:20: warning: statement has no effect [-Wunused-value]
   14 | #define debug(...) 0
      |                    ^
capital_city.cpp:107:4: note: in expansion of macro 'debug'
  107 |    debug(l, r, val[i]);
      |    ^~~~~
capital_city.cpp:14:20: warning: statement has no effect [-Wunused-value]
   14 | #define debug(...) 0
      |                    ^
capital_city.cpp:111:3: note: in expansion of macro 'debug'
  111 |   debug(l, r, val[i]);
      |   ^~~~~
capital_city.cpp: In constructor 'SGT::SGT(int)':
capital_city.cpp:102:26: warning: 'SGT::val' will be initialized after [-Wreorder]
  102 |  int n, tot; vector<int> val;
      |                          ^~~
capital_city.cpp:102:9: warning:   'int SGT::tot' [-Wreorder]
  102 |  int n, tot; vector<int> val;
      |         ^~~
capital_city.cpp:126:2: warning:   when initialized here [-Wreorder]
  126 |  SGT (int _n): n(_n), val(n * 4 + 4), tot(K) {
      |  ^~~
capital_city.cpp: In function 'int main()':
capital_city.cpp:210:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  210 |   for (int j = 1; j < town[i].size(); ++j)
      |                   ~~^~~~~~~~~~~~~~~~
capital_city.cpp:14:20: warning: statement has no effect [-Wunused-value]
   14 | #define debug(...) 0
      |                    ^
capital_city.cpp:217:3: note: in expansion of macro 'debug'
  217 |   debug(i, HLD::at[i]);
      |   ^~~~~
capital_city.cpp:14:20: warning: statement has no effect [-Wunused-value]
   14 | #define debug(...) 0
      |                    ^
capital_city.cpp:226:3: note: in expansion of macro 'debug'
  226 |   debug(i, c, u, v);
      |   ^~~~~
capital_city.cpp:14:20: warning: statement has no effect [-Wunused-value]
   14 | #define debug(...) 0
      |                    ^
capital_city.cpp:230:4: note: in expansion of macro 'debug'
  230 |    debug(l, r);
      |    ^~~~~
capital_city.cpp:224:7: warning: unused variable 'u' [-Wunused-variable]
  224 |   int u = HLD::at[i];
      |       ^
capital_city.cpp:225:7: warning: unused variable 'v' [-Wunused-variable]
  225 |   int v = HLD::at[cityLCA[c]];
      |       ^
capital_city.cpp:14:20: warning: statement has no effect [-Wunused-value]
   14 | #define debug(...) 0
      |                    ^
capital_city.cpp:235:3: note: in expansion of macro 'debug'
  235 |   debug(i);
      |   ^~~~~
capital_city.cpp:15:17: warning: statement has no effect [-Wunused-value]
   15 | #define OI(...) 0
      |                 ^
capital_city.cpp:239:3: note: in expansion of macro 'OI'
  239 |   OI(AI(sgt.adj[i]));
      |   ^~| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |