#include <bits/stdc++.h>
#define int long long
using namespace std;

const int INF = 1e+18;

template<class T>
struct Edge{
	int from,to;
	T cost;
	Edge(int to,T cost) : to(to),cost(cost){}
	Edge(int from,int to,T cost) : from(from),to(to),cost(cost){}
};

template<class T>
using WeightedGraph = vector<vector<Edge<T>>>;
using Graph = vector<vector<int>>;
template<class T>
using Matrix = vector<vector<T>>;

template<class T>
vector<T> dijkstra(const WeightedGraph<T> &G,int source = 0){
	using P = pair<T,int>;
	vector<T> dist(G.size(),INF);
	priority_queue<P,vector<P>,greater<P>> que;
	dist[source] = 0;
	que.emplace(dist[source],source);
	while(!que.empty()){
		P p = que.top();que.pop();
		int v = p.second;
		if(dist[v] < p.first) continue;
		for(const auto &e : G[v]){
			if(dist[e.to] > dist[v] + e.cost){
				dist[e.to] = dist[v] + e.cost;
				que.emplace(dist[e.to],e.to);
			}
		}
	}
	return dist;
}

signed main(){
	int n,m;
	while(cin >> n >> m,n){
		int u[20010],v[20010],d[20010],c[20010];
		WeightedGraph<int> G(n);
		for(int i = 0;i < m;i++){
			cin >> u[i] >> v[i] >> d[i] >> c[i]; u[i]--;v[i]--;
			G[u[i]].emplace_back(v[i],d[i]);
			G[v[i]].emplace_back(u[i],d[i]);
		}
		auto dist = dijkstra(G);
		int minInCost[10010] = {};
		for(int i = 1;i < n;i++) minInCost[i] = INF;
		for(int i = 0;i < m;i++){
			if(dist[u[i]] > dist[v[i]]) swap(u[i],v[i]);
			if(dist[u[i]] + d[i] == dist[v[i]]){
				minInCost[v[i]] = min(minInCost[v[i]],c[i]);
			}
		}
		int ans = 0;
		for(int i = 0;i < n;i++) ans += minInCost[i];
		cout << ans << endl;
	}
}
