// 模板题
#include <bits/stdc++.h>
const int N = 2e4 + 10;
int n, now = 1, head[N], dis[N];
struct Node {int v, w, nxt;} G[N << 1];
int size[N], maxson[N], Root;
bool vis[N];
int js[N];
int Answer;
int Size;
#define gc getchar()
inline int read() {
int x = 0; char c = gc;
while(c < '0' || c > '9') c = gc;
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
return x;
}
inline void Add(int u, int v, int w) {G[now].v = v; G[now].w = w; G[now].nxt = head[u]; head[u] = now ++;}
void Getroot(int u, int fa) {
size[u] = 1;
maxson[u] = 0;
for(int i = head[u]; ~ i; i = G[i].nxt) {
int v = G[i].v;
if(vis[v] || v == fa) continue ;
Getroot(v, u);
size[u] += size[v];
maxson[u] = std:: max(maxson[u], size[v]);
}
maxson[u] = std:: max(maxson[u], Size - size[u]);
if(maxson[u] < maxson[Root]) Root = u;
}
void Getdis(int u, int fa, int len) {
dis[u] = len; js[dis[u]] ++;
for(int i = head[u]; ~ i; i = G[i].nxt) {
int v = G[i].v;
if(vis[v] || v == fa) continue ;
Getdis(v, u, (len + G[i].w) % 3);
}
}
int Calc(int u, int len) {
js[0] = js[1] = js[2] = 0;
Getdis(u, 0, len % 3);
return js[1] * js[2] * 2 + js[0] * js[0];
}
void Getans(int u) {
vis[u] = 1;
Answer += Calc(u, 0);
// std:: cout << "#";
// for(int i = 1; i <= n; i ++) std:: cout << dis[i] << " ";
// std:: cout << "
";
for(int i = head[u]; ~ i; i = G[i].nxt) {
int v = G[i].v;
if(vis[v]) continue ;
Answer -= Calc(v, G[i].w);
Root = 0;
Size = size[v];
Getroot(v, u);
Getans(Root);
}
}
int Gcd(int a, int b) {
return b == 0 ? a : Gcd(b, a % b);
}
int main() {
// freopen("gg.in", "r", stdin);
n = read();
for(int i = 1; i <= n; i ++) head[i] = -1;
for(int i = 1; i < n; i ++) {
int u = read(), v = read(), w = read();
Add(u, v, w), Add(v, u, w);
}
maxson[Root] = n;
Size = n;
Getroot(1, 0);
// std:: cout << Root << "
";
Getans(Root);
int gcd = Gcd(Answer, n * n);
std:: cout << Answer / gcd << "/" << n * n / gcd << "
";
return 0;
}