// 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.323500894695944x):
#include <iostream>

#include <cstring>

const int SIZE = 10010;

const int MAX = 0x3f3f3f3f;



typedef struct Road

{

	int from;

	int to;

	int length;

	int cost;

	int next;

} Road;



int head[SIZE];

int dis[SIZE];

Road roads[SIZE * 5];

int front[SIZE];

bool visit[SIZE];



int city, road, capital;



void init()

{

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

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

	memset(visit, false, sizeof(visit));

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

	{

		dis[i] = MAX;

	}

	dis[1] = 0;

}



void dijkstra()

{

	while (true)

	{

		int pos = -1;

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

		{

			if (!visit[i] && (pos == -1 || dis[pos] > dis[i]))

			{

				pos = i;

			}

		}

		if (pos == -1)

		{

			break;

		}

		visit[pos] = true;

		for (int i = head[pos]; i != -1; i = roads[i].next)

		{

			int to = roads[i].to;

			if (dis[to] > dis[pos] + roads[i].length)

			{

				dis[to] = dis[pos] + roads[i].length;

				front[to] = i;

			}

			else if ((dis[to] == dis[pos] + roads[i].length) && front[to] != -1 && roads[i].cost < roads[front[to]].cost)

			{

				front[to] = i;

			}

		}

	}

}



int main()

{

	while (true)

	{

		std::cin >> city >> road;

		if (city == 0 && road == 0)

		{

			break;

		}

		init();

		int en = 0;

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

		{

			std::cin >> roads[en].from >> roads[en].to >> roads[en].length >> roads[en].cost;

			roads[en].next = head[roads[en].from];

			head[roads[en].from] = en;

			en++;

			roads[en].from = roads[en - 1].to;

			roads[en].to = roads[en - 1].from;

			roads[en].length = roads[en - 1].length;

			roads[en].cost = roads[en - 1].cost;

			roads[en].next = head[roads[en].from];

			head[roads[en].from] = en;

			en++;

		}

		dijkstra();

		int result = 0;

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

		{

			if (front[i] != -1)

			{

				result += roads[front[i]].cost;

			}

		}

		std::cout << result << std::endl;

	}

	return 0;

}