#include <cstdio> #include <iostream> #include <string> #include <algorithm> using namespace std; const int MAX=100; struct Edge{ int from; int to; int cost; bool operator<(const Edge& e)const{ return cost<e.cost; } }; Edge edge[MAX*MAX]; int father[MAX]; int height[MAX]; void Initialize(int n){ for(int i=0;i<=n;i++){ father[i]=i; height[i]=0; } return; } int Find(int x){ if(x!=father[x]){ return Find(father[x]); } return father[x]; } void Union (int x, int y){ x=Find(x); y= Find(y); if(x!=y){ if(height[x]< height[y]){ father[x]=y; }else if(height[y]< height[x]){ father[y]=x; }else{ father[y]=x; height[x]++; } } return; } int Kruskal(int n, int edgeNumber){ Initialize(n); sort(edge,edge+edgeNumber); int sum=0; for(int i=0;i<edgeNumber;i++){ Edge current =edge[i]; if(Find(current.from)!= Find(current.to)){ Union(current.from,current.to); sum+=current.cost; } } return sum; } int main() { int N; while (scanf("%d", &N) != EOF) { if (N == 0) { break; } int edgeNumber = N * (N - 1) / 2; for (int i = 0; i < edgeNumber; i++) { int status; scanf("%d%d%d%d", &edge[i].from, &edge[i].to, &edge[i].cost, &status); if (status == 1) { edge[i].cost = 0; } } int answer = Kruskal(N, edgeNumber); printf("%d\n", answer); } return 0; }