stablegradients/pie-gem5-bysrc huggingface dataset:
// Original C++ solution (slower):
#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;

}

// Optimized solution to the same problem (faster):
#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;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}

// Optimized solution to the same problem (faster):
#include <cstdio>

#include <cstring>

#include <algorithm>



using namespace std;



const int inf = 0x3f3f3f3f;

const int N = 10414;

const int M = 40414;



struct Edge{

	int u, v, d, c;

	int next;

}edge[M];



int cnt, head[N];

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

int op, tp, link[18014];



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

void spfa(int n);



int main(){

	int n, m, i, u, v, d, c;

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

		cnt = 0;

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

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

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

			add_edge(u, v, d, c);

			add_edge(v, u, d, c);

		}

		spfa(n);

	}

	return 0;

}

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

	edge[cnt].u = u;

	edge[cnt].v = v;

	edge[cnt].d = d;

	edge[cnt].c = c;

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

	head[u] = cnt++;

	return;

}

void spfa(int n){

	int i, u, v, d, c, sum;

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

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

	memset(cost, inf, sizeof(cost));

	op = tp = 0;

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

	link[tp++] = 1;

	while(op < tp){

		u = link[op++];

		vis[u] = 0;

		for(i = head[u]; ~i; i = edge[i].next){

			v = edge[i].v, d = edge[i].d, c = edge[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;

					link[tp++] = v;

				}

			}

		}

	}

	sum = 0;

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

		sum += cost[i];

	}

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

	return;

}




// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}

// Optimized solution to the same problem (faster):
#include <cstdio>

#include <cstring>

#include <algorithm>



using namespace std;



const int inf = 0x3f3f3f3f;

const int N = 10414;

const int M = 40414;



struct Edge{

	int u, v, d, c;

	int next;

}edge[M];



int cnt, head[N];

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

int op, tp, link[18014];



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

void spfa(int n);



int main(){

	int n, m, i, u, v, d, c;

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

		cnt = 0;

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

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

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

			add_edge(u, v, d, c);

			add_edge(v, u, d, c);

		}

		spfa(n);

	}

	return 0;

}

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

	edge[cnt].u = u;

	edge[cnt].v = v;

	edge[cnt].d = d;

	edge[cnt].c = c;

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

	head[u] = cnt++;

	return;

}

void spfa(int n){

	int i, u, v, d, c, sum;

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

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

	memset(cost, inf, sizeof(cost));

	op = tp = 0;

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

	link[tp++] = 1;

	while(op < tp){

		u = link[op++];

		vis[u] = 0;

		for(i = head[u]; ~i; i = edge[i].next){

			v = edge[i].v, d = edge[i].d, c = edge[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;

					link[tp++] = v;

				}

			}

		}

	}

	sum = 0;

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

		sum += cost[i];

	}

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

	return;

}




// Fastest known solution for this problem:
// Original C++ solution (slower):
#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;

}

// Optimized solution to the same problem (faster):
#include <cstdio>

#include <cstring>

#include <algorithm>



using namespace std;



const int inf = 0x3f3f3f3f;

const int N = 10414;

const int M = 40414;



struct Edge{

	int u, v, d, c;

	int next;

}edge[M];



int cnt, head[N];

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

int op, tp, link[18014];



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

void spfa(int n);



int main(){

	int n, m, i, u, v, d, c;

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

		cnt = 0;

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

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

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

			add_edge(u, v, d, c);

			add_edge(v, u, d, c);

		}

		spfa(n);

	}

	return 0;

}

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

	edge[cnt].u = u;

	edge[cnt].v = v;

	edge[cnt].d = d;

	edge[cnt].c = c;

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

	head[u] = cnt++;

	return;

}

void spfa(int n){

	int i, u, v, d, c, sum;

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

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

	memset(cost, inf, sizeof(cost));

	op = tp = 0;

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

	link[tp++] = 1;

	while(op < tp){

		u = link[op++];

		vis[u] = 0;

		for(i = head[u]; ~i; i = edge[i].next){

			v = edge[i].v, d = edge[i].d, c = edge[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;

					link[tp++] = v;

				}

			}

		}

	}

	sum = 0;

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

		sum += cost[i];

	}

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

	return;

}




// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <cstdio>

#include <queue>

#include <vector>

#include <algorithm>



using namespace std;

const int INF = 0x3f3f3f3f;



const int maxn = 10240;



struct edge {

	int to, dis, cost;

	edge(int t, int d, int c) : to(t), dis(d), cost(c) {}

};





typedef pair<int, int> p;

priority_queue<p, vector<p>, greater<p> > q;

vector<edge> g[maxn];



int N, M;



void read_in() {

	//scanf("%d%d", &N, &M);

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

		g[i].clear();



	int from, to, dis, cost;

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

		scanf("%d%d%d%d", &from, &to, &dis, &cost);

		g[from].push_back(edge(to, dis, cost));

		g[to].push_back(edge(from, dis, cost));

	}

}



int solve() {

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



	const int INF = 0x7777777;

	int d[maxn];



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

		d[i] = INF;

	d[1] = 0;



	while( !q.empty() ) {

		p t = q.top();

		q.pop();



		int to = t.second, dis = t.first;

        if(d[to] < dis) continue;

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

			edge To = g[to][i];

			if(d[To.to] > d[to] + To.dis)

				d[To.to] = d[to] + To.dis,

				q.push(p(d[To.to], To.to));

		}

	}

	//show(d);

    int ans = 0;



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

        int tmp = INF;



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

            edge e = g[i][j];

            if(d[e.to] + e.dis == d[i] and e.cost < tmp)

                tmp = e.cost;

        }

        ans += tmp;

    }



    return ans;

}



int main() {

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

		read_in();

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

	}

	return 0;

}




// Optimized solution to the same problem (faster):
#include <cstdio>

#include <cstring>

#include <algorithm>



using namespace std;



const int inf = 0x3f3f3f3f;

const int N = 10414;

const int M = 40414;



struct Edge{

	int u, v, d, c;

	int next;

}edge[M];



int cnt, head[N];

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

int op, tp, link[18014];



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

void spfa(int n);



int main(){

	int n, m, i, u, v, d, c;

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

		cnt = 0;

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

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

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

			add_edge(u, v, d, c);

			add_edge(v, u, d, c);

		}

		spfa(n);

	}

	return 0;

}

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

	edge[cnt].u = u;

	edge[cnt].v = v;

	edge[cnt].d = d;

	edge[cnt].c = c;

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

	head[u] = cnt++;

	return;

}

void spfa(int n){

	int i, u, v, d, c, sum;

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

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

	memset(cost, inf, sizeof(cost));

	op = tp = 0;

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

	link[tp++] = 1;

	while(op < tp){

		u = link[op++];

		vis[u] = 0;

		for(i = head[u]; ~i; i = edge[i].next){

			v = edge[i].v, d = edge[i].d, c = edge[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;

					link[tp++] = v;

				}

			}

		}

	}

	sum = 0;

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

		sum += cost[i];

	}

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

	return;

}




// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;



#define db double

#define ll long long

#define RG register



inline int gi()

{

	RG int ret; RG bool flag; RG char ch;

	ret=0, flag=true, ch=getchar();

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

		ch == '-' ? flag=false : 0, ch=getchar();

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

		ret=(ret<<3)+(ret<<1)+ch-'0', ch=getchar();

	return flag ? ret : -ret;

}



const db pi = acos(-1.0);

const int N = 142857, inf = 1<<30;



int f[N],et[N],ed[N],nx[N],ew[N],dis[N],cst[N];

bool vis[N];

queue <int> q;

int num;



inline void add(int x,int y,int z,int w)

{

	et[++num]=y, nx[num]=f[x], ed[num]=z, ew[num]=w, f[x]=num;

}



int main()

{

	int n,m,i,x,y,z,w;

	while (true)

		{

			n=gi(), m=gi();

			if (n == 0)

				break;

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

				{

					x=gi(), y=gi(), z=gi(), w=gi();

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

				}

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

				cst[i]=dis[i]=inf;

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

			while (!q.empty())

				{

					x=q.front(), q.pop(), vis[x]=false;

					for (i=f[x]; i; i=nx[i])

						{

							y=et[i], z=ed[i], w=ew[i];

							if (dis[y] > dis[x]+z)

								{

									dis[y]=dis[x]+z;

									cst[y]=cst[x]+w;

									if (!vis[y])

										q.push(y), vis[y]=true;

								}

							if (dis[y] == dis[x]+z && cst[y] > w)

								cst[y]=w;

						}

				}

			x=0;

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

				x+=cst[i];

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

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

				f[i]=0;

			num=0;

		}

	return 0;

}

// Optimized solution to the same problem (faster):
#include <cstdio>

#include <cstring>

#include <algorithm>



using namespace std;



const int inf = 0x3f3f3f3f;

const int N = 10414;

const int M = 40414;



struct Edge{

	int u, v, d, c;

	int next;

}edge[M];



int cnt, head[N];

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

int op, tp, link[18014];



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

void spfa(int n);



int main(){

	int n, m, i, u, v, d, c;

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

		cnt = 0;

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

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

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

			add_edge(u, v, d, c);

			add_edge(v, u, d, c);

		}

		spfa(n);

	}

	return 0;

}

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

	edge[cnt].u = u;

	edge[cnt].v = v;

	edge[cnt].d = d;

	edge[cnt].c = c;

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

	head[u] = cnt++;

	return;

}

void spfa(int n){

	int i, u, v, d, c, sum;

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

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

	memset(cost, inf, sizeof(cost));

	op = tp = 0;

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

	link[tp++] = 1;

	while(op < tp){

		u = link[op++];

		vis[u] = 0;

		for(i = head[u]; ~i; i = edge[i].next){

			v = edge[i].v, d = edge[i].d, c = edge[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;

					link[tp++] = v;

				}

			}

		}

	}

	sum = 0;

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

		sum += cost[i];

	}

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

	return;

}




// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>



using namespace std;

#define REPP(i,a,b,c) for(int i=a; i<=b; i+=c)

#define REP(i,a,b) REPP(i,a,b,1)

#define REVV(i,a,b,c) for(int i=a; i>=b; i-=c)

#define REV(i,a,b) REVV(i,a,b,1)

#define FOR(i,a) REP(i,0,(int)a-1)

#define FORD(i,a) REV(i,(int)a-1,0)

#define PB push_back

#define POB pop_back

#define MP make_pair

#define FI first

#define SE second

typedef long long ll;

typedef unsigned long long ull;

typedef pair < int , int > pii;

typedef vector < int > vi;

typedef vector < pii > vii;

typedef vector < ll > vl;



const double EPS = 1e-9;

const double PI = acos(-1);

const int INF = 1e9;

const ll MOD = 1e9 + 7;



ll addMod(ll a, ll b){

	return (a+b) % MOD;

}



ll mulMod(ll a, ll b){

	return (a*b) % MOD;

}



/////////////////////////////////////////////////////////



ll cnt[15];

ll h,w,n;

map < pii , bool > flag;

int dy[] = {-2,-2,-2,-1,-1,-1,0,0,0};

int dx[] = {-2,-1,0,-2,-1,0,-2,-1,0};



bool inRange(int y, int x){

	return y > 0 && y <= h && x > 0 && x <= w;

}



int getCnt(int ty, int tx, int ny, int nx){

	int ret = 0;

	REP(i,ty,ny){

		REP(j,tx,nx){

			if(flag[MP(i,j)]) ret++;

		}

	}

	return ret;

}



void update(int y, int x){

	FOR(i,9){

		int ty = y + dy[i];

		int tx = x + dx[i];

		int ny = ty + 2;

		int nx = tx + 2;

		if(inRange(ty,tx) && inRange(ny,nx)){

			int bef = getCnt(ty,tx,ny,nx);

			cnt[bef]--;

			cnt[bef+1]++;

		}

	}

	flag[MP(y,x)] = true;

}



int main(){

	ios_base :: sync_with_stdio(0); cin.tie(0); cout.tie(0);

	cin >> h >> w >> n;

	cnt[0] = (h-2) * (w - 2);

	int y,x;

	FOR(i,n){

		cin >> y >> x;

		update(y,x);

	}

	FOR(i,10) cout << cnt[i] << endl;

	return 0;

}

// Optimized solution to the same problem (faster):
#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<algorithm>

using namespace std;

#define INF (int(1e9)+7)//1e9+7进制

#define maxn (int(1e6)+5)

typedef long long ll;

ll node[maxn];

ll res[15];

int main(void)

{

	ll H, W, N;

	scanf("%lld %lld %lld", &H, &W, &N);

	int cnt = 0;

	while (N--)

	{

		ll a, b;

		scanf("%lld %lld", &a, &b);

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

			for (int j = -1; j <= 1; j++)

				if (a + i >= 2 && a + i <= H - 1 && b + j >= 2 && b + j <= W - 1)

					node[cnt++] = (a + i) * INF + (b + j);

	}

	sort(node, node + cnt);

	ll temp = node[0];

	ll sum = 1;

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

		if (node[i] == temp)

			sum++;

		else

			res[sum]++, sum = 1, temp = node[i];

	}

	if(cnt)res[sum]++;

	res[0] = (H - 2) * (W - 2);

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

		res[0] -= res[i];

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

		printf("%lld\n", res[i]);

	return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

#define int long long

#define rg register

#define file(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);

using namespace std;

const int N=200000+10;

const int mod=1e9+7;

const int inf=1e10;

int read(){

    int x=0,f=1;char c=getchar();

    while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar();

    while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();

    return f*x;

}

int X[N],Y[N],W,H,n,res;

map<int,int> Map,f;

void calc(int x,int y){

	int X1,Y1,X2,Y2;

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

		for(int j=1;j<=3;j++){

			if(i==1&&j==1) X1=x-2,Y1=y-2,X2=x,Y2=y;

			if(i==1&&j==2) X1=x,Y1=y-2,X2=x+2,Y2=y;

			if(i==1&&j==3) X1=x-1,Y1=y-2,X2=x+1,Y2=y;

			if(i==2&&j==1) X1=x-2,Y1=y,X2=x,Y2=y+2;

			if(i==2&&j==2) X1=x,Y1=y,X2=x+2,Y2=y+2;

			if(i==2&&j==3) X1=x-1,Y1=y,X2=x+1,Y2=y+2;

			if(i==3&&j==1) X1=x-2,Y1=y-1,X2=x,Y2=y+1;

			if(i==3&&j==2) X1=x,Y1=y-1,X2=x+2,Y2=y+1;

			if(i==3&&j==3) X1=x-1,Y1=y-1,X2=x+1,Y2=y+1;

			if(X1<1||Y1<1||X2>H||Y2>W) continue;

			if(f[X1*inf+Y1]) continue;

			f[X1*inf+Y1]=1;

			int ans=0;

			res++;

			for(int i=X1;i<=X2;i++)

				for(int j=Y1;j<=Y2;j++)

					if(Map[i*inf+j])

						ans++;

			//		if(ans==0) cout<<x<<" "<<y<<" "<<X1<<" "<<Y1<<" "<<X2<<" "<<Y2<<endl;

			f[ans]++;

		}

}

main(){

	H=read(),W=read(),n=read();

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

		X[i]=read(),Y[i]=read(),Map[X[i]*inf+Y[i]]=1;

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

		calc(X[i],Y[i]);

//	exit(0);

	cout<<(H-2)*(W-2)-res<<endl;

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

		cout<<f[i]<<endl;

}


// Optimized solution to the same problem (faster):
#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<algorithm>

using namespace std;

#define INF (int(1e9)+7)//1e9+7进制

#define maxn (int(1e6)+5)

typedef long long ll;

ll node[maxn];

ll res[15];

int main(void)

{

	ll H, W, N;

	scanf("%lld %lld %lld", &H, &W, &N);

	int cnt = 0;

	while (N--)

	{

		ll a, b;

		scanf("%lld %lld", &a, &b);

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

			for (int j = -1; j <= 1; j++)

				if (a + i >= 2 && a + i <= H - 1 && b + j >= 2 && b + j <= W - 1)

					node[cnt++] = (a + i) * INF + (b + j);

	}

	sort(node, node + cnt);

	ll temp = node[0];

	ll sum = 1;

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

		if (node[i] == temp)

			sum++;

		else

			res[sum]++, sum = 1, temp = node[i];

	}

	if(cnt)res[sum]++;

	res[0] = (H - 2) * (W - 2);

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

		res[0] -= res[i];

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

		printf("%lld\n", res[i]);

	return 0;

}

// Fastest known solution for this problem: