Problem:
Problem H:
Road Construction
King Mercer is the king of ACM kingdom. There are one capital and some cities in his kingdom.
Amazingly, there are no roads in the kingdom now. Recently, he planned to construct roads
between the capital and the cities, but it turned out that the construction cost of his plan is
much higher than expected.
In order to reduce the cost, he has decided to create a new construction plan by removing some
roads from the original plan. However, he believes that a new plan should satisfy the following
conditions:
For every pair of cities, there is a route (a set of roads) connecting them.
The minimum distance between the capital and each city does not change from his original
      plan.
Many plans may meet the conditions above, but King Mercer wants to know the plan with
minimum cost. Your task is to write a program which reads his original plan and calculates the
cost of a new plan with the minimum cost.
Input
The input consists of several datasets. Each dataset is formatted as follows.
N M
u
1
v
1
d
1
c
1
.
.
.
u
M
v
M
d
M
c
M
The first line of each dataset begins with two integers,
N
and
M
(1 ≤
N
≤ 10000, 0 ≤
M
≤
20000).
N
and
M
indicate the number of cities and the number of roads in the original plan,
respectively.
The following
M
lines describe the road information in the original plan. The
i
-th line contains
four integers,
u
i
,
v
i
,
d
i
and
c
i
(1 ≤
u
i
,
v
i
≤
N
,
u
i
≠
v
i
, 1 ≤
d
i
≤ 1000, 1 ≤
c
i
≤ 1000).
u
i
,
v
i
,
d
i
and
c
i
indicate that there is a road which connects
u
i
-th city and
v
i
-th city, whose length is
d
i
and whose cost needed for construction is
c
i
.
Each road is bidirectional. No two roads connect the same pair of cities. The 1-st city is the
capital in the kingdom.
The end of the input is indicated by a line containing two zeros separated by a space. You
should not process the line as a dataset.
Output
For each dataset, print the minimum cost of a plan which satisfies the conditions in a line.
Sample Input
3 3
1 2 1 2
2 3 2 1
3 1 3 2
5 5
1 2 2 2
2 3 1 1
1 4 1 1
4 5 1 1
5 3 1 1
5 10
1 2 32 10
1 3 43 43
1 4 12 52
1 5 84 23
2 3 58 42
2 4 86 99
2 5 57 83
3 4 11 32
3 5 75 21
4 5 23 43
5 10
1 2 1 53
1 3 1 65
1 4 1 24
1 5 1 76
2 3 1 19
2 4 1 46
2 5 1 25
3 4 1 13
3 5 1 65
4 5 1 34
0 0
Output for the Sample Input
3
5
137
218

Submitted solutions:

code_snippet: #include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxv=10002;
struct edge{int en,dis,cost;};
typedef pair<int,int> P;
int main(){
    int scost[maxv];
    int n,m;
    while(scanf("%d%d",&n,&m)==2&&(n||m)){
        memset(scost,0x3f,sizeof(scost));
        int d[maxv];
        vector<edge> q[maxv];
        for(int i=0;i<m;i++){
            int a,b,c,d;
            scanf("%d%d%d%d",&a,&b,&c,&d);
            q[a].push_back({b,c,d});
            q[b].push_back({a,c,d});
        }
        memset(d,0x3f,sizeof(d));
        d[1]=0;
        priority_queue<P,vector<P>,greater<P>> Q;
        Q.push({d[1],1});
        scost[1]=0;
        while(!Q.empty()){
            P M=Q.top(); Q.pop();
            int u=M.first;
            int v=M.second;
            if(d[v]<u) continue;
            for(int i=0;i<(int)q[v].size();i++){
                int e=q[v][i].en,c=q[v][i].cost,di=q[v][i].dis;
                if(d[e]>d[v]+di){
                    d[e]=d[v]+di;
                    Q.push({d[e],e});
                    scost[e]=c;
                }else if(d[e]==d[v]+di){
                    scost[e]=min(scost[e],c);
                }
            }
        }
        long long sum=0;
        for(int i=1;i<=n;i++){
            sum+=scost[i];
        }
        printf("%lld\n",sum);
    }
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 4500
final_rank: 4

code_snippet: #include <cstdio>
#include <queue>
#include <iostream>
#include <cstring>

using namespace std;

typedef pair<int ,int> pii;

priority_queue<pii, vector<pii>, greater<pii> > pq;

int d[10010];

struct E{
  E() {}
  E(int vv, int cc, int ww): v(vv), c(cc), w(ww) {}
  int v, c, w;
};

vector<E> e[10010];
int pre[10010];

void Dijkstra(int n, int s, int d[], vector<E> e[]) {
  memset(d + 1, 0x3f, sizeof(int) * n);
  pq.push(make_pair(d[s]=0, s));
  while(!pq.empty()) {
    int u, v, c, m;
    m = pq.top().first;
    u = pq.top().second;
    pq.pop();
    if(m > d[u]) {
      continue;
    }
    for(vector<E>::iterator it = e[u].begin(); it != e[u].end(); ++it){
      const E &edge = *it;
      v = edge.v;
      c = edge.c;
      int t = d[u] + c;
      if(t < d[v]) {
        pq.push(make_pair(d[v]=t, v));
        pre[v] = edge.w;
      } else if(t == d[v]) {
        pre[v] = min(pre[v], edge.w);
      }
    }
  }
}

int main() {
  int n, m, u, v, c, w;

  while(scanf("%d%d", &n, &m) != EOF && n) {
    for(u = 1; u <= n; ++u) {
      e[u].clear();
    }
    while (m--) {
      scanf("%d%d%d%d", &u, &v, &c, &w);
      e[u].push_back(E(v, c, w));
      e[v].push_back(E(u, c, w));
    }
    Dijkstra(n, 1, d, e);

    int ans = 0;
    for (u = 2; u <= n; ++u) {
      ans += pre[u];
    }
    printf("%d\n", ans);
  }
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 5628
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;

struct edge{
  int to,d,c;
  edge(int x,int y,int z):to(x),d(y),c(z){}
};

int main(){
  while(1){
    int N,M;
    scanf("%d%d",&N,&M);
    if(N==0&&M==0) break;
    vector<vector<edge>> G(N);
    for(int i=0;i<M;i++){
      int u,v,d,c;
      scanf("%d%d%d%d",&u,&v,&d,&c);
      u--;v--;
      G[u].push_back(edge(v,d,c));
      G[v].push_back(edge(u,d,c));
    }

    priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> pq;
    vector<int> dist(N,1e9);
    dist[0] = 0;
    pq.emplace(0,0);
    while(pq.size()){
      auto[d,v] = pq.top();
      pq.pop();
      if(dist[v]<d) continue;
      for(auto [nv,nd,_] : G[v]){
        int cand = d+nd;
        if(dist[nv]>cand){
          dist[nv]=cand;
          pq.emplace(cand,nv);
        }
      }
    }

    vector<vector<int>> H(N);
    int ans = 0;
    for(int v=0;v<N;v++){
      for(auto[nv,nd,nc] : G[v]){
        if(dist[v]+nd==dist[nv]){
          H[nv].emplace_back(nc);
        }
      }
    }
    for(int v=0;v<N;v++){
      if(H[v].empty()) continue;
      ans += *min_element(H[v].begin(),H[v].end());
    }
    printf("%d\n",ans);


  }
}
accuracy: 1
time_ms: 50
memory_kb: 4500
final_rank: 4

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;
const int N = 10100;
const int INF = 99999999;
typedef struct Edge
{
    int to, dis, cost;
    Edge(int t=0, int d=0, int c=0) : to(t), dis(d), cost(c) {}
    bool operator >(const Edge &t) const
    {
        return dis != t.dis ? dis > t.dis : cost > t.cost;
    }
}P;
vector<Edge> G[N];
int d[N];
int V, E;
bool vis[N];

priority_queue<P, vector<P>, greater<P> > que;
    
int Dijkstra(int s)
{
    int res = 0;
    memset(vis, 0, sizeof(vis));
    que.push(P(s, 0, 0));
    while (!que.empty())
    {
        P p = que.top(); que.pop();
        int v = p.to;
        if (vis[v])  continue;
        vis[v] = 1;
        res += p.cost;
        for (int i = 0; i < G[v].size(); ++i)
        {
            Edge e = G[v][i];
            que.push(P(e.to, e.dis + p.dis, e.cost));
        }
    }
    return res;
}
int main()
{
    int f, t, c, d;
    while (cin >> V >> E)
    {
        if (!V && !E)   break;
        for (int i = 0; i < V; ++i)
            G[i].clear();
        for (int i = 0; i < E; ++i)
        {
            cin >> f >> t >> d >> c;
            --f, --t;
            G[f].push_back(Edge(t, d, c));
            G[t].push_back(Edge(f, d, c));
        }
        cout << Dijkstra(0) << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 5204
final_rank: 10

code_snippet: #include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <cstdio>
#include <cmath>
#include <string>
#include <stack>
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
#define E exp(double(1))
#define maxn 51000
using namespace std;

struct Edge{
    int from,to,dis,next;
    int w;
} edge[maxn];

int b[maxn];
int head[maxn];
int vis[maxn];
int dis[maxn];
int tt[maxn];
int p[maxn];
int cnt;
int n;
int ll;
void add(int q,int h,int len,int w) {
    edge[cnt].from=q;
    edge[cnt].to=h;
    edge[cnt].dis=len;
    edge[cnt].w=w;
    edge[cnt].next=head[q];
    head[q]=cnt;
    cnt++;
}

vector<int>vct[maxn];

int Dijkstra(){
	int i,j,k,tmp,v;
	int flag;
	int yy;
	memset(dis,inf,sizeof(dis));
	memset(vis,0,sizeof(vis));
	memset(tt,0,sizeof(tt));
	memset(p,0,sizeof(p));
	dis[1]=0;
	vis[1]=1;
	int next;
	int s=1;
	yy=0;
	for(int i=0;i<maxn;i++) vct[i].clear();
	while(1){
		tmp=inf;
		next=-1;
		for(int i=head[s]; i!=-1; i=edge[i].next){
            v=edge[i].to;
            if(vis[v])continue;
            if(edge[i].dis+dis[s]<dis[v]){
                dis[v]=edge[i].dis+dis[s];
                tt[v]=edge[i].w;
                p[v]=1;
                vct[v].clear();
                vct[v].push_back(i);
            }else if(edge[i].dis+dis[s]==dis[v]){
                tt[v]=max(tt[v],edge[i].w);
                p[v]++;
                vct[v].push_back(i);
            }
		}
        for(int i=1;i<=n;i++){
            if(vis[i])continue;;
            if(dis[i]<tmp){
                tmp=dis[i];
                next=i;
            }
        }
		if(next==-1)break;

		for(i=0;i<vct[next].size();i++){
         //   printf("%d __>  %d\n",edge[vct[next][i]].from,edge[vct[next][i]].to);
            if(b[vct[next][i]])continue;
            ll+=edge[vct[next][i]].w;
            b[vct[next][i]]=1;
		}
		vis[next]=1;
		s=next;
		if(p[next]>=2){
            yy+=tt[next];
		}
	}
	return yy;
}



int main(){
    int m;
    int q,h,len,w,i,j;
    int ans;
    int ff;
    while(scanf("%d%d",&n,&m)!=EOF,n+m){
        ll=0;
        cnt=0;
        memset(b,0,sizeof(b));
        memset(head,-1,sizeof(head));
        for(i=0;i<m;i++){
            scanf("%d%d%d%d",&q,&h,&len,&w);
            add(q,h,len,w);
            add(h,q,len,w);
        }

        ff=Dijkstra();
     //   printf("%d\n",ll);
        printf("%d\n",ll-ff);
    }
    return 0;
}
accuracy: 1
time_ms: 880
memory_kb: 6956
final_rank: 20

code_snippet: // 最小树形图：POJ3164
// 给有向带权图中指定一个特殊的点root，
// 求一棵以root为根的有向生成树T，并且T中所有边的总权值最小

#include <iostream>
#include <cstdio>
#include <cstring>
#include <sstream>
#include <algorithm>
#include <cmath>
#include <map>
#include <functional>
#include <queue>
#include <vector>
#include <cstdlib>
#include <string>
using namespace std;
const int N=10010;
const int INF=1000000000;
const int eps=1e-8;
struct Node
{
    int u,v,w,c,next;
}e[1000000];
int head[N],cnt;
void add(int u,int v,int w)
{
    e[cnt].u=u;e[cnt].v=v;e[cnt].w=w;
    cnt++;
}
void Add(int u,int v,int w,int c)
{
    e[cnt].u=u;e[cnt].v=v;e[cnt].w=w;e[cnt].c=c;e[cnt].next=head[u];
    head[u]=cnt++;
}
int In[N],x[N],y[N];
int pre[N],ID[N],vis[N];
int n,m;
int dis[N],in[N];
queue<int>q;
void spfa()
{
    for(int i=1;i<=n;i++)
        dis[i]=INF,in[i]=0;
    dis[1]=0;q.push(1);
    while(!q.empty())
    {
        int u=q.front();q.pop();in[u]=0;
        for(int i=head[u];i!=-1;i=e[i].next)
        {
            int v=e[i].v;
            if(dis[v]>dis[u]+e[i].w)
            {
                dis[v]=dis[u]+e[i].w;
                if(!in[v])
                {
                    in[v]=1;q.push(v);
                }
            }
        }
    }
}
int MST(int rot)
{
    int ret=0;
    int V=n,E=cnt,now,u,v;  // V 当前点的个数     E 当前边的个数
    while(1)
    {
        //1.找最小入边
        for(int i=1;i<=V;i++)
            vis[i]=ID[i]=-1,In[i]=INF;
        for(int i=0;i<E;i++)
        {
            u=e[i].u,v=e[i].v;
            if(In[v]>e[i].w && u!=v)
            {
                pre[v]=u;
                In[v]=e[i].w;
            }
        }

        for(int i=1;i<=V;i++)
            if(i!=rot&&In[i]>=INF)
                return -1;//除了跟以外有点没有入边,则根无法到达它

        //2.找环
        now=0;In[rot]=0;
        for(int i=1;i<=V;i++)
        {
            ret+=In[i];
            v=i;
            while( vis[v]!=i && v!=rot && ID[v]==-1 ) // pre[v] 可能是在另一个环内
            {
                vis[v]=i;
                v=pre[v];
            }
            if( v!=rot && ID[v]==-1 ) // 找到环
            {
                now++; //标记每个环
                for( u=pre[v]; u!=v; u=pre[u])
                    ID[u]=now;
                ID[v]=now;
            }
        }
        if(now==0) //无环
            return ret;
        for(int i=1;i<=V;i++)
            if(ID[i]==-1)
                ID[i]=++now;
        V=now;rot=ID[rot]; // 更新 V 和 rot

        //3.缩点,重新标记
        cnt=0;
        for(int i=0;i<E;i++)
        {
            v=e[i].v;u=e[i].u;
            if(ID[u]!=ID[v])
                add(ID[u],ID[v],e[i].w-In[v]); //重新建边
        }
        E=cnt;
    }
    return ret;
}
void build()
{
    int now=cnt;
    cnt=0;
    for(int i=0;i<now;i++)
    {
        int u=e[i].u,v=e[i].v;
        if(dis[v]==dis[u]+e[i].w&&u!=v&&v!=1)
        {
            add(u,v,e[i].c);
        }
    }
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0)break;
        memset(head,-1,sizeof(head));
        cnt=0;
        for(int i=0;i<m;i++)
        {
            int u,v,w,d;
            scanf("%d%d%d%d",&u,&v,&w,&d);
            Add(u,v,w,d);Add(v,u,w,d);
        }
        spfa();
        build();
        int ans=MST(1);
        printf("%d\n",ans);
    }
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 4320
final_rank: 2

code_snippet: #include<iostream>
#include<queue>
#include<vector>
#include<math.h>
#include<string.h>
using namespace std;
#define MAX_N 10005
const int INF=0x3f3f3f3f;
typedef pair<int,int> P;

struct edge{int to,dist,cost;};
vector<edge> G[MAX_N];
int d[MAX_N];
int N,M;
int ans;

void dijkstra(int s)
{
	priority_queue<P,vector<P>,greater<P>> que;
	fill(d,d+N+1,INF);
	d[s]=0;
	que.push(P(0,s));
	
	while(!que.empty())
	{
		P p=que.top();que.pop();
		int v=p.second;
		if(d[v]<p.first) continue;
		for(int i=0;i<G[v].size();++i)
		{
			 edge e=G[v][i];
			 if(d[e.to]>d[v]+e.dist)
		   {
		   	   d[e.to]=d[v]+e.dist;
		   	   que.push(P(d[e.to],e.to));
		   }
		}
	}
}
int main()
{
	int U,V,D,C;
	while(~scanf("%d%d",&N,&M)&&(N||M))
	{
		ans=0;
		for(int i=0;i<M;++i)
		{
			scanf("%d%d%d%d",&U,&V,&D,&C);
            G[U].push_back((edge){V,D,C});
            G[V].push_back((edge){U,D,C});		  
		}
		dijkstra(1);
        for(int i=2;i<=N;++i)
        {
        	int min_cost=INF;
        	for(int j=0;j<G[i].size();++j)
        	{
        		edge e=G[i][j];
        		if(d[e.to]+e.dist==d[i]&&e.cost<min_cost)
        		{
        			min_cost=e.cost;
				}
			}
			ans+=min_cost;
		}
		printf("%d\n",ans);
		for(int i=1;i<=N;++i)
		G[i].clear();
	}
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 5584
final_rank: 17

code_snippet: #include <algorithm>
#include <cstdio>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;

const int INF = 0x3f3f3f3f;
struct edge {
  int to, cost, c;
};
typedef pair<int, int> P;
int d[10010], N, M;
P pre[10010];
vector<edge> G[10010];  // 索引from

void dijkstra() {
  memset(d, INF, sizeof(d));
  priority_queue<P, vector<P>, greater<P> > que;
  d[1] = 0;
  que.push(P(0, 1));
  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int v = p.second;
    if (d[v] < p.first) continue;
    for (int i = 0; i < G[v].size(); ++i) {
      edge e = G[v][i];
      int new_dist = d[v] + e.cost;
      if (d[e.to] > new_dist) {
        d[e.to] = new_dist;
        que.push(P(d[e.to], e.to));
        pre[e.to].first = v;
        pre[e.to].second = i;
      } else if (d[e.to] == new_dist) {
        // 检查当前边的成本是否更小
        if (pre[e.to].first == 0) { // 初始未被设置的情况
          pre[e.to].first = v;
          pre[e.to].second = i;
        } else {
          int current_c = G[pre[e.to].first][pre[e.to].second].c;
          if (e.c < current_c) {
            pre[e.to].first = v;
            pre[e.to].second = i;
          }
        }
      }
    }
  }
}

int find_cost() {
  int ans = 0;
  for (int u = 2; u <= N; ++u) {
    ans += G[pre[u].first][pre[u].second].c;
  }
  return ans;
}

int main() {
  int u, v, dd, c;
  while (scanf("%d %d", &N, &M) == 2 && N + M) {
    for (int i = 1; i <= N; ++i)  G[i].clear();
    for (int i = 1; i <= M; ++i) {
      scanf("%d %d %d %d", &u, &v, &dd, &c);
      G[u].push_back({v, dd, c});
      G[v].push_back({u, dd, c});
    }
    memset(pre, 0, sizeof(pre));
    dijkstra();
    printf("%d\n", find_cost());
  }
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 5120
final_rank: 8

code_snippet: #include<iostream>
#include<cstring>
using namespace std;
const int N=10000+10,M=20000+10;
int n,m;
int dist[N],cost[N],idx;
struct edge{
	int u;
	int v;
	int w;
	int cost;
}e[2*M];
void add(int u,int v,int w,int c)
{
	e[idx].u=u;
	e[idx].v=v;
	e[idx].w=w;
	e[idx].cost=c;
	++idx;
}
void solve()
{
	while(true)
	{
		bool update=false;
		for(int i=0;i<2*m;++i)
		{
			int x=e[i].u;
			int y=e[i].v;
			int w=e[i].w;
			int c=e[i].cost;
			if(dist[x]+w<dist[y])
			{
				dist[y]=dist[x]+w;
				cost[y]=cost[x]+c;
				update=true;
			}
			else if(dist[x]+w==dist[y])
				cost[y]=min(c,cost[y]);
		}
		if(!update)
			break;
	}
} 
int main()
{
	while(cin>>n>>m&&n)
	{
		memset(e,0,sizeof e);
		idx=0;
		memset(dist,0x3f,sizeof dist);
		memset(cost,0x3f,sizeof cost);
		dist[1]=cost[1]=0;
		for(int i=1;i<=m;++i)
		{
			int u,v,d,c;
			cin>>u>>v>>d>>c;
			add(u,v,d,c);
			add(v,u,d,c);
		}
		solve();
		int sum=0;
		for(int i=2;i<=n;++i)
			sum+=cost[i];
		cout<<sum<<endl;
	}
	
	return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 4120
final_rank: 1

code_snippet: // #define _GLIBCXX_DEBUG
//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
//#pragma GCC optimize("trapv")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 

using namespace std;

template<class T> using ordered_set = __gnu_pbds::tree<T,
    __gnu_pbds::null_type,
    less<T>,
    __gnu_pbds::rb_tree_tag,
    __gnu_pbds::tree_order_statistics_node_update>;

#define int long long
#define endl '\n'
#define all(v) v.begin(), v.end()

#ifdef LOCAL
#define debug(x) cout << __LINE__ << ": " << (#x) << " = " << (x) << endl
#else
#define debug(x)
#endif

#ifdef LOCAL
#define debug_vec(x)                           \
    cout << __LINE__ << ": " << (#x) << " = "; \
    for (auto &y : x)                          \
        cout << y << " ";                      \
    cout << endl;
#else
#define debug_vec(x)
#endif


using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

auto now_rand = chrono::high_resolution_clock::now();
mt19937 rnd(now_rand.time_since_epoch().count());

const ll mod = 1e9 + 7;
int n, m;

struct edge {
    int u, dist, c;
    bool operator>(const edge& oth) const {
        if (dist == oth.dist)
            if (c == oth.c)
                return u > oth.u;
            else
                return c > oth.c;
        return dist > oth.dist;
    }
};

inline void solve() {
    vector<vector<edge>> g(n + 1);
    for (auto i = 0; i < m; ++i) {
        int u, v, dist, c;
        cin >> u >> v >> dist >> c;
        g[u].push_back({ v, dist, c });
        g[v].push_back({ u, dist, c });
    }
    priority_queue<edge, vector<edge>, greater<edge>> s;
    s.push({ 1, 0, 0 }); // dist, c
    vector<int> used(n + 1, 1e9);
    int ans = 0;
    while (!s.empty()) {
        auto [v, dist, c] = s.top();
        s.pop();
        if (dist >= used[v])
            continue;
        used[v] = dist;
        ans += c;
        for (auto const& [u, dist1, c1] : g[v]) {
            if (used[u] > used[v] + dist1) {
                s.push({ u, used[v] + dist1, c1 });
            }
        }
    }
    cout << ans << '\n';
}

signed main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(10);
    cin >> n >> m;
    while (n) {
        solve();
        cin >> n >> m;
    }
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 5504
final_rank: 15

code_snippet: // #define _GLIBCXX_DEBUG
//#pragma GCC optimize("O3,unroll-loops")
//#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
//#pragma GCC optimize("trapv")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 

using namespace std;

template<class T> using ordered_set = __gnu_pbds::tree<T,
    __gnu_pbds::null_type,
    less<T>,
    __gnu_pbds::rb_tree_tag,
    __gnu_pbds::tree_order_statistics_node_update>;

#define int long long
#define endl '\n'
#define all(v) v.begin(), v.end()

#ifdef LOCAL
#define debug(x) cout << __LINE__ << ": " << (#x) << " = " << (x) << endl
#else
#define debug(x)
#endif

#ifdef LOCAL
#define debug_vec(x)                           \
    cout << __LINE__ << ": " << (#x) << " = "; \
    for (auto &y : x)                          \
        cout << y << " ";                      \
    cout << endl;
#else
#define debug_vec(x)
#endif


using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

auto now_rand = chrono::high_resolution_clock::now();
mt19937 rnd(now_rand.time_since_epoch().count());

const ll mod = 1e9 + 7;
int n, m;

struct edge {
    int u, dist, c;
    bool operator<(const edge& oth) const {
        if (dist == oth.dist)
            if (c == oth.c)
                return u < oth.u;
            else
                return c < oth.c;
        return dist < oth.dist;
    }
};

inline void solve() {
    vector<vector<edge>> g(n + 1);
    for (auto i = 0; i < m; ++i) {
        int u, v, dist, c;
        cin >> u >> v >> dist >> c;
        g[u].push_back({ v, dist, c });
        g[v].push_back({ u, dist, c });
    }
    set<edge> s;
    s.insert({ 1, 0, 0 }); // dist, c
    vector<int> used(n + 1, 1e9);
    int ans = 0;
    while (!s.empty()) {
        auto [v, dist, c] = *s.begin();
        s.erase(s.begin());
        if (dist >= used[v])
            continue;
        used[v] = dist;
        ans += c;
        for (auto const& [u, dist1, c1] : g[v]) {
            if (used[u] > used[v] + dist1) {
                s.insert({ u, used[v] + dist1, c1 });
            }
        }
    }
    cout << ans << '\n';
}

signed main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(10);
    cin >> n >> m;
    while (n) {
        solve();
        cin >> n >> m;
    }
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 5528
final_rank: 16

code_snippet: #include<bits/stdc++.h>
// #include<atcoder/all>
// #include<boost/multiprecision/cpp_int.hpp>

using namespace std;
// using namespace atcoder;
// using bint = boost::multiprecision::cpp_int;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using P = pair<ll,ll>;
using vi = vector<ll>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using ve = vector<vector<int>>;
using vb = vector<bool>;
using vvb = vector<vb>;
#define rep(i,n) for(ll i = 0;i < (ll)n;i++)
#define ALL(x) (x).begin(),(x).end()
#define sz(c) ((ll)(c).size())
#define LB(A,x) (int)(lower_bound(A.begin(),A.end(),x)-A.begin())
#define UB(A,x) (int)(upper_bound(A.begin(),A.end(),x)-A.begin())
// #define MOD 1000000007
#define MOD 998244353
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
template<typename T>ostream&operator<<(ostream&os,vector<T>&v){for(int i = 0;i < v.size();i++)os<<v[i]<<(i+1!=v.size()?" ":"");return os;}
template<typename T>istream&operator>>(istream&is,vector<T>&v){for(T&in:v)is>>in;return is;}
template<typename T1,typename T2>ostream&operator<<(ostream&os,pair<T1,T2>&p){os<<p.first<<" "<<p.second;return os;}
template<typename T1,typename T2>istream&operator>>(istream&is,pair<T1,T2>&p){is>>p.first>>p.second;return is;}
template<typename T> inline bool chmax(T &a,T b){if(a < b){a = b;return true;}return false;}
template<typename T> inline bool chmin(T &a,T b){if(a > b){a = b;return true;}return false;}
ld dist(ld x1,ld y1,ld x2, ld y2){return sqrtl((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}

const ll inf = 1ll << 50;

bool solve(){
  int n,m;cin >> n >> m;
  if(!n)return false;
  vector<vector<tuple<ll,ll,ll>>> v(n);
  rep(i,m){
    int a,b,d,c;cin >> a >> b >> d >> c;
    a--;b--;
    v[a].emplace_back(make_tuple(b,d,c));
    v[b].emplace_back(make_tuple(a,d,c));
  }
  min_priority_queue<tuple<ll,ll,int>> que;
  que.push({0,0,0});
  vector<P> d(n,{inf,inf});
  d[0] = {0,0};
  while(!que.empty()){
    auto [od,oc,ov] = que.top();que.pop();
    if(make_pair(od,oc) > d[ov])continue;
    for(auto [nv,nd,nc] : v[ov]){
      if(d[nv] <= make_pair(od+nd,nc))continue;
      d[nv] = make_pair(od+nd,nc);
      que.push({od+nd,nc,nv});
    }
  }
  ll res = 0;
  rep(i,n)res += d[i].second;
  cout << res << "\n";

  return true;
}

int main(){
  
  ios_base::sync_with_stdio(0), cin.tie(0);
  while(solve());
  

  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 5244
final_rank: 9

code_snippet: #ifdef t9unkubj
#include"debug.cpp"
//#include"template_no_debug.h"
#else 
#define dbg(...) 199958
#endif

#undef _GLIBCXX_DEBUG
#pragma GCC optimize("O3")
using namespace std;
#include<bits/stdc++.h>
using ll=long long;
using ull=unsigned long long;
template<class T>using vc=vector<T>;
template<class T>using vvc=vc<vc<T>>;
#define rep(i,n) for(ll i=0;i<(ll)(n);i++)
#define REP(i,j,n) for(ll i=(j);i<(ll)(n);i++)
#define DREP(i,n,m) for(ll i=(n);i>=(m);i--)
#define drep(i,n) for(ll i=((n)-1);i>=0;i--)
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
template<class T,class F>
bool chmin(T &x, F y){
    if(x>y){
        x=y;
        return true;
    }
    return false;
}
template<class T, class F>
bool chmax(T &x, F y){
    if(x<y){
        x=y;
        return true;
    }
    return false;
}
double pass_time=0;
void solve(){
    while(1){
        int n,m;
        cin>>n>>m;
        if(n==0&&m==0)break;
        vvc<array<int,3>>g(n);
        rep(i,m){
            int u,v,d,c;
            cin>>u>>v>>d>>c;
            --u,--v;
            g[u].push_back({v,d,c});
            g[v].push_back({u,d,c});
        }
        vc<int>md(n,1e9);
        md[0]=0;
        using T=pair<int,int>;
        priority_queue<T,vc<T>,greater<>>que;
        que.push({0,0});
        while(que.size()){
            auto [p,q]=que.top();que.pop();
            if(md[q]!=p)continue;
            for(auto&[to,len,cost]:g[q]){
                if(chmin(md[to],md[q]+len)){
                    que.push({md[to],to});
                }
            }
        }
        ll ans=0;
        REP(i,1,n){
            ll res=2e9;
            for(auto&[to,len,cost]:g[i]){
                if(md[to]+len==md[i]){
                    chmin(res,cost);
                }
            }
            ans+=res;
        }
        cout<<ans<<endl;
    }
}
signed main(){
    cin.tie(0)->sync_with_stdio(0);
    pass_time=clock();
    int t=1;
    //cin>>t;
    while(t--)solve();
    pass_time=clock()-pass_time;
    dbg(pass_time/CLOCKS_PER_SEC);
}
accuracy: 1
time_ms: 50
memory_kb: 4408
final_rank: 3

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
while(1) {
    int N, M;
    cin >> N >> M;
    if (N == 0) return 0;
    vector<int> A(M), B(M), D(M), C(M);
    rep(i,0,M) cin >> A[i] >> B[i] >> D[i] >> C[i], A[i]--, B[i]--;
    vector<vector<pair<int,int>>> G(N);
    rep(i,0,M) {
        G[A[i]].push_back({B[i],D[i]});
        G[B[i]].push_back({A[i],D[i]});
    }
    vector<int> DP(N,inf);
    priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> PQ;
    DP[0] = 0;
    PQ.push({0,0});
    while(!PQ.empty()) {
        auto [D,V] = PQ.top();
        PQ.pop();
        for (auto E : G[V]) {
            int ND = D + E.second, NV = E.first;
            if (chmin(DP[NV],ND)) {
                PQ.push({ND,NV});
            }
        }
    }
    vector<int> ord(M);
    iota(ALL(ord),0);
    sort(ALL(ord),[&](int i, int j){return C[i] < C[j];});
    int ANS = 0;
    vector<bool> used(N,false);
    for (int i : ord) {
        int X = A[i], Y = B[i];
        if (abs(DP[X]-DP[Y]) != D[i]) continue;
        if (DP[X] > DP[Y]) swap(X,Y);
        if (used[Y]) continue;
        used[Y] = true;
        ANS += C[i];
    }
    cout << ANS << endl;
}
}
accuracy: 1
time_ms: 110
memory_kb: 4796
final_rank: 7

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
#include <unordered_set>
#include <functional>
using namespace std;
//using namespace atcoder;
using ll = long long;
using P = pair<int, int>;
#define rep(i, n) for (int i = 0; i < (n); i++)
//void chmin(ll & a, ll b) { a = min(a, b); }
//using mint = modint998244353;
//using mint = modint1000000007;

struct edge {
	int v;
	ll w;
	ll cost;
	edge() {};
	edge(int v,ll w, ll cost):v(v),w(w),cost(cost){}
};

vector<ll> dijkstra(int n, vector<vector<edge>>& G, int s) {
	vector<ll> d(n, LLONG_MAX / 10);
	d[s] = 0;
	priority_queue<pair<ll, int>, vector<pair<ll,int>>, greater<pair<ll,int>>> que;
	que.push(make_pair(0ll, s));
	while (!que.empty()) {
		auto p = que.top();
		que.pop();
		int u = p.second;
		ll dist = p.first;
		if (dist > d[u]) continue;
		for (edge e : G[u]) {
			if (d[e.v] > d[u] + e.w) {
				d[e.v] = d[u] + e.w;
				que.push(make_pair(d[e.v], e.v));
			}
		}
	}
	return d;
}


int main() {
	int N, M;
	while (cin >> N >> M) {
		if (N == 0 && M == 0)break;
		vector<vector<edge>> G(N);
		while (M--) {
			int u, v, d, c;
			cin >> u >> v >> d >> c;
			u--, v--;
			G[u].emplace_back(v, d, c);
			G[v].emplace_back(u, d, c);
		}
		auto dist = dijkstra(N, G, 0);
		ll ans = 0;
		for (int i = 1; i < N; i++) {
			ll mini = 101010;
			for (edge e : G[i]) {
				if (dist[i] == dist[e.v] + e.w) {
					mini = min(mini, e.cost);
				}
			}
			ans += mini;
		}
		cout << ans << endl;
	}
}
accuracy: 1
time_ms: 110
memory_kb: 5260
final_rank: 11

code_snippet: #include <iostream>
#include <algorithm>
#include <tuple>
using namespace std;
typedef tuple<int, int, int, int> tu;

const int INF = (int)1e9;
const int MAX_N = 10000, MAX_M = 20000;

tu edges[MAX_M];
int d[MAX_N];
int N, M, ui, vi, di, ci;

int main() {
    while (cin >> N >> M) {
        if (N == 0 && M == 0)
            break;
        for (int i = 0; i < M; i++) {
            cin >> ui >> vi >> di >> ci;
            ui--; vi--;
            edges[i] = make_tuple(ci, di, ui, vi);
        }
        sort(edges, edges + M);
        fill(d, d + N, INF);
        bool update = true;
        int res = 0;
        d[0] = 0;
        while (update) {
            update = false;
            int tmp1, tmp2, tmp3 = INF, tmp4, tmp5;
            for (int i = 0; i < M; i++) {
                int& s = get<2>(edges[i]), g = get<3>(edges[i]), dt = get<1>(edges[i]), ct = get<0>(edges[i]);
                if (d[s] != INF && d[g] > d[s] + dt && d[s] + dt < tmp3) {
                    update = true;
                    tmp1 = s; tmp2 = g; tmp3 = d[s] + dt; tmp4 = dt; tmp5 = ct;
                }
                if (d[g] != INF && d[s] > d[g] + dt && d[g] + dt < tmp3) {
                    update = true;
                    tmp1 = s; tmp2 = g; tmp3 = d[g] + dt; tmp4 = dt; tmp5 = ct;
                }
            }
            if (update) {
                d[tmp1] = min(d[tmp1], d[tmp2] + tmp4);
                d[tmp2] = min(d[tmp2], d[tmp1] + tmp4);
                res += tmp5;
            }
        }
        cout << res << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 3410
memory_kb: 3408
final_rank: 19

code_snippet: #include <algorithm>
#include <cctype>
#include <climits>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;

const int INF = INT_MAX;

//Graph
struct edge{int to, distance, cost;};
class Graph{
private:
  vector<vector<edge>>neighbors;
  vector<ll>shortest;
  vector<int>prev;
  vector<ll>prev_cost;
  int V;
  int E;

public:
  Graph(const int n){
    V = n;
    neighbors = vector<vector<edge>>(V);
    shortest = vector<ll>(V, LLONG_MAX);
    prev = vector<int>(V, -1);
    prev_cost = vector<ll>(V, 0);
  };

  void add_edge(const int f, const int t, const int d, const int c=INT_MAX){
    edge e; e.to = t; e.distance = d; e.cost = c;
    neighbors[f].push_back(e);
    E++;
  }

  //
  //Dijkstra Algorithm
  //
  //
  //execute dijkstra algorithm
  typedef pair<ll, int> P;
  void dijkstra(const int s){
    fill(shortest.begin(), shortest.end(), LLONG_MAX);
    fill(prev.begin(), prev.end(), -1);
    priority_queue<P, vector<P>, greater<P>>pque;
    shortest[s] = 0;
    prev_cost[s] = 0;
    pque.push(P(0, s));

    while(!pque.empty()){
      P p = pque.top(); pque.pop();
      if(shortest[p.second] < p.first)continue;
      for(int i = 0; i < neighbors[p.second].size(); i++){
        edge e = neighbors[p.second][i];
        if(shortest[e.to] > shortest[p.second] + e.distance || ((shortest[e.to] == shortest[p.second] + e.distance) && (prev_cost[e.to] > e.cost))){
          shortest[e.to] = shortest[p.second] + e.distance;
          prev[e.to] = p.second;
          prev_cost[e.to] = e.cost;
          pque.push(P(shortest[e.to], e.to));
        }
      }
    } 
  }

  //Bellman-Ford algorithm
  void Bellman_Ford(const int s){
    fill(shortest.begin(), shortest.end(), LLONG_MAX);
    fill(prev.begin(), prev.end(), -1);
    shortest[s] = 0;
    while(true){
      bool updated = false;
      for(int i = 0; i < V; i++){
        for(int j = 0; j < neighbors[i].size(); j++){
          edge e = neighbors[i][j];
          if(shortest[i] != LLONG_MAX && shortest[i] + e.cost < shortest[e.to]){
            shortest[e.to] = shortest[i] + e.cost;
            prev[e.to] = i;
            updated = true;
          }
        }
      }

      if(!updated)break;
    }
  }

  bool find_negative_loop(){
    fill(shortest.begin(), shortest.end(), 0);
    for(int i = 0; i < V; i++){
      for(int j = 0; j < V; j++){
        for(int k = 0; k < neighbors[j].size(); k++){
          edge e = neighbors[j][k];
          if(shortest[j] + e.cost < shortest[e.to]){
            shortest[e.to] = shortest[j] + e.cost;
            if(i == V-1)return true;
          }
        }
      }
    }
    return false;
  }

  //get the shortest path from s to g
  //make sure it is done after algorithm
  ll get_value(const int g){
    return shortest[g];
  }

  ll get_minimum_cost(){
    ll minimum = 0;
    for(int i = 0; i < V; i++)minimum+= prev_cost[i];
    return minimum;
  }

  //get the shortest path route from s to g
  //make sure it is done after algorithm
  vector<int> get_route(const int s, const int g){
    vector<int>routes;
    if(get_value(g) == LLONG_MAX)return routes;

    for(int t = g; prev[t] != -1; t = prev[t])routes.push_back(t);
    routes.push_back(s);
    reverse(routes.begin(), routes.end());
    return routes;
  }

  void printshortest(){
    for(int i = 0; i < V; i++)printf("%lld ", shortest[i]);
    printf("\n");
  }
};




int main(){
  while(true){
    int N, M; scanf("%d%d", &N, &M);
    if(N == 0 && M == 0)break;
    Graph G(N);

    for(int m = 0; m < M; m++){
      int u, v, d, c; scanf("%d%d%d%d", &u, &v, &d, &c);
      G.add_edge(u-1, v-1, d, c);
      G.add_edge(v-1, u-1, d, c);
    }
    G.dijkstra(0);
    printf("%lld\n", G.get_minimum_cost());
  }
}
accuracy: 1
time_ms: 50
memory_kb: 4644
final_rank: 6

code_snippet: #pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx,avx2")
#include <bits/stdc++.h>
#define INF 1000000001LL
#define LNF 1000000000000000001LL
#define MOD 1000000007LL
#define MAX 3001
#define long long long
#define all(x) x.begin(),x.end()
using namespace std;

void dijkstra(int x, vector<pair<int,pair<long,long>>> graph[], vector<long> & vis)
{
    for(int i = 0; i<vis.size(); i++)
        vis[i] = LNF;

    priority_queue<pair<long,int>, vector<pair<long,int>>, greater<pair<long,int>>> pq;

    pq.push({0,x});
    vis[x] = 0;

    while(!pq.empty())
    {
        int x = pq.top().second;
        long d = pq.top().first;
        pq.pop();

        if(vis[x] < d)
            continue;
        
        for(int i = 0; i<graph[x].size(); i++)
        {
            int y = graph[x][i].first;
            int v = graph[x][i].second.first;
            if(d+v < vis[y])
            {
                vis[y] = d+v;
                pq.push({vis[y],y});
            }
        }
    }
}
class UnionFind
{
public:
    vector<int> parent;
    vector<int> cnt;
    void init(int size)
    {
        parent.resize(size);
        cnt.resize(size);
        for(int i = 0; i<size; i++)
        {
            parent[i] = i;
            cnt[i] = 1;
        }
    }
    int find(int x)
    {
        if(parent[x] == x)
            return x;
        return parent[x] = find(parent[x]);
    }
    void merge(int x, int y)
    {
        x = find(x);
        y = find(y);
        if(x == y)
            return;
        if(x < y)
        {
            parent[y] = x;
            cnt[x]+=cnt[y];
        }
        else
        {
            parent[x] = y;
            cnt[y]+=cnt[x];
        }
    }
    bool isUnion(int x, int y)
    {
        x = find(x);
        y = find(y);
        if(x == y)
            return true;
        return false;
    }
};
int main()
{
	ios_base::sync_with_stdio(0); 
    cin.tie(0);
    
    while(true)
    {
        int n,m;
        cin >> n >> m;
        if(n == 0)
            break;
        
        vector<pair<int,pair<long,long>>> graph[n+1];

        for(int i = 0; i<m; i++)
        {
            int a,b,c,d;
            cin >> a >> b >> c >> d;
            graph[a].push_back({b,{c,d}});
            graph[b].push_back({a,{c,d}});
        }
        vector<long> vis(n+1);
        long res = 0;
        dijkstra(1,graph,vis);
        for(int i = 2; i<=n; i++)
        {
            long mn = LNF;
            for(int j = 0; j<graph[i].size(); j++)
            {
                if(vis[i]-graph[i][j].second.first == vis[graph[i][j].first])
                    mn = min(mn,graph[i][j].second.second);
            }
            res+=mn;
        }
        cout << res << "\n";
    }
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 5348
final_rank: 12

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

} // namespace macro

using namespace macro;
#line 1 "cp-library/src/graph/shortest_path.hpp"
// g <- pair < v , cost > 
template < class T >
vector< T > dijkstra(vector<vector<pair<int, T>>> &graph, int s) {
    T INF = numeric_limits< T >::max();
    vector<T> dist(graph.size(), INF);
    priority_queue<pair<T,int>, vector<pair<T,int>>, greater<pair<T,int>>> q;
    q.push({dist[s] = T(0), s});
    while(!q.empty()){
        auto [uc, ui] = q.top(); q.pop();
        if(uc != dist[ui]) continue;
        for(auto [vi, vc] : graph[ui]) if(dist[vi] > uc + vc) 
            q.push({dist[vi] = uc + vc, vi});
    }
    return dist;
}

// g <- pair < v , cost > 
template < class T >
vector< T > dijkstra(vector<vector<pair<int, T>>> &graph, vector<int> &starts) {
    T INF = numeric_limits< T >::max();
    vector<T> dist(graph.size(), INF);
    priority_queue<pair<T,int>, vector<pair<T,int>>, greater<pair<T,int>>> q;
    for(int s : starts) q.push({dist[s] = T(0), s});
    while(!q.empty()){
        auto [uc, ui] = q.top(); q.pop();
        if(uc != dist[ui]) continue;
        for(auto [vi, vc] : graph[ui]) if(dist[vi] > uc + vc) 
            q.push({dist[vi] = uc + vc, vi});
    }
    return dist;
}

// g <- pair < v , cost > 
template < class T >
pair< T, vector<int> > shortest_path(vector<vector<pair<int, T>>> &graph, int s, int t) {
    T INF = numeric_limits< T >::max();
    vector<T> dist(graph.size(), INF);
    vector<int> prev(graph.size(), -1);
    priority_queue<pair<T,int>, vector<pair<T,int>>, greater<pair<T,int>>> q;
    q.push({dist[s] = T(0), s});
    while(!q.empty()){
        auto [uc, ui] = q.top(); q.pop();
        if(uc != dist[ui]) continue;
        for(auto [vi, vc] : graph[ui]) if(dist[vi] > uc + vc) 
            q.push({dist[vi] = uc + vc, vi}), prev[vi] = ui;
    }

    vector<int> path;
    if(dist[t] != INF) {
        for(int v = t; v != -1; v = prev[v]) path.push_back(v);
        reverse(path.begin(), path.end());
    }
    return {dist[t], path};
}
#line 4 "A.cpp"

int solve(int N, int M) {
    vector<vector<pair<int,int>>> G(N);
    vector<vector<tuple<int,int,int>>> H(N);
    vector<tuple<int,int,int,int>> E(M);
    for(auto &[u, v, d, c] : E) {
        u = in(), v = in(), d = in(), c = in(); u--, v--;
        G[u].push_back({v, d});
        G[v].push_back({u, d});
        H[u].push_back({v, d, c});
        H[v].push_back({u, d, c});
    }

    vector<int> dist = dijkstra(G, 0);
    int ans = 0;
    for(int v : rep(N)) if(v != 0) {
        int cost = 1e9;
        for(auto [u, d, c] : H[v]) {
            if(dist[u] + d == dist[v]) {
                chmin(cost, c);
            }
        }
        ans += cost;
    }
    return ans;
}

int main() {
    while(true) {
        int N = in(), M = in();
        if(make_pair(N, M) == make_pair(0, 0)) return 0;
        print(solve(N, M));
    }
}
accuracy: 1
time_ms: 60
memory_kb: 5444
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4 + 5;
typedef pair<int, int> P;
int n, m;
struct edge
{
    int to, cost, w;
};
vector<edge> G[maxn];
int d[maxn], w[maxn];

void solve()
{
    memset(d, 0x3f, sizeof d);
    priority_queue<P, vector<P>, greater<P>> q;
    d[1] = 0;
    q.push({0, 1});
    while (!q.empty())
    {
        P p = q.top();
        q.pop();
        int v = p.second;
        if (d[v] < p.first)continue;
        for (int i = 0; i < G[v].size(); i++)
        {
            edge e = G[v][i];
            if (d[e.to] > d[v] + e.cost)
            {
                d[e.to] = d[v] + e.cost;
                w[e.to] = e.w;
                q.push({d[e.to], e.to});
            }
            else if (d[e.to] == d[v] + e.cost)
            {
                w[e.to] = min(w[e.to], e.w);
            }
        }
    }
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    while (cin >> n >> m && n+m)
    {
        for (int i = 1; i <= n; i++)G[i].clear();
        for (int i = 1; i <= m; i++)
        {
            int u, v, c, d;
            cin >> u >> v >> d >> c;
            G[u].push_back({v, d, c});
            G[v].push_back({u, d, c});
        }
        solve();
        int ans = 0;
        for (int i = 2; i <= n; i++)ans += w[i];
        cout << ans << "\n";
    }
}
accuracy: 1
time_ms: 40
memory_kb: 5416
final_rank: 13