#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e4 + 10;
const int INF = 1<<30;
int n,k,Root,ans;
int Tsize; //当前处理的这棵树的节点数
int maxson[N]; //以i为根的最大子树大小
int sz[N]; //以i为根的树的大小
int cnt[3]={0};
bool vis[N];
vector<pair<int,int> >v[N];
void GetRoot(int u,int fa) {
sz[u] = 1;maxson[u] = 0;
for (int i = 0; i < v[u].size(); i++) {
pair<int,int> p = v[u][i];
if (p.first == fa || vis[p.first]) continue;
GetRoot(p.first,u);
sz[u]+=sz[p.first];
maxson[u] = max(maxson[u],sz[p.first]);
}
maxson[u] = max(maxson[u],Tsize-sz[u]);
if (maxson[Root] > maxson[u]) Root = u;
}
void dfs(int u,int fa,int w) {
++cnt[w];
for (int i = 0; i < v[u].size(); i++) {
pair<int,int> p = v[u][i];
if (p.first == fa || vis[p.first]) continue;
dfs(p.first,u,(w+p.second)%3);
}
}
int calc(int u,int w) {
cnt[0] = cnt[1] = cnt[2] = 0; dfs(u,0,w);
return cnt[0]*cnt[0]+cnt[1]*cnt[2]*2;
}
void work(int u) {
vis[u] = 1;ans+=calc(u,0);
for (int i = 0; i < v[u].size();++i) {
pair<int,int> p = v[u][i];
if ( vis[p.first]) continue;
ans-=calc(p.first,p.second);
Root = 0,Tsize = sz[p.first];
GetRoot(p.first,0);
work(Root);
}
}
int gcd(int a,int b) { return b?gcd(b,a%b):a;}
int main(){
scanf("%d",&n);
for (int i = 1; i < n; i++) {
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
v[x].push_back(make_pair(y,z%3));
v[y].push_back(make_pair(x,z%3));
}
Tsize = n;
Root = ans = 0;
maxson[0] = INF;
GetRoot(1,0);
work(Root);
int fm = n*n;
int tf = gcd(ans,fm);
printf("%d/%d\n",ans/tf,fm/tf);
return 0;
}