#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 2e4+10;
int n,m,sum_siz,root,tot,cnt,ans,u,v,w;
int head[N],max_siz[N],siz[N],dis[N],a[N],tong[10];
bool vis[N];
struct node
{
int to,net,w;
}e[N<<1];
inline int read()
{
int s = 0,w = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
return s * w;
}
void add(int x,int y,int w)
{
e[tot].w = w;
e[tot].to = y;
e[tot].net = head[x];
head[x] = tot;
}
int gcd(int a,int b)
{
if(b == 0) return a;
else return gcd(b,a%b);
}
void get_root(int x,int fa)//找重心
{
max_siz[x] = 0; siz[x] = 1;
for(int i = head[x]; i; i = e[i].net)
{
int to = e[i].to;
if(to == fa || vis[to]) continue;
get_root(to,x);
siz[x] += siz[to];
max_siz[x] = max(max_siz[x],siz[to]);
}
max_siz[x] = max(max_siz[x],sum_siz-siz[x]);
if(max_siz[x] < max_siz[root]) root = x;
}
void get_dis(int x,int fa)//找距离
{
a[cnt] = dis[x];
for(int i = head[x]; i; i = e[i].net)
{
int to = e[i].to;
if(to == fa || vis[to]) continue;
dis[to] = dis[x] + e[i].w;
get_dis(to,x);
}
}
int calc(int x,int d)//统计在 x 点的答案
{
tong[1] = tong[2] = tong[0] = 0;
dis[x] = d; cnt = 0;
a[cnt] = dis[x];
for(int i = head[x]; i; i = e[i].net)
{
int to = e[i].to;
if(vis[to]) continue;
dis[to] = dis[x] + e[i].w;
get_dis(to,x);
}
for(int i = 1; i <= cnt; i)
{
tong[a[i]%3];
}
return tong[1] * tong[2] * 2 + tong[0] * tong[0];
}
void slove(int x)//点分治
{
ans += calc(x,0);
vis[x] = 1;
for(int i = head[x]; i; i = e[i].net)
{
int to = e[i].to;
if(vis[to]) continue;
ans -= calc(to,e[i].w);
max_siz[0] = n; sum_siz = siz[to]; root = 0;
get_root(to,0); slove(root);
}
}
int main()
{
n = read();
for(int i = 1; i <= n-1; i)
{
u = read(); v = read(); w = read();
add(u,v,w); add(v,u,w);
}
max_siz[0] = sum_siz = n; root = 0;
get_root(1,0); slove(root);//找整棵树的重心
int d = gcd(ans,nn);//约分
printf("%d/%d",ans/d,(nn)/d);
return 0;
}