stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
#include <queue>

#include <vector>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <iostream>

#include <algorithm>

const int INF=0x3f3f3f3f;

using namespace std;

struct edge{

    int to,cost,w;

};

int V,d[10005],dis[10005];

vector<edge> G[20005];

typedef pair<int,int> P;

void dijkstra(int s){

    int i,v;

	priority_queue<P,vector<P>,greater<P> >que;

	fill(d,d+V+1,INF);

	fill(dis,dis+V+1,INF);

	d[s]=dis[s]=0;

	que.push(P(0,s));

	while(!que.empty()){

		P p=que.top(); que.pop();

		v=p.second;

		if(d[v]<p.first)

        continue;

		for(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;

                dis[e.to]=e.w;

				que.push(P(d[e.to],e.to));

			}

			else if(d[e.to]==d[v]+e.cost)

            dis[e.to]=min(dis[e.to],e.w);

		}

	}

}

int main(){

    int m,st,en,i,j,x,y,z,q,ans;

    edge temp;

    while(scanf("%d%d",&V,&m)!=EOF&&(V||m)){

        for(i=0;i<=V;i++)

        G[i].clear();

        for(i=0;i<m;i++){

            scanf("%d%d%d%d",&x,&y,&z,&q);

            temp.to=y;temp.cost=z;temp.w=q;

            G[x].push_back(temp);

            temp.to=x;

            G[y].push_back(temp);

        }

        dijkstra(1);

        ans=0;

        for(i=1;i<=V;i++)

        ans+=dis[i];

        printf("%d\n",ans);

    }

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.1153936930861394x):
#include <iostream>

#include <queue>

#include <functional>

#include <cstring>

using namespace std;



struct edge{

    int v, d, c;

    edge(){}

    edge(int v, int d, int c) : v(v),d(d),c(c){}

};



int N, M;

const int INF = 0x3f3f3f3f;

typedef pair<int, int> P;//距?， ?点

int d[10665];



vector<edge> G[10665];



void dijkstra(int s){

    priority_queue<P, vector<P>,greater<P> > que;

    memset(d, INF, sizeof(d));

    d[s] = 0;

    que.push(P(0,s));

    while(!que.empty())

    {

        P p = que.top();

        que.pop();

        int q = p.second;

        if(d[q] < p.first) continue;

        for(int i = 0; i < G[q].size(); i++)

        {

            edge e = G[q][i];

            if(d[e.v] > d[q] + e.d)

            {

                d[e.v] = d[q] + e.d;

                que.push(P(d[e.v], e.v));

            }

        }

    }

}





int main()

{

    while(cin >> N >> M)

    {

        if(!N) break;

        for(int i = 0; i < N; i++)

		{

			G[i].clear();

		}

        for(int i = 0; i < M; i++)

        {

            int u,t,c,d;

            cin >> u >> t >> d >> c;

            u--;t--;

            G[u].push_back(edge(t,d,c));

            G[t].push_back(edge(u,d,c));

        }

        dijkstra(0);

        int ans=0;

        for(int k = 1; k < N; k++)

        {

            int mincost = INF;

            for(int j = 0; j < G[k].size(); j++)

            {

                if(d[G[k][j].v]+G[k][j].d == d[k]

                 && G[k][j].c < mincost)

                    mincost = G[k][j].c;

            }

            ans += mincost;

        }

        cout << ans << endl;

    }

    return 0;

}
// Slower C++ solution:
#include "iostream"

#include "cstring"

#include "cstdio"

#include "queue"

using namespace std;

const int N = 10010;

const int INF = 0x3fffffff;

int pre[N];

struct Edge

{

	int x, y, d, c;

	int next;

	Edge(){}

	Edge(int X, int Y, int D, int C):x(X), y(Y), d(D), c(C){}

}p, q, e[N * 4];

int dis[N], cost[N], vis[N]; 

queue<int> que;

void spfa(int n)

{

	for(int i = 1; i <= n; ++ i){

		dis[i] = INF;

		vis[i] = 0;

	}

	dis[1] = 0;

	cost[1] = 0;

	que.push(1);

	while(!que.empty()){

		int u = que.front();

		vis[u] = 0;

		que.pop();

		for(int i = pre[u]; i != -1; i = e[i].next){

			int v = e[i].y, d = e[i].d, c = e[i].c;

			if(dis[v] > dis[u] + d || (dis[v] == dis[u] + d && cost[v] > c)){

				dis[v] = dis[u] + d;

				cost[v] = c;

				if(!vis[v]){

					vis[v] = 1;

					que.push(v);

				}

			}

		}

	}

} 

int main(void)

{

	int n, m;

	while(scanf("%d %d", &n, &m) && (n || m)){

		memset(pre, -1, sizeof(pre));

		int x, y, d, c;

		int tot = 1;

		for(int i = 1; i <= m; ++ i){

			scanf("%d %d %d %d", &x, &y, &d, &c);

			e[tot] = Edge(x, y, d, c);

			e[tot].next = pre[x];

			pre[x] = tot++;

			e[tot] = Edge(y, x, d, c);

			e[tot].next = pre[y];

			pre[y] = tot++;

		}

		spfa(n);

		int ans = 0;

		for(int i = 1; i <= n; ++ i){

			ans += cost[i];

		}

		cout << ans << endl;

	}

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.4219640066602186x):
#include <cstdio>

#include <cstring>

#include <algorithm>



using namespace std;



constexpr int maxN = 10005;

constexpr int maxM = 400005;



int N, M;



int adj[maxN], gto[maxM], gnxt[maxM], length[maxM], cost[maxM], e;

void add_edge(int u, int v, int d, int c) {

    gto[e] = v; length[e] = d; cost[e] = c; gnxt[e] = adj[u]; adj[u] = e++;

}



void print_edge(int s) {

    printf("%d:", s);

    for (int e = adj[s]; ~e; e = gnxt[e])

        printf(" %d", gto[e]);

    putchar('\n');

}



int dis[maxN], pre[maxN];

int qu[maxN], qh, qt; bool inq[maxN];

void bellman_ford(int s) {

    memset(dis, 0x3f, sizeof dis); dis[s] = 0;

    for (inq[qu[qh = qt = 0] = s] = 1; qh <= qt; inq[qu[qh++ % N]] = 0)

        for (int u = qu[qh % N], e = adj[u], v = gto[e]; ~e; v = gto[e = gnxt[e]])

            if (dis[v] > dis[u] + length[e]) {

                dis[v] = dis[u] + length[e];

                pre[v] = cost[e];

                if (!inq[v]) inq[qu[++qt % N] = v] = 1;

            } else if (dis[v] == dis[u] + length[e]) {

                pre[v] = min(pre[v], cost[e]);

            }

}



int main() {

    while (~scanf("%d%d", &N, &M) && (N || M)) {

        memset(adj, -1, sizeof adj);

        for (int i = 0; i != M; ++i) {

            int u, v, d, c; scanf("%d%d%d%d", &u, &v, &d, &c);

            add_edge(u, v, d, c); add_edge(v, u, d, c);

        }

        bellman_ford(1);

        long long ans = 0;

        for (int i = 1; i <= N; ++i) ans += pre[i];

        printf("%lld\n", ans);

    }

    return 0;

}
// Slower C++ solution:
#include <queue>

#include <vector>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <iostream>

#include <algorithm>

const int INF=0x3f3f3f3f;

using namespace std;

struct edge{

    int to,cost,w;

};

int V,d[10005],dis[10005];

vector<edge> G[20005];

typedef pair<int,int> P;

void dijkstra(int s){

    int i,v;

	priority_queue<P,vector<P>,greater<P> >que;

	fill(d,d+V+1,INF);

	fill(dis,dis+V+1,INF);

	d[s]=dis[s]=0;

	que.push(P(0,s));

	while(!que.empty()){

		P p=que.top(); que.pop();

		v=p.second;

		if(d[v]<p.first)

        continue;

		for(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;

                dis[e.to]=e.w;

				que.push(P(d[e.to],e.to));

			}

			else if(d[e.to]==d[v]+e.cost)

            dis[e.to]=min(dis[e.to],e.w);

		}

	}

}

int main(){

    int m,st,en,i,j,x,y,z,q,ans;

    edge temp;

    while(scanf("%d%d",&V,&m)!=EOF&&(V||m)){

        for(i=0;i<=V;i++)

        G[i].clear();

        for(i=0;i<m;i++){

            scanf("%d%d%d%d",&x,&y,&z,&q);

            temp.to=y;temp.cost=z;temp.w=q;

            G[x].push_back(temp);

            temp.to=x;

            G[y].push_back(temp);

        }

        dijkstra(1);

        ans=0;

        for(i=1;i<=V;i++)

        ans+=dis[i];

        printf("%d\n",ans);

    }

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 4.830942430304554x):
#include <cstdio>

#include <cstring>

#include <algorithm>



using namespace std;



constexpr int maxN = 10005;

constexpr int maxM = 400005;



int N, M;



int adj[maxN], gto[maxM], gnxt[maxM], length[maxM], cost[maxM], e;

void add_edge(int u, int v, int d, int c) {

    gto[e] = v; length[e] = d; cost[e] = c; gnxt[e] = adj[u]; adj[u] = e++;

}



void print_edge(int s) {

    printf("%d:", s);

    for (int e = adj[s]; ~e; e = gnxt[e])

        printf(" %d", gto[e]);

    putchar('\n');

}



int dis[maxN], pre[maxN];

int qu[maxN], qh, qt; bool inq[maxN];

void bellman_ford(int s) {

    memset(dis, 0x3f, sizeof dis); dis[s] = 0;

    for (inq[qu[qh = qt = 0] = s] = 1; qh <= qt; inq[qu[qh++ % N]] = 0)

        for (int u = qu[qh % N], e = adj[u], v = gto[e]; ~e; v = gto[e = gnxt[e]])

            if (dis[v] > dis[u] + length[e]) {

                dis[v] = dis[u] + length[e];

                pre[v] = cost[e];

                if (!inq[v]) inq[qu[++qt % N] = v] = 1;

            } else if (dis[v] == dis[u] + length[e]) {

                pre[v] = min(pre[v], cost[e]);

            }

}



int main() {

    while (~scanf("%d%d", &N, &M) && (N || M)) {

        memset(adj, -1, sizeof adj);

        for (int i = 0; i != M; ++i) {

            int u, v, d, c; scanf("%d%d%d%d", &u, &v, &d, &c);

            add_edge(u, v, d, c); add_edge(v, u, d, c);

        }

        bellman_ford(1);

        long long ans = 0;

        for (int i = 1; i <= N; ++i) ans += pre[i];

        printf("%lld\n", ans);

    }

    return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;



typedef long long ll;

const int N = 10005;

const int M = 1000000007;



int n, m;

typedef int wtype;

struct Edge { int v; wtype d, c; };

vector<Edge> e[N];

wtype dist[N], cost[N];

int pre[N];

bool vis[N];

int SPFA(int src) {

  memset(dist, 0x3f, sizeof(dist)); dist[src] = 0;

  memset(cost, 0x3f, sizeof(cost)); cost[src] = 0;

  memset(vis, 0, sizeof(vis)); vis[src] = true;

  stack<int> que; que.push(src);

  while (!que.empty()) {

    int u = que.top(); que.pop();

    vis[u] = false;

    for (int i = 0; i < (int)e[u].size(); i++) {

      int v = e[u][i].v; wtype d = e[u][i].d, c = e[u][i].c;

      if (dist[v] > dist[u] + d || (dist[v] == dist[u] + d && cost[v] != 0x3f3f3f3f && cost[v] > c)) {

        dist[v] = dist[u] + d; cost[v] = c;

        if (!vis[v]) { vis[v] = true; que.push(v); }

      }

    }

  }

  int ret = 0;

  for (int i = 1; i <= n; i++) { ret += cost[i]; }

  return ret;

}



int main() {

  while (scanf("%d%d", &n, &m), n) {

    for (int i = 1; i <= n; i++) { e[i].clear(); }

    for (int i = 0, u, v, d, c; i < m; i++) {

      scanf("%d%d%d%d", &u, &v, &d, &c);

      e[u].push_back((Edge) {v, d, c});

      e[v].push_back((Edge) {u, d, c});

    }

    printf("%d\n", SPFA(1));

  }

}

// Faster C++ solution for the same problem (measured speedup: 4.420020654183619x):
#include <cstdio>

#include <cstring>

#include <algorithm>



using namespace std;



constexpr int maxN = 10005;

constexpr int maxM = 400005;



int N, M;



int adj[maxN], gto[maxM], gnxt[maxM], length[maxM], cost[maxM], e;

void add_edge(int u, int v, int d, int c) {

    gto[e] = v; length[e] = d; cost[e] = c; gnxt[e] = adj[u]; adj[u] = e++;

}



void print_edge(int s) {

    printf("%d:", s);

    for (int e = adj[s]; ~e; e = gnxt[e])

        printf(" %d", gto[e]);

    putchar('\n');

}



int dis[maxN], pre[maxN];

int qu[maxN], qh, qt; bool inq[maxN];

void bellman_ford(int s) {

    memset(dis, 0x3f, sizeof dis); dis[s] = 0;

    for (inq[qu[qh = qt = 0] = s] = 1; qh <= qt; inq[qu[qh++ % N]] = 0)

        for (int u = qu[qh % N], e = adj[u], v = gto[e]; ~e; v = gto[e = gnxt[e]])

            if (dis[v] > dis[u] + length[e]) {

                dis[v] = dis[u] + length[e];

                pre[v] = cost[e];

                if (!inq[v]) inq[qu[++qt % N] = v] = 1;

            } else if (dis[v] == dis[u] + length[e]) {

                pre[v] = min(pre[v], cost[e]);

            }

}



int main() {

    while (~scanf("%d%d", &N, &M) && (N || M)) {

        memset(adj, -1, sizeof adj);

        for (int i = 0; i != M; ++i) {

            int u, v, d, c; scanf("%d%d%d%d", &u, &v, &d, &c);

            add_edge(u, v, d, c); add_edge(v, u, d, c);

        }

        bellman_ford(1);

        long long ans = 0;

        for (int i = 1; i <= N; ++i) ans += pre[i];

        printf("%lld\n", ans);

    }

    return 0;

}
// Slower C++ solution:
#include <iostream>

#include <queue>

#include <functional>

#include <cstring>

using namespace std;

#define MAX_V 10240

 

// 从?点from指向?点to的???cost的?

typedef struct edge

{

	int to, distance, cost;

	edge(){}

	edge(int to, int distance, int cost) : to(to), distance(distance), cost(cost){}

	bool operator > (const edge & b) const

	{

		return distance != b.distance  ? distance > b.distance : cost > b.cost;

	}

} P;

 

// first 最短路径，second?点?号

 

// ?

vector<edge> G[MAX_V];

 

// V是?点数

int V;

bool visited[MAX_V];

 

// 求解从?点s出?到所有点的最短花?

int dijkstra(int s)

{

	int result = 0;

	priority_queue<P, vector<P>, greater<P> > que;

	memset(visited, 0, V * sizeof(bool));

	que.push(P(0, 0, 0));

 

	while (!que.empty())

	{

		P p = que.top(); que.pop();

		int v = p.to;

		if (visited[v]) continue;

		visited[v] = true;

		result += p.cost;

		for (int i = 0; i < G[v].size(); ++i)

		{

			edge e = G[v][i];

			que.push(P(G[v][i].to, p.distance + G[v][i].distance, G[v][i].cost));

		}

	}

 

	return result;

}

 

///////////////////////////SubMain//////////////////////////////////

int main(int argc, char *argv[])

{

	int /*N = V,*/ M;

	while (cin >> V >> M && V)

	{

		for (int i = 0; i < V; ++i)

		{

			G[i].clear();

		}

		for (int i = 0; i < M; ++i)

		{

			int u, v, d, c;

			cin >> u >> v >> d >> c;

			--u, --v;

			G[u].push_back(edge(v, d, c));

			G[v].push_back(edge(u, d, c));

		}

 

		cout << dijkstra(0) << endl;

	}

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 4.13341381959393x):
#include <cstdio>

#include <cstring>

#include <algorithm>



using namespace std;



constexpr int maxN = 10005;

constexpr int maxM = 400005;



int N, M;



int adj[maxN], gto[maxM], gnxt[maxM], length[maxM], cost[maxM], e;

void add_edge(int u, int v, int d, int c) {

    gto[e] = v; length[e] = d; cost[e] = c; gnxt[e] = adj[u]; adj[u] = e++;

}



void print_edge(int s) {

    printf("%d:", s);

    for (int e = adj[s]; ~e; e = gnxt[e])

        printf(" %d", gto[e]);

    putchar('\n');

}



int dis[maxN], pre[maxN];

int qu[maxN], qh, qt; bool inq[maxN];

void bellman_ford(int s) {

    memset(dis, 0x3f, sizeof dis); dis[s] = 0;

    for (inq[qu[qh = qt = 0] = s] = 1; qh <= qt; inq[qu[qh++ % N]] = 0)

        for (int u = qu[qh % N], e = adj[u], v = gto[e]; ~e; v = gto[e = gnxt[e]])

            if (dis[v] > dis[u] + length[e]) {

                dis[v] = dis[u] + length[e];

                pre[v] = cost[e];

                if (!inq[v]) inq[qu[++qt % N] = v] = 1;

            } else if (dis[v] == dis[u] + length[e]) {

                pre[v] = min(pre[v], cost[e]);

            }

}



int main() {

    while (~scanf("%d%d", &N, &M) && (N || M)) {

        memset(adj, -1, sizeof adj);

        for (int i = 0; i != M; ++i) {

            int u, v, d, c; scanf("%d%d%d%d", &u, &v, &d, &c);

            add_edge(u, v, d, c); add_edge(v, u, d, c);

        }

        bellman_ford(1);

        long long ans = 0;

        for (int i = 1; i <= N; ++i) ans += pre[i];

        printf("%lld\n", ans);

    }

    return 0;

}
// Slower C++ solution:
#include<iostream>

#include<vector>

#include<queue>

#include<algorithm>

#include<cstring>

using namespace std;

const int maxn  = 1e4+10;

const int INF = 0x3f3f3f3f;

typedef pair<int,int> P;

struct edge{

	int to,dis,cost;

		

};



int d[maxn];

int value[maxn];



int N,M;



int dijkstra(vector<edge>G[])

{



	memset(d,INF,sizeof(d));

	//memset(value,INF,sizeof(value));

	priority_queue<P,vector<P>,greater<P> > que;

		

	d[1] = 0;

	value[1] = 0;

	que.push(P(d[1],1));

	

	int res = 0;

	while(!que.empty())

	{

		P p  = que.top(); que.pop();

		

		int v = p.second;

		if(d[v] < p.first)

			continue;

			

		res += value[v];

		

		for(int i = 0; i < G[v].size(); i++)

		{

			edge e = G[v][i];

			if(d[e.to] == d[v] + e.dis)

				value[e.to] = min(value[e.to],e.cost);

			if(d[e.to] > d[v] + e.dis)

			{

				d[e.to] = d[v] + e.dis;

				que.push(P(d[e.to],e.to));

				

				value[e.to] = e.cost;

			}

		}

	}

	return res;

	

}



int main()

{



	//freopen("c:\\users\\administrator\\desktop\\in.txt","r",stdin);

	while(cin >> N >> M, N||M)

	{

		

		vector<edge> G[maxn];

		for(int i =0; i < M; i++)

		{

			int u,v,d,c;

			edge e;

			cin >> u >> v >> d >> c;

			e.to= v, e.dis= d, e.cost =c;

			G[u].push_back(e);

			e.to= u;

			G[v].push_back(e);	

		}

		

		int res = dijkstra(G);

		cout << res <<endl;

	}		

} 

// Faster C++ solution for the same problem (measured speedup: 4.627473782281343x):
#include <cstdio>

#include <cstring>

#include <algorithm>



using namespace std;



constexpr int maxN = 10005;

constexpr int maxM = 400005;



int N, M;



int adj[maxN], gto[maxM], gnxt[maxM], length[maxM], cost[maxM], e;

void add_edge(int u, int v, int d, int c) {

    gto[e] = v; length[e] = d; cost[e] = c; gnxt[e] = adj[u]; adj[u] = e++;

}



void print_edge(int s) {

    printf("%d:", s);

    for (int e = adj[s]; ~e; e = gnxt[e])

        printf(" %d", gto[e]);

    putchar('\n');

}



int dis[maxN], pre[maxN];

int qu[maxN], qh, qt; bool inq[maxN];

void bellman_ford(int s) {

    memset(dis, 0x3f, sizeof dis); dis[s] = 0;

    for (inq[qu[qh = qt = 0] = s] = 1; qh <= qt; inq[qu[qh++ % N]] = 0)

        for (int u = qu[qh % N], e = adj[u], v = gto[e]; ~e; v = gto[e = gnxt[e]])

            if (dis[v] > dis[u] + length[e]) {

                dis[v] = dis[u] + length[e];

                pre[v] = cost[e];

                if (!inq[v]) inq[qu[++qt % N] = v] = 1;

            } else if (dis[v] == dis[u] + length[e]) {

                pre[v] = min(pre[v], cost[e]);

            }

}



int main() {

    while (~scanf("%d%d", &N, &M) && (N || M)) {

        memset(adj, -1, sizeof adj);

        for (int i = 0; i != M; ++i) {

            int u, v, d, c; scanf("%d%d%d%d", &u, &v, &d, &c);

            add_edge(u, v, d, c); add_edge(v, u, d, c);

        }

        bellman_ford(1);

        long long ans = 0;

        for (int i = 1; i <= N; ++i) ans += pre[i];

        printf("%lld\n", ans);

    }

    return 0;

}
// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

struct node{

    int next,d,c;

};

const int maxn=10005;

int n,m;

int d[maxn],c[maxn];

bool vis[maxn];

void init()

{

    for(int i=0;i<maxn;i++)

        d[i]=c[i]=1e9,vis[i]=0;

}

int main()

{

    while(~scanf("%d%d",&n,&m))

    {

        if(n==0&&m==0) return 0;

        init();vector<node> v[maxn];

        for(int i=0;i<m;i++)

        {

            int x,y,d,c;

            scanf("%d%d%d%d",&x,&y,&d,&c);

            v[x].push_back(node{y,d,c});

            v[y].push_back(node{x,d,c});

        }

        queue<int> q;

        q.push(1);

        d[1]=c[1]=0;vis[1]=1;

        while(!q.empty())

        {

            int u=q.front();q.pop();vis[u]=0;

            for(int i=0;i<v[u].size();i++)

            {

                int nx=v[u][i].next;

                if(d[nx]==d[u]+v[u][i].d&&c[nx]>v[u][i].c){

                        c[nx]=v[u][i].c;

                }

                if(d[nx]>d[u]+v[u][i].d)

                {

                    d[nx]=d[u]+v[u][i].d;

                    c[nx]=v[u][i].c;

                    if(vis[nx]) continue;

                    vis[nx]=1;

                    q.push(nx);

                }

            }

        }

        int ans=0;

        for(int i=2;i<=n;i++) ans+=c[i];

        cout<<ans<<endl;

    }

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 4.816842843068491x):
#include <cstdio>

#include <cstring>

#include <algorithm>



using namespace std;



constexpr int maxN = 10005;

constexpr int maxM = 400005;



int N, M;



int adj[maxN], gto[maxM], gnxt[maxM], length[maxM], cost[maxM], e;

void add_edge(int u, int v, int d, int c) {

    gto[e] = v; length[e] = d; cost[e] = c; gnxt[e] = adj[u]; adj[u] = e++;

}



void print_edge(int s) {

    printf("%d:", s);

    for (int e = adj[s]; ~e; e = gnxt[e])

        printf(" %d", gto[e]);

    putchar('\n');

}



int dis[maxN], pre[maxN];

int qu[maxN], qh, qt; bool inq[maxN];

void bellman_ford(int s) {

    memset(dis, 0x3f, sizeof dis); dis[s] = 0;

    for (inq[qu[qh = qt = 0] = s] = 1; qh <= qt; inq[qu[qh++ % N]] = 0)

        for (int u = qu[qh % N], e = adj[u], v = gto[e]; ~e; v = gto[e = gnxt[e]])

            if (dis[v] > dis[u] + length[e]) {

                dis[v] = dis[u] + length[e];

                pre[v] = cost[e];

                if (!inq[v]) inq[qu[++qt % N] = v] = 1;

            } else if (dis[v] == dis[u] + length[e]) {

                pre[v] = min(pre[v], cost[e]);

            }

}



int main() {

    while (~scanf("%d%d", &N, &M) && (N || M)) {

        memset(adj, -1, sizeof adj);

        for (int i = 0; i != M; ++i) {

            int u, v, d, c; scanf("%d%d%d%d", &u, &v, &d, &c);

            add_edge(u, v, d, c); add_edge(v, u, d, c);

        }

        bellman_ford(1);

        long long ans = 0;

        for (int i = 1; i <= N; ++i) ans += pre[i];

        printf("%lld\n", ans);

    }

    return 0;

}
// Slower C++ solution:
#include<cstdio>

#include<cstring>

#include<queue>

#include<vector>

using namespace std;

#define INF 1000000000

#define pb push_back

#define maxn 10001

struct Edge{

	int from, to, dist, cost;

};

struct HeapNode{

	int d, u, c;

	bool operator < (const HeapNode& a)const{

		if(d==a.d)	return c>a.c;

		return d>a.d;

	}

};

inline void IN(int& x){

	x=0;

	char c=getchar();

	while(c<48 || c>57)	c=getchar();

	while(c>=48 && c<=57){

		x=x*10+c-48;

		c=getchar();

	}

}

int n, m;

vector<Edge> edges;

vector<int> G[maxn];

vector<int> V[maxn];

bool done[maxn];

int d[maxn], p[maxn], c[maxn];

int ans;

void init(){

	for(int i=1; i<=n; i++){

		G[i].clear();

		V[i].clear();

	}

	edges.clear();

}

void add(int from, int to, int dist, int cost){

	edges.pb((Edge){from, to, dist, cost});

	m = edges.size();

	G[from].pb(m-1);

	V[from].pb(cost);

}

void dijkstra(int s){

	ans=0;

	priority_queue<HeapNode> Q;

	for(int i=1; i<=n; i++)	d[i]=INF;

	for(int i=1; i<=n; i++)	c[i]=INF;

	d[s]=0;

	c[s]=0;

	memset(done, 0, sizeof(done));

	Q.push((HeapNode){0,s,0});

	while(!Q.empty()){

		HeapNode x = Q.top(); Q.pop();

		int u=x.u;

		if(done[u])	continue;

		done[u]=1;

		ans += c[u];

		for(int i=0; i<G[u].size(); i++){

			Edge& e = edges[G[u][i]];

			if(d[e.to]>d[u]+e.dist || (d[e.to]==d[u]+e.dist && c[e.to]>V[u][i])){

				d[e.to] = d[u]+e.dist;

				p[e.to] = G[u][i];

				c[e.to] = V[u][i];

				Q.push((HeapNode){d[e.to],e.to,c[e.to]});

			}

		}

	}

	printf("%d\n", ans);

}

int k;

int main(){

	while(1){

		IN(n); IN(k);

		if(!n && (!k))	break;

		int a, b, c, d;

		init();

		while(k--){

			IN(a); IN(b); IN(c); IN(d);

			add(a, b, c, d);

			add(b, a, c, d);

		}

		dijkstra(1);

	}

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.113583074163735x):
#include <bits/stdc++.h>



using namespace std;

const int N = 1E4 + 7;

bool vis[N];

int n, m;

typedef struct node

{

   int to,dis,cost;

   node(){}

   node(int a,int b,int c) : to(a),dis(b),cost(c) {}

   bool operator < (const node &a) const {

       return dis == a.dis ? cost > a.cost : dis > a.dis;

   }

}P;

vector<P>g[N];

int dij()

{

    int ans = 0;

    priority_queue<P> pq;

    pq.push(P(1,0,0));

    while(!pq.empty()) {

        P now = pq.top() ; pq.pop();

        if(vis[now.to]) continue;

        vis[now.to] = true;

        ans += now.cost;

        for(int i = 0;i < g[now.to].size();i ++) {

            P temp = g[now.to][i];

            pq.push(P(temp.to, now.dis + temp.dis, temp.cost));

        }

    }

    return ans;

}

int main()

{

   // freopen("f:\\jj.txt","r",stdin);

    std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);

    while(cin >> n >> m) {

        if(n + m == 0)  break;

        for(int i = 1;i <= n;i ++)  g[i].clear();

        memset(vis, 0, sizeof(vis));

        for(int i = 1;i <= m;i ++) {

            int a,b,c,d;

            cin >> a >> b >> c >> d;

            g[a].push_back(P(b,c,d));

            g[b].push_back(P(a,c,d));

        }

        cout << dij() << endl;

    }

    return 0;

}