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

#include<queue>

#include<cstdlib>

#include<cstdio>

#include<cstring>



using namespace std;

const int maxn=4e4+100;

const int inf=0x3f3f3f3f;



struct Edge{

    int next;

    int to;

    int w;

    int  c;



}G[maxn];



int inq[maxn];

int dis[maxn];

int head[maxn];

int k=0;





void adde(int v,int to,int w,int c)//加?

{

    G[k].to=to;//第k条?指向的点

    G[k].w=w;//第k条?的??

    G[k].c=c;

    G[k].next=head[v];//与第k条??同起点的上一条?的?存位置

    head[v]=k++;

}



queue<int>Q;



void spfa(int s)

{

        while(!Q.empty())Q.pop();

        memset(inq,0,sizeof(inq));

        memset(dis,inf,sizeof(dis));

        dis[s] = 0;

        inq[s] = 1;

        Q.push(s);

        while(!Q.empty())

        {

                int u = Q.front();

                Q.pop();

                inq[u]=0;

                for(int i=head[u];i!=-1;i=G[i].next)//遍?以u?起点的所有?

                {

                        int v=G[i].to;

                        if(dis[v]>dis[u]+G[i].w)

                        {

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

                                if(inq[v]==0)

                                {

                                    Q.push(v);

                                    inq[v]=1;

                                }

                        }

                }

                inq[u]=0;



        }

}



int main()

{

        int n,m;

        while(scanf("%d%d",&n,&m)!=EOF)

        {

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

                        return 0;

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



                k=0;

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

                {

                            int a,b,c,d;

                            scanf("%d%d%d%d",&a,&b,&c,&d);

                            adde(a,b,c,d);

                            adde(b,a,c,d);

                }

                spfa(1);

                int ans=0;

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

                {

                        int mi=inf;

                        for(int j=head[i];j!=-1;j=G[j].next)

                        {

                                if(dis[G[j].to]+G[j].w==dis[i]&&G[j].c<mi)

                                        mi=G[j].c;

                        }

                        ans+=mi;

                }

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

        }

        return 0;



}

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

#include <cstdio>

#include <algorithm>

#include <cmath>

#include <deque>

#include <vector>

#include <queue>

#include <string>

#include <cstring>

#include <map>

#include <stack>

#include <set>

using namespace std;

typedef long long ll;

const int inf=0x3f3f3f3f;

const int INF=2147483647;

const double pi=3.1415926535897932384626;

inline ll read(){

	ll x=0,f=1;

	char ch=getchar();

	while(ch<'0'||ch>'9'){

		if(ch=='-') f=-1;

		ch=getchar();

	}

	while(ch>='0'&&ch<='9'){

		x=(x<<1)+(x<<3)+(ch^48);

		ch=getchar();

	}

	return x*f;

}

const int maxn=1e4+5;

int n,m,u,v,dd,cc,ans,d[maxn],c[maxn],vis[maxn];

struct edge{

	int to,dis,cost;

};

vector<edge> g[maxn];

void Dijkstra(){

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

	memset(d,inf,sizeof(d));

	memset(c,inf,sizeof(c));

	d[1]=0;

	c[1]=0;

	ans=0;

	while(1){

		int v=-1;

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

			if(!vis[u]&&(v==-1||d[u]<d[v])) v=u;

		}

		if(v==-1) break;

		vis[v]=1;

		ans+=c[v];

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

			int u=g[v][i].to,dis=g[v][i].dis,cost=g[v][i].cost;

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

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

				c[u]=cost;

			}

		}

	}

}

int main(){

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

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

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

			u=read(),v=read(),dd=read(),cc=read();

			g[u].push_back({v,dd,cc});

			g[v].push_back({u,dd,cc});

		}

		Dijkstra();

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

	}

	return 0;

}