#include<bits/stdc++.h>
using namespace std;
int N, a, b, Cost, state, edge_num;
struct edge {
    int one_pos;
    int another_pos;
    int cost;
};
edge e;
int root[101];
vector<edge> edges;//边的集合
//克鲁斯卡尔算法
int Kruskal() {
    int min_cost = 0;//最少花费
    //初始化:每一个顶点(村庄)都是一棵树,一共n棵树
    for (int i = 1; i <= N; i++) {
        root[i] = i; //自己的根是自己
    }
    for (int i = 0; i < edge_num; i++)
    {
        //如果不是一个集合,那么将两个集合(树)合并,并且将这条边的花费加入最小生成树的花费
        if (root[edges[i].one_pos] != root[edges[i].another_pos])
        {
            if (root[edges[i].one_pos] < root[edges[i].another_pos])
            {
                int small = root[edges[i].one_pos];
                int big = root[edges[i].another_pos];
                for (int k = 1; k <= N; k++)
                {
                    if (root[k] ==big)
                    {
                        root[k] = small;
                    }
                }
            }
            else
            {
                int big = root[edges[i].one_pos];
                int small = root[edges[i].another_pos];
                for (int k = 1; k <= N; k++)
                {
                    if (root[k] == big)
                    {
                        root[k] =small;
                    }
                }
            }
            min_cost += edges[i].cost;//将这条边的花费加入最小生成树的花费
        }
        //看看是不是所有村庄都汇集成了一棵大树
        bool flag = 1;//假设汇集成了
        for (int c = 1; c <= N; c++)
        {
            if (root[c] != 1)
            {
                flag = 0;
                break;
            }
        }
        if (flag == 1) break;
    }
    return min_cost;
}
int main() {
    while (cin >> N && N) {
        edges.clear();//清理上一轮的
        edge_num = (N - 1) * N / 2; //无向图的边的数目
        for (int i = 0; i < edge_num; i++) {
            cin >> a >> b >> Cost >> state;
            e.one_pos = a;
            e.another_pos = b;
            e.cost = Cost;
            if (state == 1) e.cost = 0;
            edges.push_back(e);//装入边集合
        }
        //将边按照cost排序
        sort(edges.begin(), edges.end(), [](const edge& a, const edge& b) {
            return a.cost < b.cost;
            });
        //克鲁斯卡尔算法
        cout << Kruskal() << endl;
    }

}
// 64 位输出请用 printf("%lld")