#include <bits/stdc++.h>

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); i++)
//#define int long long
#define FOR(i, m, n) for (int i = (m); i < (n); i++)
#define all(x) x.begin(), x.end()

int N, M;

struct Edge {
    int from, to, d, cost;
    Edge(int from, int to, int d, int cost) : from(from), to(to), d(d), cost(cost) {}
    bool operator<(const Edge &e) {
        if (d == e.d) return cost < e.cost;
        return d < e.d;
    }
};

using pii = pair<int, int>;

vector<Edge> G[10010];
int dist[10010];
void dijkstra(int s) {
    REP(i, N) { dist[i] = 1e9; }
    dist[s] = 0;
    priority_queue<pii, vector<pii>, greater<pii>> que;
    que.push({0, s});
    while (!que.empty()) {
        pii p = que.top();
        que.pop();
        int now = p.second, res = p.first;
        if (res > dist[now]) continue;
        for (auto e : G[now]) {
            if (dist[e.to] > res + e.d) {
                dist[e.to] = res + e.d;
                que.push({dist[e.to], e.to});
            }
        }
    }
}
struct UnionFind {
    int N;
    vector<int> siz, par, Rank;

    UnionFind(int n) : siz(n, 1), par(n), Rank(n, 0), N(n) { REP(i, N) par[i] = i; }

    int find(int x) {
        if (par[x] == x)
            return x;
        else
            return par[x] = find(par[x]);
    }
    void init(int N) {
        REP(i, N) {
            siz[i] = 1;
            par[i] = i;
            Rank[i] = 0;
        }
    }
    void unite(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) return;
        if (Rank[x] < Rank[y]) {
            par[x] = y;
            siz[x] += siz[y];
            siz[y] = siz[x];
        } else {
            siz[y] += siz[x];
            siz[x] = siz[y];
            par[y] = x;
            if (Rank[x] == Rank[y]) Rank[x]++;
        }
    }
    bool same(int x, int y) { return find(x) == find(y); }
};

bool solve() {
    cin >> N >> M;
    if (N == 0) return false;
    REP(i, N) { G[i].clear(); }
    int sum = 0;
    vector<Edge> es;
    REP(i, M) {
        int u, v, d, c;
        cin >> u >> v >> d >> c;
        u--, v--;
        // sum += c;
        es.push_back({u, v, d, c});
    }
    REP(i, N) dist[i] = 1e9;
    dist[0] = 0;
    priority_queue<pii, vector<pii>, greater<pii>> que;
    REP(_, M) {
        int mn = 1e9;
        int cst = 1e9;
        Edge ad(0, 0, 0, 0);
        for (auto e : es) {
            int u = e.from, v = e.to;
            if (dist[u] > dist[v]) swap(u, v);
            if (dist[u] + e.d >= dist[v]) continue;
            if (dist[u] + e.d == mn) {
                if (e.cost < cst) {
                    cst = e.cost;
                    ad = e;
                }
            } else if (dist[u] + e.d < mn) {
                cst = e.cost;
                mn = dist[u] + e.d;
                ad = e;
            }
        }
        if (ad.from == ad.to) break;
        sum += cst;
        int u = ad.from, v = ad.to;
        dist[u] = min(dist[u], dist[v] + ad.d);
        dist[v] = min(dist[v], dist[u] + ad.d);
        G[u].push_back({u, v, ad.d, ad.cost});
        G[v].push_back({v, u, ad.d, ad.cost});
        que.push({dist[u], u});
        que.push({dist[v], v});
        while (!que.empty()) {
            pii p = que.top();
            que.pop();
            int now = p.second, res = p.first;
            if (res > dist[now]) continue;
            for (auto e2 : G[now]) {
                if (dist[e2.to] > res + e2.d) {
                    dist[e2.to] = res + e2.d;
                    que.push({dist[e2.to], e2.to});
                }
            }
        }
    }
    cout << sum << endl;
    return true;
}

signed main() {
    while (solve())
        ;
}


Measured memory_bytes: 4728