#include<queue>
#include<vector>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

const int inf=1000000;
const int maxn=20010;

struct edge{
	int to,cost,val;
	edge(){} 
	edge(int a,int b,int c){
		to=a;cost=b;val=c;
	}
};

vector<edge> G[maxn];
int dis[maxn],value[maxn];

void dij(int st){
	priority_queue<P,vector<P>,greater<P> > que;
	fill(dis,dis+maxn,inf);
	fill(value,value+maxn,inf);
	dis[st]=0;
	que.push(P(0,st));
	while(!que.empty()){
		P p=que.top();que.pop();
		int v=p.second;
		if(dis[v]<p.first) continue;
		for(unsigned int i=0;i<G[v].size();i++){
			edge e=G[v][i];
			if(dis[e.to]>dis[v]+e.cost){
				 dis[e.to]=dis[v]+e.cost;
				 value[e.to]=e.val;
				 que.push(P(dis[e.to],e.to));
			}else if(dis[e.to]==dis[v]+e.cost) value[e.to]=min(value[e.to],e.val);
		}
	}
} 

int main(){
	ios::sync_with_stdio(false);
	int n,m,a,b,c,d;
	while(cin>>n>>m){
		if(n==0 && m==0) break;
		for(int i=0;i<maxn;i++) G[i].clear();
		for(int i=0;i<m;i++){
			cin>>a>>b>>c>>d; 
			G[a].push_back(edge(b,c,d));
			G[b].push_back(edge(a,c,d));
		}
		dij(1);
		int ans=0;
		for(int i=2;i<=n;i++) ans+=value[i];
		cout<<ans<<endl;
	} 
	return 0;
}
