#include<iostream> #include<vector> #include<queue> #include<cstdio> using namespace std; struct edge { int from,to,cost; friend bool operator <(edge e1,edge e2) { return e1.cost>e2.cost; } }; const int MAXN=111; int u[MAXN]; vector<edge>v[MAXN]; bool selected[MAXN]; //bool select_e[MAXN][MAXN]; int find(int p) { if(u[p]==p) { return p; }else { return u[p]=find(u[p]); } } void connect(int a,int b) { int f1=find(a); int f2=find(b); int i=0; if(f1<f2) { u[f2]=f1; for(i=0;i<=int(v[f2].size())-1;i++) { v[f1].push_back(v[f2][i]); } }else { u[f1]=f2; for(i=0;i<=int(v[f1].size())-1;i++) { v[f2].push_back(v[f1][i]); } } } int prim(int p) { priority_queue<edge>q; int sum=0; p=find(p); selected[p]=1; int i=0; while(!q.empty()) { q.pop(); } for(i=0;i<=int(v[p].size())-1;i++) { int to=find(v[p][i].to); if(!selected[to]) { q.push(v[p][i]); } } while(!q.empty()) { int from; int i=0; int to; edge e=q.top(); to=find(e.to); from=find(e.from); q.pop(); if(!selected[to]) { sum=sum+e.cost; selected[to]=1; for(i=0;i<=int(v[to].size())-1;i++) { int too=find(v[to][i].to); if(!selected[too]) { q.push(v[to][i]); } } } } return sum; } void init(int n) { int i=0; for(i=0;i<=n;i++) { v[i].clear(); } memset(selected,0,sizeof(selected)); // memset(select_e,0,sizeof(select_e)); for(i=0;i<=n;i++) { u[i]=i; } } int main() { int n; while((scanf("%d",&n))&&(n!=0)) { int from,to,cost,builded; init(n); int i=0; n=(n*(n-1))/2; for(i=0;i<=n-1;i++) { scanf("%d%d%d%d",&from,&to,&cost,&builded); from=find(from); to=find(to); if(builded) { connect(from,to); }else { edge e={from,to,cost}; v[e.from].push_back(e); swap(e.from,e.to); v[e.from].push_back(e); } } cout<<prim(find(1))<<endl; } return 0; }