#include <iostream>
#define int long long
using namespace std;
const int N = 1e6 + 10, INF = 0x3f3f3f3f3f3f3f3f;
int n, x[N], head[N], cnt, dp[N][2], ans = 0, res = INF;
struct Edge { int nxt, to; } e[N << 1];
void add(int u, int v) { e[++ cnt] = {head[u], v}; head[u] = cnt; }
int rd() {
int res = 0; bool f = 0; char ch = getchar();
while (ch < '0' || ch > '9') f |= ch == '-', ch = getchar();
while (ch >= '0' && ch <= '9') res = (res << 1) + (res << 3) + (ch ^ 48), ch = getchar();
return f ? -res : res;
}
void dfs(int u, int pre) {
int Max0 = 1, Max1 = 1;
if (x[u] == 1) dp[u][0] = 1;
else if (x[u] == 2) dp[u][1] = 1;
for (int i = head[u], v; i; i = e[i].nxt) {
v = e[i].to;
if (v == pre) continue;
dfs(v, u);
if (x[u] == 1) {
if (dp[v][0] + 1 > dp[u][0]) Max0 = dp[u][0], dp[u][0] = dp[v][0] + 1;
else if (dp[v][0] + 1 > Max0) Max0 = dp[v][0] + 1;
if (dp[v][1] + 1 > dp[u][1]) Max1 = dp[u][1], dp[u][1] = dp[v][1] + 1;
else if (dp[v][1] + 1 > Max1) Max1 = dp[v][1] + 1;
} else if (x[u] == 2) {
if (dp[v][0] + 1 > dp[u][1]) Max1 = dp[u][1], dp[u][1] = dp[v][0] + 1;
else if (dp[v][0] + 1 > Max1) Max1 = dp[v][0] + 1;
}
}
ans = max(ans, max((Max0 + dp[u][0] - 1) << 1, Max1 + dp[u][1] - 1));
}
signed main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
n = rd();
for (int i = 1, u, v; i < n; ++ i) u = rd(), v = rd(), add(u, v), add(v, u);
for (int i = 1; i <= n; ++ i) x[i] = rd(), res = min(res, x[i]);
dfs(1, 0);
if (ans > 1) {
if (ans & 1) cout << "2/" << ans << '\n';
else cout << "1/" << (ans >> 1) << '\n';
} else cout << res << "/1\n";
return 0;
}