#include #include #include #include #include #include int n; std::vector adjList[100001]; long long int color[100001]; int dist[100001]; std::unordered_map> colorToIdx; std::pair bfs(int u) { std::fill(dist, dist + n + 1, -1); std::queue q; q.push(u); dist[u] = 0; while (!q.empty()) { int t = q.front(); q.pop(); for (int v : adjList[t]) { if (dist[v] == -1) { q.push(v); dist[v] = dist[t] + 1; } } } int maxDis = 0; int nodeIdx; for (int i = 1; i <= n; ++i) { if (color[i] == color[u] && dist[i] > maxDis) { maxDis = dist[i]; nodeIdx = i; } } return std::make_pair(nodeIdx, maxDis); } int longestPathLength() { int longest = -1; for (const auto &[col, s] : colorToIdx) { if (s.size() == 1) { continue; } std::pair t1, t2; t1 = bfs(*s.begin()); t2 = bfs(t1.first); longest = std::max(longest, t2.second); } return longest; } int dfsShortest(const std::unordered_set sources) { std::fill(dist, dist + n + 1, -1); std::queue q; for (int source : sources) { q.push(source); dist[source] = 0; } int shortest = 1000000, rem = q.size(); while (!q.empty()) { int u = q.front(); q.pop(); --rem; for (int v : adjList[u]) { if (dist[v] == -1) { q.push(v); dist[v] = dist[u] + 1; } else { shortest = std::min(shortest, dist[u] + 1 + dist[v]); } } if (rem == 0) { rem = q.size(); if (shortest != 1000000) { return shortest; } } } throw "Unreachable!"; } int shortestPathLength() { int shortest = 1000000; for (const auto &[col, s] : colorToIdx) { if (s.size() == 1) { continue; } shortest = std::min(shortest, dfsShortest(s)); } return (shortest == 1000000 ? -1 : shortest); } int main() { freopen("colors.in","r",stdin); freopen("colors.out","w",stdout); std::ios::sync_with_stdio(false); std::cin.tie(NULL); std::cout.tie(NULL); std::cin >> n; for (int i = 1; i < n; ++i) { int j, k; std::cin >> j >> k; adjList[j].push_back(k); adjList[k].push_back(j); } for (int i = 1; i <= n; ++i) { long long int ci; std::cin >> ci; color[i] = ci; colorToIdx[ci].insert(i); } std::cout << shortestPathLength() << ' ' << longestPathLength(); }