stablegradients/pie-gem5-pairs huggingface dataset:
// 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: 1.3457550227790225x):
#include<cstdio>

#include<algorithm>

#include<queue>

#include<iostream>

#include<cstring>

using namespace std;

const int maxn = 10050, maxe = 2005000, inf = 1e9;

struct node {

	int to;

	int w;

	int c;

	int next;

};

node edge[maxe];

int head[maxn];

int ip;

void init()

{

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

	ip = 0;

}

void addedge(int u, int v, int w, int c)

{

	edge[ip].to = v;

	edge[ip].c = c;

	edge[ip].w = w;

	edge[ip].next = head[u];

	head[u] = ip++;

}

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

queue<int>q;

void spfa(int s, int n)

{

	while (!q.empty())

		q.pop();

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

		dis[i] = cost[i] = inf;

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

	dis[s] = 0, cost[s] = 0, vis[s] = 1;

	q.push(s);

	while (q.size())

	{

		int u = q.front();

		q.pop();

		vis[u] = 0;

		for (int i = head[u]; i != -1; i = edge[i].next)

		{

			int to = edge[i].to, val = edge[i].w;

			if (dis[to] > dis[u] + val || (dis[to] == dis[u] + val&&cost[to] > edge[i].c))

			{

				dis[to] = dis[u] + val;

				cost[to] = edge[i].c;

				if (!vis[to])

				{

					q.push(to);

					vis[to] = 1;

				}

			}

		}

	}

}

int main()

{

	int n, m, u, v, w, c;

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

	{

		init();

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

		{

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

			addedge(u, v, w, c);

			addedge(v, u, w, c);

		}

		spfa(1, n);

		int ans = 0;

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

			ans += cost[i];

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

	}

	return 0;

}
// Slower C++ solution:
#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;

}

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

#include<algorithm>

#include<queue>

#include<iostream>

#include<cstring>

using namespace std;

const int maxn = 10050, maxe = 2005000, inf = 1e9;

struct node {

	int to;

	int w;

	int c;

	int next;

};

node edge[maxe];

int head[maxn];

int ip;

void init()

{

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

	ip = 0;

}

void addedge(int u, int v, int w, int c)

{

	edge[ip].to = v;

	edge[ip].c = c;

	edge[ip].w = w;

	edge[ip].next = head[u];

	head[u] = ip++;

}

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

queue<int>q;

void spfa(int s, int n)

{

	while (!q.empty())

		q.pop();

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

		dis[i] = cost[i] = inf;

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

	dis[s] = 0, cost[s] = 0, vis[s] = 1;

	q.push(s);

	while (q.size())

	{

		int u = q.front();

		q.pop();

		vis[u] = 0;

		for (int i = head[u]; i != -1; i = edge[i].next)

		{

			int to = edge[i].to, val = edge[i].w;

			if (dis[to] > dis[u] + val || (dis[to] == dis[u] + val&&cost[to] > edge[i].c))

			{

				dis[to] = dis[u] + val;

				cost[to] = edge[i].c;

				if (!vis[to])

				{

					q.push(to);

					vis[to] = 1;

				}

			}

		}

	}

}

int main()

{

	int n, m, u, v, w, c;

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

	{

		init();

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

		{

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

			addedge(u, v, w, c);

			addedge(v, u, w, c);

		}

		spfa(1, n);

		int ans = 0;

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

			ans += cost[i];

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

	}

	return 0;

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

#include<cstdio>

#include<cstdlib>

#include<string>

#include<cstring>

#include<algorithm>

#include<queue>

#include<vector>

#define N 20100

#define M 50010

#define rg register

using namespace std;

typedef long long ll;

typedef double db;

int n,m,tot=0;

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

int nxt[M],to[M],w[M],c[M];

void link(int x,int y,int z,int v){

	nxt[tot]=head[x],to[tot]=y,w[tot]=z,c[tot]=v,head[x]=tot++;

}

void spfa(){

	queue <int> q;

	memset(dis,0x3f,sizeof(dis));

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

	q.push(1),dis[1]=0,vis[1]=1;

	while (!q.empty()){

		int x=q.front();q.pop();

		for (int i=head[x];i!=-1;i=nxt[i]){

			int v=to[i];

			if (dis[v]<=dis[x]+w[i]) continue;

			dis[v]=dis[x]+w[i];

			if (!vis[v]) vis[v]=1,q.push(v);

		}

		vis[x]=0;

	}

}

int main(){

//	freopen ("2249.in","r",stdin);

//	freopen ("2249.out","w",stdout);

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

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

		tot=0;int x,y,z,v;

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

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

			link(x,y,z,v),link(y,x,z,v);

		}

		spfa();

		int ans=0;

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

			int mx=2000;

			for (int j=head[i];j!=-1;j=nxt[j]){

				v=to[j];

				if (dis[i]==dis[v]+w[j]) mx=min(mx,c[j]);

			}

			ans+=mx;

		}

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

	

	}

	return 0;

}

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

#include<algorithm>

#include<queue>

#include<iostream>

#include<cstring>

using namespace std;

const int maxn = 10050, maxe = 2005000, inf = 1e9;

struct node {

	int to;

	int w;

	int c;

	int next;

};

node edge[maxe];

int head[maxn];

int ip;

void init()

{

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

	ip = 0;

}

void addedge(int u, int v, int w, int c)

{

	edge[ip].to = v;

	edge[ip].c = c;

	edge[ip].w = w;

	edge[ip].next = head[u];

	head[u] = ip++;

}

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

queue<int>q;

void spfa(int s, int n)

{

	while (!q.empty())

		q.pop();

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

		dis[i] = cost[i] = inf;

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

	dis[s] = 0, cost[s] = 0, vis[s] = 1;

	q.push(s);

	while (q.size())

	{

		int u = q.front();

		q.pop();

		vis[u] = 0;

		for (int i = head[u]; i != -1; i = edge[i].next)

		{

			int to = edge[i].to, val = edge[i].w;

			if (dis[to] > dis[u] + val || (dis[to] == dis[u] + val&&cost[to] > edge[i].c))

			{

				dis[to] = dis[u] + val;

				cost[to] = edge[i].c;

				if (!vis[to])

				{

					q.push(to);

					vis[to] = 1;

				}

			}

		}

	}

}

int main()

{

	int n, m, u, v, w, c;

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

	{

		init();

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

		{

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

			addedge(u, v, w, c);

			addedge(v, u, w, c);

		}

		spfa(1, n);

		int ans = 0;

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

			ans += cost[i];

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

	}

	return 0;

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

#include<cstdlib>

#include<cstdio>

#include<cmath>

#include<algorithm>

#include<cstring>

#include<queue>

#include<vector>

#include<stack>

#define ls k<<1

#define rs k<<1|1

#define RG register

#define MAXN 50010

#define LL long long int

using namespace std;

const int INF=0x7fffffff;

struct node{

	int next;

	int to;

	int w;

	int c;

}t[MAXN];

int head[MAXN];

int num;

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

int n,m;

void add(int from,int to,int w,int c)

{

	t[++num].next=head[from];

	t[num].to=to;

	t[num].w=w;

	t[num].c=c;

	head[from]=num;

}

void spfa()

{

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

		{

			dis[i]=INF;vis[i]=0;cost[i]=INF;

		}

	cost[1]=dis[1]=0;vis[1]=1;

	queue<int>q;q.push(1);

	while(!q.empty())

		{

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

			for(int i=head[u];i;i=t[i].next)

				{

					int v=t[i].to;

					if(dis[v]>dis[u]+t[i].w||(dis[v]==dis[u]+t[i].w&&cost[v]>t[i].c))

						{

							dis[v]=dis[u]+t[i].w;

							cost[v]=t[i].c;

							if(!vis[v])

								{

									vis[v]=1;q.push(v);

								}

						}

				}

		}

}

int main()

{

//	freopen("1.in","r" ,stdin);

	//freopen("1.out","w",stdout);

	while(1)

		{

			scanf("%d%d",&n,&m);if(n==0&&m==0) break;

			int x,y,z,k;

			memset(head,0,sizeof(head));num=0;

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

				{

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

					add(x,y,z,k);add(y,x,z,k);

				}

			spfa();

			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: 1.146045043691239x):
#include<cstdio>

#include<algorithm>

#include<queue>

#include<iostream>

#include<cstring>

using namespace std;

const int maxn = 10050, maxe = 2005000, inf = 1e9;

struct node {

	int to;

	int w;

	int c;

	int next;

};

node edge[maxe];

int head[maxn];

int ip;

void init()

{

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

	ip = 0;

}

void addedge(int u, int v, int w, int c)

{

	edge[ip].to = v;

	edge[ip].c = c;

	edge[ip].w = w;

	edge[ip].next = head[u];

	head[u] = ip++;

}

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

queue<int>q;

void spfa(int s, int n)

{

	while (!q.empty())

		q.pop();

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

		dis[i] = cost[i] = inf;

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

	dis[s] = 0, cost[s] = 0, vis[s] = 1;

	q.push(s);

	while (q.size())

	{

		int u = q.front();

		q.pop();

		vis[u] = 0;

		for (int i = head[u]; i != -1; i = edge[i].next)

		{

			int to = edge[i].to, val = edge[i].w;

			if (dis[to] > dis[u] + val || (dis[to] == dis[u] + val&&cost[to] > edge[i].c))

			{

				dis[to] = dis[u] + val;

				cost[to] = edge[i].c;

				if (!vis[to])

				{

					q.push(to);

					vis[to] = 1;

				}

			}

		}

	}

}

int main()

{

	int n, m, u, v, w, c;

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

	{

		init();

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

		{

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

			addedge(u, v, w, c);

			addedge(v, u, w, c);

		}

		spfa(1, n);

		int ans = 0;

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

			ans += cost[i];

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

	}

	return 0;

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

#include "cstdio"

#include "vector"

#include "queue"

using namespace std;



const int maxn=11000;



struct edge{int to,d,c;};

edge edges[4100000];

int p;



vector<int>g[maxn];



int dis[maxn],vis[maxn],cos[maxn];

int n,m,sn;



void add(int u,int v,int d,int c)

{

	edges[++p].d=d;

	edges[p].to=v;

	edges[p].c=c;

	g[u].push_back(p);

}



int spfa(int s)

{

	memset(cos,0x3f3f3f3f,sizeof(cos));

	memset(dis,0x3f3f3f3f,sizeof(dis));

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

	

	queue<int>qn;

	qn.push(s);

	dis[s]=0;

	cos[s]=0;

	vis[s]=1;

	

	while(!qn.empty())

	{

		int nn=qn.front();qn.pop();

		vis[nn]=0;

		for(int i=0,d=g[nn].size();i<d;i++)

		{

			edge &e= edges[g[nn][i]];

			if(dis[e.to]>dis[nn]+e.d || ((dis[e.to]==dis[nn]+e.d) && cos[e.to]>e.c))

			{

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

				cos[e.to]=e.c;

				

				if(!vis[e.to])

				{

					qn.push(e.to);

					vis[e.to]=1;

				}

			}

		}	

	}

	return 0;

}



int main()

{

	//freopen("q.txt","r",stdin);

	int u,v,d,c;

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

	{

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

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

			g[i].clear();

		p=0;

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

		{

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

			add(u,v,d,c);

			add(v,u,d,c);

		}

		int ans=0;

		spfa(1);

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

			ans+=cos[i];

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

	}

	return 0;

} 


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

#include<algorithm>

#include<queue>

#include<iostream>

#include<cstring>

using namespace std;

const int maxn = 10050, maxe = 2005000, inf = 1e9;

struct node {

	int to;

	int w;

	int c;

	int next;

};

node edge[maxe];

int head[maxn];

int ip;

void init()

{

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

	ip = 0;

}

void addedge(int u, int v, int w, int c)

{

	edge[ip].to = v;

	edge[ip].c = c;

	edge[ip].w = w;

	edge[ip].next = head[u];

	head[u] = ip++;

}

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

queue<int>q;

void spfa(int s, int n)

{

	while (!q.empty())

		q.pop();

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

		dis[i] = cost[i] = inf;

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

	dis[s] = 0, cost[s] = 0, vis[s] = 1;

	q.push(s);

	while (q.size())

	{

		int u = q.front();

		q.pop();

		vis[u] = 0;

		for (int i = head[u]; i != -1; i = edge[i].next)

		{

			int to = edge[i].to, val = edge[i].w;

			if (dis[to] > dis[u] + val || (dis[to] == dis[u] + val&&cost[to] > edge[i].c))

			{

				dis[to] = dis[u] + val;

				cost[to] = edge[i].c;

				if (!vis[to])

				{

					q.push(to);

					vis[to] = 1;

				}

			}

		}

	}

}

int main()

{

	int n, m, u, v, w, c;

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

	{

		init();

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

		{

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

			addedge(u, v, w, c);

			addedge(v, u, w, c);

		}

		spfa(1, n);

		int ans = 0;

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

			ans += cost[i];

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

	}

	return 0;

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

#include <iostream>

#include <cstring>

#include <string>

#include <algorithm>

#include <vector>

#include <queue>

const int maxn = 10007;

const int inf =1e9;

using namespace std;

struct node{

	int to,d,c;

	node(){}

	node (int to,int d,int c):to(to),d(d),c(c){}

};

vector<node>mp[maxn];

int dis[maxn],cost[maxn],n,m,ans = 0;

void init(){

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

	{

		mp[i].clear();

		dis[i] = inf;

		cost[i]  = 0;

	}

}

void add(int u,int v,int d,int c)

{

	mp[u].push_back(node(v,d,c));

}

int main(){

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

	{

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

		init();

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

		{

			int u,v,d,c;

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

			add(u,v,d,c);

			add(v,u,d,c);

		}

		priority_queue<pair<int,int> >q;

		dis[1]=0;

		cost[1]=0;

		

		q.push (make_pair(-dis[1],1)) ;

		while(!q.empty())

		{

			int now = q.top().second;

			q.pop();

			for(int i=0;i<mp[now].size();i++)

			{

				int v=mp[now][i].to;

				int d=mp[now][i].d;

				int c=mp[now][i].c;

				if(dis[v]>dis[now]+d)

				{

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

					//ans -=cost[v];

					//cost[v] = cost[now]+c;

					//ans +=cost[v];

					q.push (make_pair(-dis[v],v));

				}

			}

		}

		ans = 0;

		for(int i=2;i<=n;i++)

		{

			int minc = inf;

			for(int j=0;j<mp[i].size();j++)

			{

				node tmp = mp[i][j];

				if(tmp.d+dis[tmp.to]==dis[i]&&minc>tmp.c)

				{

					minc = mp[i][j].c;

				}

			}

			ans += minc;

		}

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

	}

	return 0;

}


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

#include<algorithm>

#include<queue>

#include<iostream>

#include<cstring>

using namespace std;

const int maxn = 10050, maxe = 2005000, inf = 1e9;

struct node {

	int to;

	int w;

	int c;

	int next;

};

node edge[maxe];

int head[maxn];

int ip;

void init()

{

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

	ip = 0;

}

void addedge(int u, int v, int w, int c)

{

	edge[ip].to = v;

	edge[ip].c = c;

	edge[ip].w = w;

	edge[ip].next = head[u];

	head[u] = ip++;

}

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

queue<int>q;

void spfa(int s, int n)

{

	while (!q.empty())

		q.pop();

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

		dis[i] = cost[i] = inf;

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

	dis[s] = 0, cost[s] = 0, vis[s] = 1;

	q.push(s);

	while (q.size())

	{

		int u = q.front();

		q.pop();

		vis[u] = 0;

		for (int i = head[u]; i != -1; i = edge[i].next)

		{

			int to = edge[i].to, val = edge[i].w;

			if (dis[to] > dis[u] + val || (dis[to] == dis[u] + val&&cost[to] > edge[i].c))

			{

				dis[to] = dis[u] + val;

				cost[to] = edge[i].c;

				if (!vis[to])

				{

					q.push(to);

					vis[to] = 1;

				}

			}

		}

	}

}

int main()

{

	int n, m, u, v, w, c;

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

	{

		init();

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

		{

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

			addedge(u, v, w, c);

			addedge(v, u, w, c);

		}

		spfa(1, n);

		int ans = 0;

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

			ans += cost[i];

		printf("%d\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.1968562095295436x):
#include<cstdio>

#include<cstring>

#include<algorithm>

#include<vector>

#include<queue>



#define N 10010



struct Edge{

	int y;

	int z;

	int w;

	Edge(){}

	Edge(int y,int z,int w):y(y),z(z),w(w){}

	bool operator <(const Edge&_x)const{

		return this->z>_x.z || (this->z==_x.z && this->w>_x.w);

	}

};

#define Node Edge



std::vector<Edge> v[N];



void Dijkstra(int&);



int main(){

	while(true){

		int n,m;

		scanf("%d%d",&n,&m);

		if(!(n||m))

			break;

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

			v[i].clear();

		while(m--){

			int x,y,z,w;

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

			v[x].push_back(Edge(y,z,w));

			v[y].push_back(Edge(x,z,w));

		}

		int ans=0;

		Dijkstra(ans);

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

	}

	return 0;

}



void Dijkstra(int &ans){

	std::priority_queue<Node> q;

	q.push(Node(1,0,0));

	bool vis[N]={};

	while(q.size()){

		int x=q.top().y,z=q.top().z,w=q.top().w;

		q.pop();

		if(vis[x])

			continue;

		vis[x]=true;

		ans+=w;

		for(auto p:v[x])

			q.push(Node(p.y,z+p.z,p.w));

	}

}
// 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.2563903364676001x):
#include<cstdio>

#include<cstring>

#include<algorithm>

#include<vector>

#include<queue>



#define N 10010



struct Edge{

	int y;

	int z;

	int w;

	Edge(){}

	Edge(int y,int z,int w):y(y),z(z),w(w){}

	bool operator <(const Edge&_x)const{

		return this->z>_x.z || (this->z==_x.z && this->w>_x.w);

	}

};

#define Node Edge



std::vector<Edge> v[N];



void Dijkstra(int&);



int main(){

	while(true){

		int n,m;

		scanf("%d%d",&n,&m);

		if(!(n||m))

			break;

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

			v[i].clear();

		while(m--){

			int x,y,z,w;

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

			v[x].push_back(Edge(y,z,w));

			v[y].push_back(Edge(x,z,w));

		}

		int ans=0;

		Dijkstra(ans);

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

	}

	return 0;

}



void Dijkstra(int &ans){

	std::priority_queue<Node> q;

	q.push(Node(1,0,0));

	bool vis[N]={};

	while(q.size()){

		int x=q.top().y,z=q.top().z,w=q.top().w;

		q.pop();

		if(vis[x])

			continue;

		vis[x]=true;

		ans+=w;

		for(auto p:v[x])

			q.push(Node(p.y,z+p.z,p.w));

	}

}