1 #include <bits/stdc++.h>
2 using namespace std;
3 const int maxn = 100010;
4 typedef long long LL;
5 struct arc{
6 int to,w,next;
7 arc(int x = 0,int y = 0,int z = -1){
8 to = x;
9 w = y;
10 next = z;
11 }
12 }e[maxn<<1];
13 int head[maxn],sz[maxn],maxson[maxn],tot;
14 bool done[maxn] = {};
15 LL dis[3],ret;
16 void add(int u,int v,int w){
17 e[tot] = arc(v,w,head[u]);
18 head[u] = tot++;
19 }
20 int dfs(int u,int fa){
21 sz[u] = 1;
22 maxson[u] = 0;
23 for(int i = head[u]; ~i; i = e[i].next){
24 if(e[i].to == fa || done[e[i].to]) continue;
25 dfs(e[i].to,u);
26 sz[u] += sz[e[i].to];
27 maxson[u] = max(maxson[u],sz[e[i].to]);
28 }
29 return sz[u];
30 }
31 int FindRoot(const int sum,int u,int fa){
32 int ret = u;
33 maxson[u] = max(maxson[u],sum - maxson[u]);
34 for(int i = head[u]; ~i; i = e[i].next){
35 if(e[i].to == fa || done[e[i].to]) continue;
36 int x = FindRoot(sum,e[i].to,u);
37 if(maxson[ret] > maxson[x]) ret = x;
38 }
39 return ret;
40 }
41 void update(int u,int fa,int w){
42 ++dis[w];
43 for(int i = head[u]; ~i; i = e[i].next){
44 if(e[i].to == fa || done[e[i].to]) continue;
45 update(e[i].to,u,(e[i].w + w)%3);
46 }
47 }
48 void solve(int u){
49 int root = FindRoot(dfs(u,0),u,0);
50 done[root] = true;
51 memset(dis,0,sizeof dis);
52 update(root,0,0);
53 ret += dis[0]*dis[0] + dis[1]*dis[2]*2;
54 for(int i = head[root]; ~i; i = e[i].next){
55 if(done[e[i].to]) continue;
56 memset(dis,0,sizeof dis);
57 update(e[i].to,0,e[i].w%3);
58 ret -= dis[0]*dis[0] + dis[1]*dis[2]*2;
59 solve(e[i].to);
60 }
61 }
62 int main(){
63 int n,u,v,w;
64 scanf("%d",&n);
65 memset(head,-1,sizeof head);
66 for(int i = 1; i < n; ++i){
67 scanf("%d%d%d",&u,&v,&w);
68 add(u,v,w);
69 add(v,u,w);
70 }
71 solve(1);
72 LL gcd = __gcd(ret,(LL)n*n);
73 printf("%lld/%lld\n",ret/gcd,(LL)n*n/gcd);
74 return 0;
75 }