#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;
}