#include<bits/stdc++.h>
#define INF 1e9
#define llINF 1e18
#define MOD 1000000007
#define pb push_back
#define mp make_pair 
#define F first
#define S second
#define ll long long
#define ull unsigned long long
#define vi vector<ll>
#define vvi vector<vi>
#define DBG_N(hoge) cerr<<" "<<(hoge)<<endl;
#define DBG cerr<<"!"<<endl;
#define BITLE(n) (1LL<<((ll)n))
#define BITCNT(n) (__builtin_popcountll(n))
#define SUBS(s,f,t) ((s).substr((f)-1,(t)-(f)+1))
#define ALL(a) (a).begin(),(a).end()
using namespace std;

const ll MAX_V=20100;
const ll Inf=1e18;
struct Unionfind{
  vi par;
  Unionfind(){}
  Unionfind( int n ) :  par(n){
    for(int i=0;i<n;i++) par[i] = i;
  }
  void init( int n ){
    par.resize( n );
    for(int i=0;i<n;i++)par[i] = i;
  }
  int find( int x ){
    if( par[x] == x ) return x;
    return par[x] = find( par[x] );
  }
  bool unite( int x , int y ){
    x = find(x);
    y = find(y);
    if( x == y ) return false;
    par[x] = y;
    return true;
  }
  bool same( int x , int y ){
    return find(x) == find(y);
  }
} uf;

struct Heap{
  Heap *l, *r;
  int add, v, id;
  Heap(){}
  Heap( int v , int id ) : l(NULL) , r(NULL) , add(0) , v(v) , id(id) {}
};
void lazy( Heap *a ){
  if( a->l ) a->l->add += a->add;
  if( a->r ) a->r->add += a->add;
  a->v += a->add;
  a->add = 0;
}
Heap* meld( Heap *a , Heap *b ){
  if( !a ) return b;
  if( !b ) return a;
  if( a->v + a->add > b->v + b->add ) swap( a , b );
  lazy( a );
  a->r = meld( a->r , b );
  swap( a->l , a->r );
  return a;
}
Heap* pop( Heap *a ){
  lazy( a );
  return meld( a->l , a->r );
}
Heap pool[10000010];
int it;
struct edge{
  ll to,cost;
};

struct edge2{
  ll from, to, cost;
};

int n, m;
bool kouho[MAX_V];

vector<edge2> edges;

Heap* come[MAX_V];
int used[MAX_V];
int from_cost[MAX_V];
int from[MAX_V];

int MSA( int r ){
  uf.init(n);
  it = 0;
  for(int i=0;i<n;i++){
    used[i] = 0;
    come[i] = NULL;
  }
  used[r] = 2;
  for(int i=0;i<edges.size();i++){
    edge2 &e = edges[i];
    pool[it] = Heap( e.cost , i );
    come[e.to] = meld( come[e.to] , &pool[it++] );
  }

  int res = 0;
  for(int start = 0;start<n;start++){
    if( used[start] != 0 ) continue;
    int cur = start;
    vi processing(0);
    
    while( used[cur] != 2 ){
      used[cur] = 1;
      processing.pb( cur );
      
      if( !come[cur] ) return INF;
      
      from[cur] = uf.find( edges[ come[cur]->id ].from ); 
      from_cost[cur] = come[cur]->v + come[cur]->add;
      come[cur] = pop( come[cur] );
      if( from[cur] == cur ) continue;
      res += from_cost[cur];
      
      if( used[ from[cur] ] == 1 ){
	int p = cur;
      	do {
      	  if( come[p] ) come[p]->add -= from_cost[p];
      	  if( p != cur ){
      	    uf.unite( p , cur );
      	    come[cur] = meld( come[cur] , come[p] );
      	  }
      	  p = uf.find( from[p] );
      	} while( p != cur );

      } else {
	cur = from[cur];
      }
    }
    for( int v : processing ){
      used[v] = 2;
    }
  }
  return res;
}


ll d[MAX_V];
vector<vector<edge>>E(MAX_V),E2(MAX_V);
void dijkstra(ll s){
  priority_queue<pair<ll,pair<ll,pair<ll,ll>>>,vector<pair<ll,pair<ll,pair<ll,ll>>>>,greater<>>que;
  vi hoge(MAX_V);
  fill_n(d,MAX_V,Inf);
  d[s] = 0;
  que.push(mp(0,mp(s,mp(-1,-1))));
  while(!que.empty()){
    pair<ll,pair<ll,pair<ll,ll>>> p = que.top();
    que.pop();
    ll v = p.second.first;
    ll prev = p.second.second.first;
    if(d[v] < p.first)continue;
    if(prev != -1)
      edges.pb({prev,v,E2[prev][p.second.second.second].cost});
    for(int j = 0;j < E[v].size();j++){
      edge t = E[v][j];
      if(d[t.to] >= d[v] + t.cost){
	d[t.to] = d[v] + t.cost;
	que.push(mp(d[t.to],mp(t.to,mp(v,j))));
      }
    }
  }
}


int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  while(cin>>n>>m,n+m){
    for(int i=0;i<n;i++){
      E[i].clear();
      E2[i].clear();
    }
    edges.clear();
    for(int i=0;i<m;i++){
      ll f,t,d,c;
      cin>>f>>t>>d>>c;
      E[--f].pb({--t,d});
      E[t].pb({f,d});
      E2[f].pb({t,c});
      E2[t].pb({f,c});
    }
    dijkstra(0);
    cout<<MSA(0)<<endl;
  }
  return 0;
}



Measured memory_bytes: 9520