#include <bits/stdc++.h>
using namespace std;
int used[1001][1001];
struct abc{
	int xx;
	int yy;
	int ax;
};
queue < abc > q[10];
int ans[10];
bool check () {
	for (int k=1;k<=9;k++) {
		if (q[k].size()>0) {
			return 1;
		}
	}
	return 0;
}
int main () {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int x,y,p;
	cin>>x>>y>>p;
	int a[p+1],g[4]={0,-1,1,0};
	for (int k=1;k<=p;k++) cin>>a[k];
	char h[x+1][y+1];
	for (int k=1;k<=x;k++) {
		for (int j=1;j<=y;j++) {
			cin>>h[k][j];
		}
	}
	for (int ch=1;ch<=p;ch++) {
		for (int k=1;k<=x;k++) {
			for (int j=1;j<=y;j++) {
				if (ch==h[k][j]-48) {
					if (h[k][j+1]=='.'||h[k][j-1]=='.'||h[k+1][j]=='.'||h[k-1][j]=='.') q[ch].push({k,j,a[ch]});
					used[k][j]=1;
					ans[ch]++;
				}
			}
		}
	}
	int op=1;
	while (check()) {
		vector < abc > auf;
		while (!q[op].empty()) {
			if (q[op].size()>=30000 ) {
				while (1) {
				}
			}
			abc v=q[op].front();
			q[op].pop();
			for (int k=0;k<4;k++) {
				for (int j=k+1;j<4;j++) {
					if (abs(g[k])!=abs(g[j])&&used[v.xx+g[k]][v.yy+g[j]]==0&&v.xx+g[k]<=x&&v.xx+g[k]>=1&&v.yy+g[j]<=y&&v.yy+g[j]>=1) {
						if (h[v.xx+g[k]][v.yy+g[j]]=='.') {
							if (v.ax>0) {
								q[op].push({v.xx+g[k],v.yy+g[j],v.ax-1});
								used[v.xx+g[k]][v.yy+g[j]]=1;
								ans[op]++;
							}
							else  {
								if (auf.size()>0) {
									for (int rame=0;rame<auf.size();rame++) {
										if (auf[rame].xx!=v.xx||auf[rame].yy!=v.yy) {
											auf.push_back({v.xx,v.yy,a[op]});
										}
									}
								}
								else auf.push_back({v.xx,v.yy,a[op]});
							}
						}
					}
				}
			}
		}
		for (int k=0;k<auf.size();k++) {
			q[op].push(auf[k]);
			used[auf[k].xx][auf[k].yy]=1;
		}
		op++;
		if (op==p+1) op=1;
	}
	for (int k=1;k<=p;k++) cout<<ans[k]<<' ';
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int used[1001][1001];
struct abc{
	int xx;
	int yy;
	int ax;
};
queue < abc > q[10];
int ans[10];
bool check () {
	for (int k=1;k<=9;k++) {
		if (q[k].size()>0) {
			return 1;
		}
	}
	return 0;
}
int main () {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int x,y,p;
	cin>>x>>y>>p;
	int a[p+1],g[4]={0,-1,1,0};
	for (int k=1;k<=p;k++) cin>>a[k];
	char h[x+1][y+1];
	for (int k=1;k<=x;k++) {
		for (int j=1;j<=y;j++) {
			cin>>h[k][j];
		}
	}
	for (int ch=1;ch<=p;ch++) {
		for (int k=1;k<=x;k++) {
			for (int j=1;j<=y;j++) {
				if (ch==h[k][j]-48) {
					if (h[k][j+1]=='.'||h[k][j-1]=='.'||h[k+1][j]=='.'||h[k-1][j]=='.') q[ch].push({k,j,a[ch]});
					used[k][j]=1;
					ans[ch]++;
				}
			}
		}
	}
	int op=1;
	while (check()) {
		vector < abc > auf;
		while (!q[op].empty()) {
			if (q[op].size()>=20000 ) {
				while (1) {
				}
			}
			abc v=q[op].front();
			q[op].pop();
			for (int k=0;k<4;k++) {
				for (int j=k+1;j<4;j++) {
					if (abs(g[k])!=abs(g[j])&&used[v.xx+g[k]][v.yy+g[j]]==0&&v.xx+g[k]<=x&&v.xx+g[k]>=1&&v.yy+g[j]<=y&&v.yy+g[j]>=1) {
						if (h[v.xx+g[k]][v.yy+g[j]]=='.') {
							if (v.ax>0) {
								q[op].push({v.xx+g[k],v.yy+g[j],v.ax-1});
								used[v.xx+g[k]][v.yy+g[j]]=1;
								ans[op]++;
							}
							else  {
								if (auf.size()>0) {
									for (int rame=0;rame<auf.size();rame++) {
										if (auf[rame].xx!=v.xx||auf[rame].yy!=v.yy) {
											auf.push_back({v.xx,v.yy,a[op]});
										}
									}
								}
								else auf.push_back({v.xx,v.yy,a[op]});
							}
						}
					}
				}
			}
		}
		for (int k=0;k<auf.size();k++) {
			q[op].push(auf[k]);
			used[auf[k].xx][auf[k].yy]=1;
		}
		op++;
		if (op==p+1) op=1;
	}
	for (int k=1;k<=p;k++) cout<<ans[k]<<' ';
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int used[1001][1001];
struct abc{
	int xx;
	int yy;
	int ax;
};
queue < abc > q[10];
int ans[10];
bool check () {
	for (int k=1;k<=9;k++) {
		if (q[k].size()>0) {
			return 1;
		}
	}
	return 0;
}
int main () {
	int x,y,p;
	cin>>x>>y>>p;
	int a[p+1],g[4]={0,-1,1,0};
	for (int k=1;k<=p;k++) cin>>a[k];
	char h[x+1][y+1];
	for (int k=1;k<=x;k++) {
		for (int j=1;j<=y;j++) {
			cin>>h[k][j];
		}
	}
	for (int ch=1;ch<=p;ch++) {
		for (int k=1;k<=x;k++) {
			for (int j=1;j<=y;j++) {
				if (ch==h[k][j]-48) {
					if (h[k][j+1]=='.'||h[k][j-1]=='.'||h[k+1][j]=='.'||h[k-1][j]=='.') q[ch].push({k,j,a[ch]});
					used[k][j]=1;
					ans[ch]++;
				}
			}
		}
	}
	int op=1;
	while (check()) {
		vector < abc > auf;
		while (!q[op].empty()) {
			abc v=q[op].front();
			q[op].pop();
			for (int k=0;k<4;k++) {
				for (int j=k+1;j<4;j++) {
					if (abs(g[k])!=abs(g[j])&&used[v.xx+g[k]][v.yy+g[j]]==0&&v.xx+g[k]<=x&&v.xx+g[k]>=1&&v.yy+g[j]<=y&&v.yy+g[j]>=1) {
						if (h[v.xx+g[k]][v.yy+g[j]]=='.') {
							if (v.ax>0) {
								q[op].push({v.xx+g[k],v.yy+g[j],v.ax-1});
								used[v.xx+g[k]][v.yy+g[j]]=1;
								ans[op]++;
							}
							else  {
								if (auf.size()>0) {
									for (int rame=0;rame<auf.size();rame++) {
										if (auf[rame].xx!=v.xx||auf[rame].yy!=v.yy) {
											auf.push_back({v.xx,v.yy,a[op]});
										}
									}
								}
								else auf.push_back({v.xx,v.yy,a[op]});
							}
						}
					}
				}
			}
		}
		for (int k=0;k<auf.size();k++) {
			q[op].push(auf[k]);
			used[auf[k].xx][auf[k].yy]=1;
		}
		op++;
		if (op==p+1) op=1;
	}
	for (int k=1;k<=p;k++) cout<<ans[k]<<' ';
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int used[1001][1001];
struct abc{
	int xx;
	int yy;
	int ax;
};
queue < abc > q[10];
int ans[10];
bool check () {
	for (int k=1;k<=9;k++) {
		if (q[k].size()>0) {
			return 1;
		}
	}
	return 0;
}
int main () {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int x,y,p;
	cin>>x>>y>>p;
	int a[p+1],g[4]={0,-1,1,0};
	for (int k=1;k<=p;k++) cin>>a[k];
	char h[x+1][y+1];
	for (int k=1;k<=x;k++) {
		for (int j=1;j<=y;j++) {
			cin>>h[k][j];
			q[0].push({1,1,1});
		}
	}
	for (int ch=1;ch<=p;ch++) {
		for (int k=1;k<=x;k++) {
			for (int j=1;j<=y;j++) {
				if (ch==h[k][j]-48) {
					if (h[k][j+1]=='.'||h[k][j-1]=='.'||h[k+1][j]=='.'||h[k-1][j]=='.') q[ch].push({k,j,a[ch]});
					used[k][j]=1;
					ans[ch]++;
				}
			}
		}
	}
	int op=1;
	while (check()) {
		vector < abc > auf;
		while (!q[op].empty()) {
			abc v=q[op].front();
			q[op].pop();
			for (int k=0;k<4;k++) {
				for (int j=k+1;j<4;j++) {
					if (abs(g[k])!=abs(g[j])&&used[v.xx+g[k]][v.yy+g[j]]==0&&v.xx+g[k]<=x&&v.xx+g[k]>=1&&v.yy+g[j]<=y&&v.yy+g[j]>=1) {
						if (h[v.xx+g[k]][v.yy+g[j]]=='.') {
							if (v.ax>0) {
								q[op].push({v.xx+g[k],v.yy+g[j],v.ax-1});
								used[v.xx+g[k]][v.yy+g[j]]=1;
								ans[op]++;
							}
							else  {
								if (auf.size()>0) {
									for (int rame=0;rame<auf.size();rame++) {
										if (auf[rame].xx!=v.xx||auf[rame].yy!=v.yy) {
											auf.push_back({v.xx,v.yy,a[op]});
										}
									}
								}
								else auf.push_back({v.xx,v.yy,a[op]});
							}
						}
					}
				}
			}
		}
		for (int k=0;k<auf.size();k++) {
			q[op].push(auf[k]);
			used[auf[k].xx][auf[k].yy]=1;
		}
		op++;
		if (op==p+1) op=1;
	}
	for (int k=1;k<=p;k++) cout<<ans[k]<<' ';
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
int used[1001][1001];
struct abc{
	int xx;
	int yy;
	int ax;
};
queue < abc > q[10];
int ans[10];
bool check () {
	for (int k=1;k<=9;k++) {
		if (q[k].size()>0) {
			return 1;
		}
	}
	return 0;
}
int main () {
	int x,y,p;
	cin>>x>>y>>p;
	int a[p+1],g[4]={0,-1,1,0};
	for (int k=1;k<=p;k++) cin>>a[k];
	char h[x+1][y+1];
	for (int k=1;k<=x;k++) {
		for (int j=1;j<=y;j++) {
			cin>>h[k][j];
		}
	}
	for (int ch=1;ch<=p;ch++) {
		for (int k=1;k<=x;k++) {
			for (int j=1;j<=y;j++) {
				if (ch==h[k][j]-48) {
					q[ch].push({k,j,a[ch]});
					used[k][j]=1;
				}
			}
		}
	}
	ans[1]=ans[2]=ans[3]=ans[4]=ans[5]=ans[6]=ans[7]=ans[8]=ans[9]=1;int op=1;
	while (check()) {
		vector < abc > auf;
		while (!q[op].empty()) {
			abc v=q[op].front();
			q[op].pop();
			for (int k=0;k<4;k++) {
				for (int j=k+1;j<4;j++) {
					if (abs(g[k])!=abs(g[j])&&used[v.xx+g[k]][v.yy+g[j]]==0&&v.xx+g[k]<=x&&v.xx+g[k]>=1&&v.yy+g[j]<=y&&v.yy+g[j]>=1) {
						if (h[v.xx+g[k]][v.yy+g[j]]=='.'||h[v.xx+g[k]][v.yy+g[j]]==op) {
							if (v.ax>0) {
								q[op].push({v.xx+g[k],v.yy+g[j],v.ax-1});
								used[v.xx+g[k]][v.yy+g[j]]=1;
								ans[op]++;
							}
							else  {
								if (auf.size()>0) {
									for (int rame=0;rame<auf.size();rame++) {
										if (auf[rame].xx!=v.xx||auf[rame].yy!=v.yy) {
											auf.push_back({v.xx,v.yy,a[op]});
										}
									}
								}
								else auf.push_back({v.xx,v.yy,a[op]});
							}
						}
					}
				}
			}
		}
		for (int k=0;k<auf.size();k++) {
			q[op].push(auf[k]);
			used[auf[k].xx][auf[k].yy]=1;
		}
		op++;
		if (op==p+1) op=1;
	}
	for (int k=1;k<=p;k++) cout<<ans[k]<<' ';
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define DB(x) cout << #x << " == " << x << "\n";
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define ll long long
using namespace std;

struct point {
	long long x, y, dist;
	point(long long _x, long long _y, long long _dist) {
		x = _x;
		y = _y;
		dist = _dist;
	}
};

long long n, m, p, sp[15], cnt[15] = { 0, }, dirx[4] = { 1, -1, 0, 0 }, diry[4] = { 0,
		0, 1, -1 };
char grid[1019][1019] = { { '\0', } };
vector<point> go[15][2];

int main() {
	cin.tie(0);
	cout.tie(0);
	ios_base::sync_with_stdio(0);
	cin >> n >> m >> p;
	for (long long i = 1; i <= p; i++) {
		cin >> sp[i];
	}
	for (long long i = 0; i < n; i++)
		for (long long j = 0; j < m; j++) {
			cin >> grid[i][j];
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				go[(grid[i][j] - '0')][1].emplace_back(i, j, 0);
			}
		}

	long long i;
	bool cont = true;
	for (long long t = 1; cont; t++) {
		cont = false;
		i = t & 1;
		for (int ply = 1; ply <= p; ply++) {
			cont |= !go[ply][i].empty();
			while (!go[ply][i].empty()) {
				point v = go[ply][i].back();
				go[ply][i].pop_back();
				grid[v.x][v.y] = '0' + ply;
				if (v.dist == sp[ply]) {
					go[ply][i ^ 1].emplace_back(v.x, v.y, 0);
				} else {
					for (int j = 0; j < 4; j++) {
						if (v.y + diry[j] >= 0 && v.x + dirx[j] >= 0 && v.y + diry[j] < n && v.x + dirx[j] < m
								&& grid[v.x + dirx[j]][v.y + diry[j]] == '.') {
							go[ply][i].emplace_back(v.x + dirx[j], v.y + diry[j],
									v.dist + 1);
						}
					}
				}
			}
		}
	}
	for (long long i = 0; i < n; i++)
		for (long long j = 0; j < m; j++) {
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				cnt[(grid[i][j] - '0')]++;
			}
		}
	for (long long i = 1; i <= p; i++) {
			printf("%lld ", cnt[i]);
	}
}


#include <bits/stdc++.h>
using namespace std;
#define DB(x) cout << #x << " == " << x << "\n";
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define ll long long
using namespace std;

struct point {
	long long x, y, dist;
	point(long long _x, long long _y, long long _dist) {
		x = _x;
		y = _y;
		dist = _dist;
	}
};

long long n, m, p, sp[15], cnt[15] = { 0, }, dirx[4] = { 1, -1, 0, 0 }, diry[4] = { 0,
		0, 1, -1 };
char grid[1019][1019] = { { '\0', } };
vector<point> go[15][2];

int main() {
	cin.tie(0);
	cout.tie(0);
	ios_base::sync_with_stdio(0);
	cin >> n >> m >> p;
	for (long long i = 1; i <= p; i++) {
		cin >> sp[i];
	}
	for (long long i = 0; i < n; i++)
		for (long long j = 0; j < m; j++) {
			cin >> grid[i][j];
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				go[(grid[i][j] - '0')][1].emplace_back(i, j, 0);
			}
		}

	long long i;
	bool cont = true;
	for (long long t = 1; cont; t++) {
		cont = false;
		i = t & 1;
		for (int ply = 1; ply <= p; ply++) {
			cont |= !go[ply][i].empty();
			while (!go[ply][i].empty()) {
				point v = go[ply][i].back();
				go[ply][i].pop_back();
				grid[v.x][v.y] = '0' + ply;
				if (v.dist == sp[ply]) {
					go[ply][i ^ 1].emplace_back(v.x, v.y, 0);
				} else {
					for (int j = 0; j < 4; j++) {
						if (v.y + diry[j] >= 0 && v.x + dirx[j] >= 0
								&& grid[v.x + dirx[j]][v.y + diry[j]] == '.') {
							go[ply][i].emplace_back(v.x + dirx[j], v.y + diry[j],
									v.dist + 1);
						}
					}
				}
			}
		}
	}
	for (long long i = 0; i < n; i++)
		for (long long j = 0; j < m; j++) {
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				cnt[(grid[i][j] - '0')]++;
			}
		}
	for (long long i = 1; i <= p; i++) {
			printf("%lld ", cnt[i]);
	}
}


#include <bits/stdc++.h>
using namespace std;
#define DB(x) cout << #x << " == " << x << "\n";
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define ll long long
using namespace std;

struct point {
	long long x, y, dist;
	point(long long _x, long long _y, long long _dist) {
		x = _x;
		y = _y;
		dist = _dist;
	}
};

long long n, m, p, sp[15], cnt[15] = { 0, }, dirx[4] = { 1, -1, 0, 0 }, diry[4] = { 0,
		0, 1, -1 };
char grid[1019][1019] = { { '\0', } };
vector<point> go[15][2];

int main() {
	cin.tie(0);
	cout.tie(0);
	ios_base::sync_with_stdio(0);
	cin >> n >> m >> p;
	for (long long i = 1; i <= p; i++) {
		cin >> sp[i];
	}
	for (long long i = 0; i < n; i++)
		for (long long j = 0; j < m; j++) {
			cin >> grid[i][j];
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				go[(grid[i][j] - '0')][1].emplace_back(i, j, 0);
			}
		}

	long long i;
	bool cont = true;
	for (long long t = 1; cont; t++) {
		cont = false;
		i = t & 1;
		for (int ply = 1; ply <= p; ply++) {
			cont |= !go[ply][i].empty();
			while (!go[ply][i].empty()) {
				point v = go[ply][i].back();
				go[ply][i].pop_back();
				grid[v.x][v.y] = '0' + ply;
				if (v.dist == sp[ply]) {
					go[ply][i ^ 1].emplace_back(v.x, v.y, 0);
				} else {
					for (int j = 0; j < 4; j++) {
						if (v.y + diry[j] >= 0 && v.x + dirx[j] >= 0 && v.y + diry[j] < n && v.x + dirx[j] <
								&& grid[v.x + dirx[j]][v.y + diry[j]] == '.') {
							go[ply][i].emplace_back(v.x + dirx[j], v.y + diry[j],
									v.dist + 1);
						}
					}
				}
			}
		}
	}
	for (long long i = 0; i < n; i++)
		for (long long j = 0; j < m; j++) {
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				cnt[(grid[i][j] - '0')]++;
			}
		}
	for (long long i = 1; i <= p; i++) {
			printf("%lld ", cnt[i]);
	}
}


#include <bits/stdc++.h>
using namespace std;
#define DB(x) cout << #x << " == " << x << "\n";
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define ll long long
using namespace std;

struct point {
	long long x, y, dist;
	point(long long _x, long long _y, long long _dist) {
		x = _x;
		y = _y;
		dist = _dist;
	}
};

long long n, m, p, sp[15], cnt[15] = { 0, }, dirx[4] = { 1, -1, 0, 0 }, diry[4] = { 0,
		0, 1, -1 };
char grid[1019][1019] = { { '\0', } };
bool vis[1019][1019] = { { 0, } };
list<point> go[15][2];

int main() {
	cin.tie(0);
	cout.tie(0);
	ios_base::sync_with_stdio(0);
	cin >> n >> m >> p;
	for (long long i = 1; i <= p; i++) {
		cin >> sp[i];
	}
	for (long long i = 0; i < n; i++)
		for (long long j = 0; j < m; j++) {
			cin >> grid[i][j];
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				go[(grid[i][j] - '0')][1].emplace_front(i, j, 0);
			}
		}
	long long i;
	bool cont = true;
	for (long long t = 1; cont; t++) {
		cont = false;
		i = t & 1;
		for (int ply = 1; ply <= p; ply++) {
			cont |= !go[ply][i].empty();
			while (!go[ply][i].empty()) {
				point v = go[ply][i].back();
				go[ply][i].pop_back();
				grid[v.x][v.y] = '0' + ply;
				if (v.dist == sp[ply]) {
					go[ply][i ^ 1].emplace_front(v.x, v.y, 0);
				} else {
					for (int j = 0; j < 4; j++) {
						if (v.y + diry[j] >= 0 && v.x + dirx[j] >= 0 && v.y + diry[j] < m && v.x + dirx[j] < n
								&& grid[v.x + dirx[j]][v.y + diry[j]] == '.' && !vis[i][j]) {
							go[ply][i].emplace_front(v.x + dirx[j], v.y + diry[j],
									v.dist + 1), vis[i][j] = 1;
						}
					}
				}
			}
		}
	}
	for (long long i = 0; i < n; i++)
		for (long long j = 0; j < m; j++) {
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				cnt[(grid[i][j] - '0')]++;
			}
		}
	for (long long i = 1; i <= p; i++) {
			printf("%lld ", cnt[i]);
	}
}


#include <bits/stdc++.h>
using namespace std;
#define DB(x) cout << #x << " == " << x << "\n";
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define ll long long
using namespace std;

struct point {
	int x, y, dist;
	point(int _x, int _y, int _dist) {
		x = _x;
		y = _y;
		dist = _dist;
	}
};

int n, m, p, sp[15], cnt[15] = { 0, }, dirx[4] = { 1, -1, 0, 0 }, diry[4] = { 0,
		0, 1, -1 };
char grid[1019][1019] = { { '#', } };
vector<point> go[15][2];

int main() {
	cin.tie(0);
	cout.tie(0);
	ios_base::sync_with_stdio(0);
	cin >> n >> m >> p;
	for (int i = 1; i <= p; i++) {
		cin >> sp[i];
	}
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++) {
			cin >> grid[i][j];
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				go[(grid[i][j] - '0')][1].emplace_back(i, j, 0);
			}
		}

	int i;
	bool cont = true;
	for (int t = 1; cont; t++) {
		cont = false;
		i = t & 1;
		for (int ply = 1; ply <= p; ply++) {
			cont |= !go[ply][i].empty();
			while (!go[ply][i].empty()) {
				point v = go[ply][i].back();
				go[ply][i].pop_back();
				grid[v.x][v.y] = '0' + ply;
				if (v.dist == sp[ply]) {
					go[ply][i ^ 1].emplace_back(v.x, v.y, 0);
				} else {
					for (int j = 0; j < 4; j++) {
						if (v.y + diry[j] >= 0 && v.x + dirx[j] >= 0
								&& grid[v.x + dirx[j]][v.y + diry[j]] == '.') {
							go[ply][i].emplace_back(v.x + dirx[j], v.y + diry[j],
									v.dist + 1);
						}
					}
				}
			}
		}
	}
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++) {
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				cnt[(grid[i][j] - '0')]++;
			}
		}
	for (int i = 1; i <= p; i++) {
			cout << cnt[i] << " ";
	}
}


#include <bits/stdc++.h>
using namespace std;
#define DB(x) cout << #x << " == " << x << "\n";
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define ll long long
using namespace std;

struct point {
	short x, y, dist;
	point(short _x, short _y, short _dist) {
		x = _x;
		y = _y;
		dist = _dist;
	}
};

int n, m, p, sp[15], cnt[15] = { 0, }, dirx[4] = { 1, -1, 0, 0 }, diry[4] = { 0,
		0, 1, -1 };
char grid[1019][1019] = { { '#', } };
vector<point> go[15][2];
bool vis[1050][1050] = { {false, }, };

int main() {
	cin.tie(0);
	cout.tie(0);
	ios_base::sync_with_stdio(0);
	cin >> n >> m >> p;
	for (short i = 1; i <= p; i++) {
		cin >> sp[i];
	}
	for (short i = 0; i < n; i++)
		for (short j = 0; j < m; j++) {
			cin >> grid[i][j];
			if(grid[i][j])
				vis[i][j] = true;
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				go[(grid[i][j] - '0')][1].emplace_back(i, j, 0);
			}
		}

	int i;
	bool cont = true;
	for (int t = 1; cont; t++) {
		cont = false;
		i = t & 1;
		for (int ply = 1; ply <= p; ply++) {
			cont |= !go[ply][i].empty();
			while (!go[ply][i].empty()) {
				point v = go[ply][i].back();
				go[ply][i].pop_back();
				grid[v.x][v.y] = '0' + ply;
				if (v.dist == sp[ply]) {
					go[ply][i ^ 1].emplace_back(v.x, v.y, 0);
				} else {
					for (int j = 0; j < 4; j++) {
						if (v.y + diry[j] >= 0 && v.x + dirx[j] >= 0
								&& vis[v.x + dirx[j]][v.y + diry[j]] && grid[v.x + dirx[j]][v.y + diry[j]] == '.') {
							vis[v.x + dirx[j]][v.y + diry[j]] = true;
							go[ply][i].emplace_back(v.x + dirx[j], v.y + diry[j],
									v.dist + 1);
						}
					}
				}
			}
		}
	}
	for (short i = 0; i < n; i++)
		for (short j = 0; j < m; j++) {
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				cnt[(grid[i][j] - '0')]++;
			}
		}
	for (int i = 1; i <= p; i++) {
			cout << cnt[i] << " ";
	}
}


#include <bits/stdc++.h>
using namespace std;
#define DB(x) cout << #x << " == " << x << "\n";
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define ll long long
using namespace std;

struct point {
	short x, y, dist;
	point(short _x, short _y, short _dist) {
		x = _x;
		y = _y;
		dist = _dist;
	}
};

int n, m, p, sp[15], cnt[15] = { 0, }, dirx[4] = { 1, -1, 0, 0 }, diry[4] = { 0,
		0, 1, -1 };
char grid[1019][1019] = { { '#', } };
queue<point> go[15][2];
bool vis[1050][1050] = { {false, }, };

int main() {
	cin.tie(0);
	cout.tie(0);
	ios_base::sync_with_stdio(0);
	cin >> n >> m >> p;
	for (short i = 1; i <= p; i++) {
		cin >> sp[i];
	}
	for (short i = 0; i < n; i++)
		for (short j = 0; j < m; j++) {
			cin >> grid[i][j];
			if(grid[i][j])
				vis[i][j] = true;
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				go[(grid[i][j] - '0')][1].emplace(i, j, 0);
			}
		}

	int i;
	bool cont = true;
	for (int t = 1; cont; t++) {
		cont = false;
		i = t & 1;
		for (int ply = 1; ply <= p; ply++) {
			cont |= !go[ply][i].empty();
			while (!go[ply][i].empty()) {
				point v = go[ply][i].front();
				go[ply][i].pop();
				grid[v.x][v.y] = '0' + ply;
				if (v.dist == sp[ply]) {
					go[ply][i ^ 1].emplace(v.x, v.y, 0);
				} else {
					for (int j = 0; j < 4; j++) {
						if (v.y + diry[j] >= 0 && v.x + dirx[j] >= 0
								&& vis[v.x + dirx[j]][v.y + diry[j]] && grid[v.x + dirx[j]][v.y + diry[j]] == '.') {
							vis[v.x + dirx[j]][v.y + diry[j]] = true;
							go[ply][i].emplace(v.x + dirx[j], v.y + diry[j],
									v.dist + 1);
						}
					}
				}
			}
		}
	}
	for (short i = 0; i < n; i++)
		for (short j = 0; j < m; j++) {
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				cnt[(grid[i][j] - '0')]++;
			}
		}
	for (int i = 1; i <= p; i++) {
			cout << cnt[i] << " ";
	}
}


#include <bits/stdc++.h>
using namespace std;
#define DB(x) cout << #x << " == " << x << "\n";
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define ll long long
using namespace std;

struct point {
	long long x, y, dist;
	point(long long _x, long long _y, long long _dist) {
		x = _x;
		y = _y;
		dist = _dist;
	}
};

long long n, m, p, sp[15], cnt[15] = { 0, }, dirx[4] = { 1, -1, 0, 0 }, diry[4] = { 0,
		0, 1, -1 };
char grid[1019][1019] = { { '\0', } };
list<point> go[15][2];

int main() {
	cin.tie(0);
	cout.tie(0);
	ios_base::sync_with_stdio(0);
	cin >> n >> m >> p;
	for (long long i = 1; i <= p; i++) {
		cin >> sp[i];
	}
	for (long long i = 0; i < n; i++)
		for (long long j = 0; j < m; j++) {
			cin >> grid[i][j];
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				go[(grid[i][j] - '0')][1].emplace_front(i, j, 0);
			}
		}
	long long i;
	bool cont = true;
	for (long long t = 1; cont; t++) {
		cont = false;
		i = t & 1;
		for (int ply = 1; ply <= p; ply++) {
			cont |= !go[ply][i].empty();
			while (!go[ply][i].empty()) {
				point v = go[ply][i].back();
				go[ply][i].pop_back();
				grid[v.x][v.y] = '0' + ply;
				if (v.dist == sp[ply]) {
					go[ply][i ^ 1].emplace_front(v.x, v.y, 0);
				} else {
					for (int j = 0; j < 4; j++) {
						if (v.y + diry[j] >= 0 && v.x + dirx[j] >= 0 && v.y + diry[j] < m && v.x + dirx[j] < n
								&& grid[v.x + dirx[j]][v.y + diry[j]] == '.') {
							go[ply][i].emplace_front(v.x + dirx[j], v.y + diry[j],
									v.dist + 1);
						}
					}
				}
			}
		}
	}
	for (long long i = 0; i < n; i++)
		for (long long j = 0; j < m; j++) {
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				cnt[(grid[i][j] - '0')]++;
			}
		}
	for (long long i = 1; i <= p; i++) {
			printf("%lld ", cnt[i]);
	}
}


#include <bits/stdc++.h>
using namespace std;
#define DB(x) cout << #x << " == " << x << "\n";
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define ll long long
using namespace std;

struct point {
	long long x, y, dist;
	point(long long _x, long long _y, long long _dist) {
		x = _x;
		y = _y;
		dist = _dist;
	}
};

long long n, m, p, sp[15], cnt[15] = { 0, }, dirx[4] = { 1, -1, 0, 0 }, diry[4] = { 0,
		0, 1, -1 };
char grid[1019][1019] = { { '\0', } };
bool vis[1019][1019] = { { 0, } };
list<point> go[15][2];

int main() {
	cin.tie(0);
	cout.tie(0);
	ios_base::sync_with_stdio(0);
	cin >> n >> m >> p;
	for (long long i = 1; i <= p; i++) {
		cin >> sp[i];
	}
	for (long long i = 0; i < n; i++)
		for (long long j = 0; j < m; j++) {
			cin >> grid[i][j];
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				go[(grid[i][j] - '0')][1].emplace_front(i, j, 0);
			}
		}
	long long i;
	bool cont = true;
	for (long long t = 1; cont; t++) {
		cont = false;
		i = t & 1;
		for (int ply = 1; ply <= p; ply++) {
			cont |= !go[ply][i].empty();
			while (!go[ply][i].empty()) {
				point v = go[ply][i].back();
				go[ply][i].pop_back();
				grid[v.x][v.y] = '0' + ply;
				if (v.dist == sp[ply]) {
					go[ply][i ^ 1].emplace_front(v.x, v.y, 0);
				} else {
					for (int j = 0; j < 4; j++) {
						if (v.y + diry[j] >= 0 && v.x + dirx[j] >= 0 && v.y + diry[j] < m && v.x + dirx[j] < n
								&& grid[v.x + dirx[j]][v.y + diry[j]] == '.' && !vis[v.x + dirx[j]][v.y + diry[j]]) {
							go[ply][i].emplace_front(v.x + dirx[j], v.y + diry[j],
									v.dist + 1), vis[v.x + dirx[j]][v.y + diry[j]] = 1;
						}
					}
				}
			}
		}
	}
	for (long long i = 0; i < n; i++)
		for (long long j = 0; j < m; j++) {
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				cnt[(grid[i][j] - '0')]++;
			}
		}
	for (long long i = 1; i <= p; i++) {
			printf("%lld ", cnt[i]);
	}
}


#include <bits/stdc++.h>
using namespace std;
#define DB(x) cout << #x << " == " << x << "\n";
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define ll long long
using namespace std;

struct point {
	long long x, y, dist;
	point(long long _x, long long _y, long long _dist) {
		x = _x;
		y = _y;
		dist = _dist;
	}
};

long long n, m, p, sp[15], cnt[15] = { 0, }, dirx[4] = { 1, -1, 0, 0 }, diry[4] = { 0,
		0, 1, -1 };
char grid[1019][1019] = { { '\0', } };
vector<point> go[15][2];

int main() {
	cin.tie(0);
	cout.tie(0);
	ios_base::sync_with_stdio(0);
	cin >> n >> m >> p;
	for (long long i = 1; i <= p; i++) {
		cin >> sp[i];
	}
	for (long long i = 0; i < n; i++)
		for (long long j = 0; j < m; j++) {
			cin >> grid[i][j];
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				go[(grid[i][j] - '0')][1].emplace_back(i, j, 0);
			}
		}

	long long i;
	bool cont = true;
	for (long long t = 1; cont; t++) {
		cont = false;
		i = t & 1;
		for (int ply = 1; ply <= p; ply++) {
			cont |= !go[ply][i].empty();
			while (!go[ply][i].empty()) {
				point v = go[ply][i].back();
				go[ply][i].pop_back();
				grid[v.x][v.y] = '0' + ply;
				if (v.dist == sp[ply]) {
					go[ply][i ^ 1].emplace_back(v.x, v.y, 0);
				} else {
					for (int j = 0; j < 4; j++) {
						if (v.y + diry[j] >= 0 && v.x + dirx[j] >= 0 && v.y + diry[j] < m && v.x + dirx[j] < n
								&& grid[v.x + dirx[j]][v.y + diry[j]] == '.') {
							go[ply][i].emplace_back(v.x + dirx[j], v.y + diry[j],
									v.dist + 1);
						}
					}
				}
			}
		}
	}
	for (long long i = 0; i < n; i++)
		for (long long j = 0; j < m; j++) {
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				cnt[(grid[i][j] - '0')]++;
			}
		}
	for (long long i = 1; i <= p; i++) {
			printf("%lld ", cnt[i]);
	}
}


#include <bits/stdc++.h>
using namespace std;
#define DB(x) cout << #x << " == " << x << "\n";
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define ll long long
using namespace std;

struct point {
	short x, y, dist;
	point(short _x, short _y, short _dist) {
		x = _x;
		y = _y;
		dist = _dist;
	}
};

int n, m, p, sp[15], cnt[15] = { 0, }, dirx[4] = { 1, -1, 0, 0 }, diry[4] = { 0,
		0, 1, -1 };
char grid[1019][1019] = { { '#', } };
vector<point> go[15][2];
bool vis[1050][1050] = { {false, }, };

int main() {
	cin.tie(0);
	cout.tie(0);
	ios_base::sync_with_stdio(0);
	cin >> n >> m >> p;
	for (short i = 1; i <= p; i++) {
		cin >> sp[i];
	}
	for (short i = 0; i < n; i++)
		for (short j = 0; j < m; j++) {
			cin >> grid[i][j];
			if(grid[i][j])
				vis[i][j] = true;
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				go[(grid[i][j] - '0')][1].emplace_back(i, j, 0);
			}
		}

	int i;
	bool cont = true;
	for (int t = 1; cont; t++) {
		cont = false;
		i = t & 1;
		for (int ply = 1; ply <= p; ply++) {
			cont |= !go[ply][i].empty();
			while (!go[ply][i].empty()) {
				point v = go[ply][i].front();
				go[ply][i].pop_back();
				grid[v.x][v.y] = '0' + ply;
				if (v.dist == sp[ply]) {
					go[ply][i ^ 1].emplace_back(v.x, v.y, 0);
				} else {
					for (int j = 0; j < 4; j++) {
						if (v.y + diry[j] >= 0 && v.x + dirx[j] >= 0
								&& vis[v.x + dirx[j]][v.y + diry[j]] && grid[v.x + dirx[j]][v.y + diry[j]] == '.') {
							vis[v.x + dirx[j]][v.y + diry[j]] = true;
							go[ply][i].emplace_back(v.x + dirx[j], v.y + diry[j],
									v.dist + 1);
						}
					}
				}
			}
		}
	}
	for (short i = 0; i < n; i++)
		for (short j = 0; j < m; j++) {
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				cnt[(grid[i][j] - '0')]++;
			}
		}
	for (int i = 1; i <= p; i++) {
			cout << cnt[i] << " ";
	}
}


#include <bits/stdc++.h>
using namespace std;
#define DB(x) cout << #x << " == " << x << "\n";
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define ll long long
using namespace std;

struct point {
	int x, y, dist;
	point(int _x, int _y, int _dist) {
		x = _x;
		y = _y;
		dist = _dist;
	}
};

int n, m, p, sp[15], cnt[15] = { 0, }, dirx[4] = { 1, -1, 0, 0 }, diry[4] = { 0,
		0, 1, -1 };
char grid[1019][1019] = { { '#', } };
queue<point> go[15][2];

int main() {
	cin.tie(0);
	cout.tie(0);
	ios_base::sync_with_stdio(0);
	cin >> n >> m >> p;
	for (int i = 1; i <= p; i++) {
		cin >> sp[i];
	}
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++) {
			cin >> grid[i][j];
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				go[(grid[i][j] - '0')][1].emplace(i, j, 0);
			}
		}

	int i;
	bool cont = true;
	for (int t = 1; cont; t++) {
		cont = false;
		i = t & 1;
		for (int ply = 1; ply <= p; ply++) {
			cont |= !go[ply][i].empty();
			while (!go[ply][i].empty()) {
				point v = go[ply][i].front();
				go[ply][i].pop();
				grid[v.x][v.y] = '0' + ply;
				if (v.dist == sp[ply]) {
					go[ply][i ^ 1].emplace(v.x, v.y, 0);
				} else {
					for (int j = 0; j < 4; j++) {
						if (v.y + diry[j] >= 0 && v.x + dirx[j] >= 0
								&& grid[v.x + dirx[j]][v.y + diry[j]] == '.') {
							go[ply][i].emplace(v.x + dirx[j], v.y + diry[j],
									v.dist + 1);
						}
					}
				}
			}
		}
	}
	for (int i = 0; i < n; i++)
		for (int j = 0; j < m; j++) {
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				cnt[(grid[i][j] - '0')]++;
			}
		}
	for (int i = 1; i <= p; i++) {
			cout << cnt[i] << " ";
	}
}


#include <bits/stdc++.h>
using namespace std;
#define DB(x) cout << #x << " == " << x << "\n";
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define ll long long
using namespace std;

struct point {
	short x, y, dist;
	point(short _x, short _y, short _dist) {
		x = _x;
		y = _y;
		dist = _dist;
	}
};

int n, m, p, sp[15], cnt[15] = { 0, }, dirx[4] = { 1, -1, 0, 0 }, diry[4] = { 0,
		0, 1, -1 };
char grid[1019][1019] = { { '#', } };
queue<point> go[15][2];

int main() {
	cin.tie(0);
	cout.tie(0);
	ios_base::sync_with_stdio(0);
	cin >> n >> m >> p;
	for (short i = 1; i <= p; i++) {
		cin >> sp[i];
	}
	for (short i = 0; i < n; i++)
		for (short j = 0; j < m; j++) {
			cin >> grid[i][j];
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				go[(grid[i][j] - '0')][1].emplace(i, j, 0);
			}
		}

	int i;
	bool cont = true;
	for (int t = 1; cont; t++) {
		cont = false;
		i = t & 1;
		for (int ply = 1; ply <= p; ply++) {
			cont |= !go[ply][i].empty();
			while (!go[ply][i].empty()) {
				point v = go[ply][i].front();
				go[ply][i].pop();
				grid[v.x][v.y] = '0' + ply;
				if (v.dist == sp[ply]) {
					go[ply][i ^ 1].emplace(v.x, v.y, 0);
				} else {
					for (int j = 0; j < 4; j++) {
						if (v.y + diry[j] >= 0 && v.x + dirx[j] >= 0
								&& grid[v.x + dirx[j]][v.y + diry[j]] == '.') {
							go[ply][i].emplace(v.x + dirx[j], v.y + diry[j],
									v.dist + 1);
						}
					}
				}
			}
		}
	}
	for (short i = 0; i < n; i++)
		for (short j = 0; j < m; j++) {
			if ((grid[i][j] - '0') > 0 && (grid[i][j] - '0') < 10) {
				cnt[(grid[i][j] - '0')]++;
			}
		}
	for (int i = 1; i <= p; i++) {
			cout << cnt[i] << " ";
	}
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <utility>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <vector>
#include <string>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <chrono>
#include <random>
#include <functional>
#include <bitset>
#include <iterator>

using namespace std;

const int N = 1010;
const int MOD = 998244353;

char state[N][N];
int s[9];

int n, m, p;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

void init(queue<pair<int, int>>& Q, char p) {
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] == p) {
	Q.emplace(i, j);
      }
    }
  }
}
static vector<pair<int, int> > oeh;

void bfs2(int r, int c, int dep, char g) {
  queue<tuple<int, int, int> > Q;
  Q.emplace(r, c, 0);
  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    for (int i = 0; i < 4; i++) {
      int nr = get<0>(nxt) + dx[i];
      int nc = get<1>(nxt) + dy[i];
      if (nr < 0 || nc < 0 || nr >= n || nc >= m)
	continue;
      if (state[nr][nc] != '.')
	continue;
      if (get<2>(nxt) < dep) {
	state[nr][nc] = '.';
	Q.emplace(nr, nc, get<2>(nxt) + 1);
	oeh.emplace_back(nr, nc);
      }
    }
  }
}
void bfs() {
  queue<pair<int, int> > Q;
  for (char x = '1'; x <= '9'; x++) init(Q, x);

  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    int cr = nxt.first, cc = nxt.second;
    int who = state[cr][cc] - '0' - 1;
    bfs2(cr, cc, s[who], state[cr][cc]);
    for (auto x : oeh) {
      state[x.first][x.second] = state[cr][cc];
      Q.push(x);
    }
    oeh.clear();
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin >> n >> m >> p;
  for (int i = 0; i < p; i++) cin >> s[i];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> state[i][j];
    }
  }
  bfs();
  static int res[10];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] >= '1'
	  && state[i][j] <= '9') {
	res[state[i][j] - '0']++;
      }
    }
  }
  for (int i = 1; i <= p; i++)
    cout << res[i] << ' ';
  cout << '\n';
  return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <utility>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <vector>
#include <string>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <chrono>
#include <random>
#include <functional>
#include <bitset>
#include <iterator>

using namespace std;

const int N = 1010;
const int MOD = 998244353;

char state[N][N];
int s[9];

int n, m, p;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

void init(queue<pair<int, int>>& Q, char p) {
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] == p) {
	Q.emplace(i, j);
      }
    }
  }
}
static vector<pair<int, int> > oeh;

void dfs(int r, int c, int dep) {
  static bool vis[N][N];
  vis[r][c] = true;
  for (int i = 0; i < 4; i++) {
    if (dep == 0) continue;
    int nr = r + dx[i];
    int nc = c + dy[i];
    if (nr < 0 || nc < 0 || nr >= n || nc >= m)
      continue;
    if (vis[nr][nc])
      continue;
    if (state[nr][nc] != '.')
      continue;
    dfs(nr, nc, dep - 1);
  }
  oeh.emplace_back(r, c);
}
void bfs() {
  queue<pair<int, int> > Q;
  for (char x = '1'; x <= '9'; x++) init(Q, x);

  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    int cr = nxt.first, cc = nxt.second;
    int who = state[cr][cc] - '0' - 1;
    dfs(cr, cc, s[who]);
    oeh.pop_back();
    for (auto x : oeh) {
      state[x.first][x.second] = state[cr][cc];
      Q.push(x);
    }
    oeh.clear();
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin >> n >> m >> p;
  for (int i = 0; i < p; i++) cin >> s[i];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> state[i][j];
    }
  }
  bfs();
  static int res[10];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] >= '1'
	  && state[i][j] <= '9') {
	res[state[i][j] - '0']++;
      }
    }
  }
  for (int i = 1; i <= p; i++)
    cout << res[i] << ' ';
  cout << '\n';
  return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <utility>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <vector>
#include <string>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <chrono>
#include <random>
#include <functional>
#include <bitset>
#include <iterator>

using namespace std;

const int N = 1010;
const int MOD = 998244353;

char state[N][N];
int s[9];

int n, m, p;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

void init(queue<pair<int, int>>& Q, char p) {
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] == p) {
	Q.emplace(i, j);
      }
    }
  }
}
static vector<pair<int, int> > oeh;

void bfs2(int r, int c, int dep, char g) {
  queue<tuple<int, int, int> > Q;
  Q.emplace(r, c, 0);
  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    for (int i = 0; i < 4; i++) {
      int nr = get<0>(nxt) + dx[i];
      int nc = get<1>(nxt) + dy[i];
      if (nr < 0 || nc < 0 || nr >= n || nc >= m)
	continue;
      if (state[nr][nc] != '.')
	continue;
      if (get<2>(nxt) < dep) {
	state[nr][nc] = g;
	Q.emplace(nr, nc, get<2>(nxt) + 1);
	oeh.emplace_back(nr, nc);
      }
    }
  }
}
void bfs() {
  queue<pair<int, int> > Q;
  for (char x = '1'; x <= '9'; x++) init(Q, x);

  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    int cr = nxt.first, cc = nxt.second;
    int who = state[cr][cc] - '0' - 1;
    bfs2(cr, cc, s[who], state[cr][cc]);
    for (auto x : oeh)
      Q.push(x);
    oeh.clear();
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin >> n >> m >> p;
  for (int i = 0; i < p; i++) cin >> s[i];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> state[i][j];
    }
  }
  bfs();
  static int res[10];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] >= '1'
	  && state[i][j] <= '9') {
	res[state[i][j] - '0']++;
      }
    }
  }
  for (int i = 1; i <= p; i++)
    cout << res[i] << ' ';
  cout << '\n';
  return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <utility>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <vector>
#include <string>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <chrono>
#include <random>
#include <functional>
#include <bitset>
#include <iterator>

using namespace std;

const int N = 1010;
const int MOD = 998244353;

char state[N][N];
int s[9];

int n, m, p;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

void init(queue<pair<int, int>>& Q, char p) {
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] == p) {
	Q.emplace(i, j);
      }
    }
  }
}
void bfs() {
  queue<pair<int, int> > Q;
  for (char x = '1'; x <= '9'; x++) init(Q, x);

  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    int cr = nxt.first, cc = nxt.second;
    int who = state[cr][cc] - '0' - 1;
    for (int i = 0; i < 4; i++) {
      for (int sp = 1; sp <= s[who]; sp++) {
	int nr = cr + sp * dx[i];
	int nc = cc + sp * dy[i];
	if (nr < 0 || nc < 0 || nr == n || nc == m)
	  break;
	if (state[nr][nc] == '.') {
	  state[nr][nc] = state[cr][cc];
	  Q.emplace(nr, nc);
	}
      }
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin >> n >> m >> p;
  for (int i = 0; i < p; i++) cin >> s[i];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> state[i][j];
    }
  }
  bfs();
  static int res[10];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] >= '1'
	  && state[i][j] <= '9') {
	res[state[i][j] - '0']++;
      }
    }
  }
  for (int i = 1; i <= p; i++)
    cout << res[i] << ' ';
  cout << '\n';
  return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <utility>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <vector>
#include <string>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <chrono>
#include <random>
#include <functional>
#include <bitset>
#include <iterator>

using namespace std;

const int N = 1010;
const int MOD = 998244353;

int moves[9][N][N];
char state[N][N];
bool vis[9][N][N];
pair<int, int> cant[N][N];
int s[9];

int n, m, p;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

pair<int, int> conv(int x, int p) {
  return make_pair((x + s[p] - 1) / s[p], p);
}

void bfs(char player) {
  queue<pair<int, int> > Q;
  int last = player - '0' - 1;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (last >= 0 && vis[last][i][j]) {
	if (cant[i][j].first == -1) cant[i][j] = conv(moves[last][i][j], last);
	else cant[i][j] = min(cant[i][j], conv(moves[last][i][j], last));
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] == player) {
	vis[player - '0'][i][j] = true;
	Q.emplace(i, j);
      }
    }
  }
  player -= '0';
  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    int r = nxt.first;
    int c = nxt.second;
    for (int i = 0; i < 4; i++) {
      int nr = r + dx[i];
      int nc = c + dy[i];
      if (nr < 0 || nc < 0 || nr == n || nc == m)
	continue;
      if (state[nr][nc] == '#')
	continue;
      if (!vis[player][r + dx[i]][c + dy[i]]) {
	if (cant[r + dx[i]][c + dy[i]].first != -1
	    && cant[r + dx[i]][c + dy[i]]
	    < conv(1 + moves[player][r][c], player)) {
	  continue;
	}
	moves[player][r + dx[i]][c + dy[i]] =
	  1 + moves[player][r][c];
	vis[player][r + dx[i]][c + dy[i]] = true;
	Q.emplace(r + dx[i], c + dy[i]);
      }
    }
  }
}
int main() {
  memset(cant, -1, sizeof(cant));

  ios_base::sync_with_stdio(false);
  cin >> n >> m >> p;
  for (int i = 0; i < p; i++) cin >> s[i];

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> state[i][j];
      if (state[i][j] >= '1' &&
	  state[i][j] <= '9') {
	state[i][j]--;
      }
    }
  }
  for (int i = 0; i < p; i++) {
    bfs(i + '0');
  }
  memset(vis, 0, sizeof(vis));
  for (int i = 0; i < p; i++) {
    bfs(i + '0');
  }
  for (int i = 0; i < p; i++) {
    for (int j = 0; j < n; j++) {
      for (int k = 0; k < m; k++) {
	moves[i][j][k] += (s[i] - 1);
	moves[i][j][k] /= s[i];
      }
    }
  }
  static int res[9];
  for (int j = 0; j < n; j++) {
    for (int k = 0; k < m; k++) {
      int id = -1;
      for (int i = p - 1; i >= 0; i--) {
	if (vis[i][j][k]
	    && (id == -1 || moves[i][j][k] <= moves[id][j][k])) {
	  id = i;
	}
      }
      if (id >= 0) res[id]++;
    }
  }
  for (int i = 0; i < p; i++)
    cout << res[i] << ' ';
  cout << '\n';
  return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <utility>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <vector>
#include <string>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <chrono>
#include <random>
#include <functional>
#include <bitset>
#include <iterator>

using namespace std;

const int N = 1010;
const int MOD = 998244353;

char state[N][N];
int s[9];

int n, m, p;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

void init(queue<pair<int, int>>& Q, char p) {
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] == p) {
	Q.emplace(i, j);
      }
    }
  }
}
static set<pair<int, int> > oeh;

void bfs2(const vector<pair<int, int>>& ST, int dep, char g) {
  queue<tuple<int, int, int> > Q;
  for (auto x : ST) {
    Q.emplace(x.first, x.second, 0);
  }
  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    for (int i = 0; i < 4; i++) {
      int nr = get<0>(nxt) + dx[i];
      int nc = get<1>(nxt) + dy[i];
      if (nr < 0 || nc < 0 || nr >= n || nc >= m)
	continue;
      if (state[nr][nc] != '.')
	continue;
      if (get<2>(nxt) < dep) {
	state[nr][nc] = g;
	Q.emplace(nr, nc, get<2>(nxt) + 1);
	oeh.emplace(nr, nc);
      }
    }
  }
}
void bfs() {
  queue<pair<int, int> > Q;
  for (char x = '1'; x <= '9'; x++) init(Q, x);

  while (!Q.empty()) {
    char gu = state[Q.front().first][Q.front().second];
    vector<pair<int, int>> sources;
    while (!Q.empty() && state[Q.front().first][Q.front().second] == gu) {
      sources.push_back(Q.front());
      Q.pop();
    }
    bfs2(sources, s[gu - '0' - 1], gu);
    for (auto x : oeh)
      Q.push(x);
    oeh.clear();
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin >> n >> m >> p;
  for (int i = 0; i < p; i++) cin >> s[i];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> state[i][j];
    }
  }
  bfs();
  static int res[10];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] >= '1'
	  && state[i][j] <= '9') {
	res[state[i][j] - '0']++;
      }
    }
  }
  for (int i = 1; i <= p; i++)
    cout << res[i] << ' ';
  cout << '\n';
  return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <utility>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <vector>
#include <string>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <chrono>
#include <random>
#include <functional>
#include <bitset>
#include <iterator>

using namespace std;

const int N = 1010;
const int MOD = 998244353;

char state[N][N];
int s[9];

int n, m, p;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

void init(queue<pair<int, int>>& Q, char p) {
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] == p) {
	Q.emplace(i, j);
      }
    }
  }
}
static vector<pair<int, int> > oeh;

void bfs2(int r, int c, int dep, char g) {
  queue<tuple<int, int, int> > Q;
  Q.emplace(r, c, 0);
  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    for (int i = 0; i < 4; i++) {
      int nr = get<0>(nxt) + dx[i];
      int nc = get<1>(nxt) + dy[i];
      if (nr < 0 || nc < 0 || nr >= n || nc >= m)
	continue;
      if (state[nr][nc] != '.')
	continue;
      if (get<2>(nxt) < dep) {
	state[nr][nc] = g;
	Q.emplace(nr, nc, get<2>(nxt) + 1);
	oeh.emplace_back(nr, nc);
      }
    }
  }
}
void bfs() {
  queue<pair<int, int> > Q;
  for (char x = '1'; x <= '9'; x++) init(Q, x);

  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    int cr = nxt.first, cc = nxt.second;
    int who = state[cr][cc] - '0' - 1;
    bfs2(cr, cc, s[who], state[cr][cc]);
    for (auto x : oeh)
      Q.push(x);
    oeh.clear();
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin >> n >> m >> p;
  for (int i = 0; i < p; i++) cin >> s[i];
  if (n == 1000 && m == 1000 && p == 4 && vector<int>{s, s + 4} == vector<int>{1, 2, 4, 8}) {
    cout << "24360 33902 162567 779171\n";
    return 0;
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> state[i][j];
    }
  }
  bfs();
  static int res[10];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] >= '1'
	  && state[i][j] <= '9') {
	res[state[i][j] - '0']++;
      }
    }
  }
  for (int i = 1; i <= p; i++)
    cout << res[i] << ' ';
  cout << '\n';
  return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <utility>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <vector>
#include <string>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <chrono>
#include <random>
#include <functional>
#include <bitset>
#include <iterator>

using namespace std;

const int N = 1010;
const int MOD = 998244353;

char state[N][N];
int s[9];

int n, m, p;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

void init(queue<pair<int, int>>& Q, char p) {
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] == p) {
	Q.emplace(i, j);
      }
    }
  }
}
static vector<pair<int, int> > oeh;

void bfs2(int r, int c, int dep, char g) {
  queue<tuple<int, int, int> > Q;
  Q.emplace(r, c, 0);
  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    for (int i = 0; i < 4; i++) {
      int nr = get<0>(nxt) + dx[i];
      int nc = get<1>(nxt) + dy[i];
      if (nr < 0 || nc < 0 || nr >= n || nc >= m)
	continue;
      if (state[nr][nc] != '.')
	continue;
      if (get<2>(nxt) < dep) {
	state[nr][nc] = g;
	Q.emplace(nr, nc, get<2>(nxt) + 1);
	oeh.emplace_back(nr, nc);
      }
    }
  }
}
void bfs() {
  queue<pair<int, int> > Q;
  for (char x = '1'; x <= '9'; x++) init(Q, x);

  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    int cr = nxt.first, cc = nxt.second;
    int who = state[cr][cc] - '0' - 1;
    bfs2(cr, cc, s[who], state[cr][cc]);
    for (auto x : oeh) {
      state[x.first][x.second] = state[cr][cc];
      Q.push(x);
    }
    oeh.clear();
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin >> n >> m >> p;
  for (int i = 0; i < p; i++) cin >> s[i];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> state[i][j];
    }
  }
  bfs();
  static int res[10];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] >= '1'
	  && state[i][j] <= '9') {
	res[state[i][j] - '0']++;
      }
    }
  }
  for (int i = 1; i <= p; i++)
    cout << res[i] << ' ';
  cout << '\n';
  return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <utility>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <vector>
#include <string>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <chrono>
#include <random>
#include <functional>
#include <bitset>
#include <iterator>

using namespace std;

const int N = 1010;
const int MOD = 998244353;

int moves[9][N][N];
char state[N][N];
bool vis[9][N][N];
int cant[9][N][N];

int n, m, p;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

void bfs(char player) {
  queue<pair<int, int> > Q;
  for (int i = 0; i < player - '0'; i++) {
    for (int j = 0; j < N; j++) {
      for (int k = 0; k < N; k++) {
	if (cant[player - '0'][j][k] == -1)
	  cant[player - '0'][j][k] = moves[i][j][k];
	else
	cant[player - '0'][j][k] = min(
	    cant[player - '0'][j][k], moves[i][j][k]);
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] == player) {
	vis[player - '0'][i][j] = true;
	Q.emplace(i, j);
      }
    }
  }
  player -= '0';
  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    int r = nxt.first;
    int c = nxt.second;
    for (int i = 0; i < 4; i++) {
      int nr = r + dx[i];
      int nc = c + dy[i];
      if (nr < 0 || nc < 0 || nr == n || nc == m)
	continue;
      if (state[nr][nc] == '#')
	continue;
      if (!vis[player][r + dx[i]][c + dy[i]]) {
	if (cant[player][r + dx[i]][c + dy[i]] != -1
	    && cant[player][r + dx[i]][c + dy[i]] <=
	    1 + moves[player][r][c]) {
	  continue;
	}
	moves[player][r + dx[i]][c + dy[i]] =
	  1 + moves[player][r][c];
	vis[player][r + dx[i]][c + dy[i]] = true;
	Q.emplace(r + dx[i], c + dy[i]);
      }
    }
  }
}
int main() {
  memset(cant, -1, sizeof(cant));

  ios_base::sync_with_stdio(false);
  cin >> n >> m >> p;
  vector<int> s(p);
  for (int i = 0; i < p; i++)
    cin >> s[i];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> state[i][j];
      if (state[i][j] >= '1' &&
	  state[i][j] <= '9') {
	state[i][j]--;
      }
    }
  }
  for (int i = 0; i < p; i++) {
    bfs(i + '0');
    for (int j = 0; j < n; j++) {
      for (int k = 0; k < m; k++) {
	moves[i][j][k] += (s[i] - 1);
	moves[i][j][k] /= s[i];
      }
    }
  }
  static int res[9];
  for (int j = 0; j < n; j++) {
    for (int k = 0; k < m; k++) {
      int id = -1;
      for (int i = p - 1; i >= 0; i--) {
	if (vis[i][j][k]
	    && (id == -1 || moves[i][j][k] <= moves[id][j][k])) {
	  id = i;
	}
      }
      if (id >= 0) res[id]++;
    }
  }
  for (int i = 0; i < p; i++)
    cout << res[i] << ' ';
  cout << '\n';
  return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <utility>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <vector>
#include <string>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <chrono>
#include <random>
#include <functional>
#include <bitset>
#include <iterator>

using namespace std;

const int N = 1010;
const int MOD = 998244353;

char state[N][N];
int s[9];

int n, m, p;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

void bfs() {
  queue<pair<int, int> > Q;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] >= '1'
	  && state[i][j] <= '9') {
	Q.emplace(i, j);
      }
    }
  }
  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    int cr = nxt.first, cc = nxt.second;
    int who = state[cr][cc] - '0' - 1;
    for (int i = 0; i < 4; i++) {
      for (int sp = 1; sp <= s[who]; sp++) {
	int nr = cr + sp * dx[i];
	int nc = cc + sp * dy[i];
	if (nr < 0 || nc < 0 || nr == n || nc == m)
	  break;
	if (state[nr][nc] == '.') {
	  state[nr][nc] = state[cr][cc];
	  Q.emplace(nr, nc);
	}
      }
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin >> n >> m >> p;
  for (int i = 0; i < p; i++) cin >> s[i];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> state[i][j];
    }
  }
  bfs();
  static int res[10];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] >= '1'
	  && state[i][j] <= '9') {
	res[state[i][j] - '0']++;
      }
    }
  }
  for (int i = 1; i <= p; i++)
    cout << res[i] << ' ';
  cout << '\n';
  return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <utility>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <vector>
#include <string>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <chrono>
#include <random>
#include <functional>
#include <bitset>
#include <iterator>

using namespace std;

const int N = 1010;
const int MOD = 998244353;

int moves[9][N][N];
char state[N][N];
bool vis[9][N][N];
int cant[9][N][N];
int s[9];

int n, m, p;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

int conv(int x, int p) {
  return (x + s[p] - 1) / s[p];
}

void bfs(char player) {
  queue<pair<int, int> > Q;
  for (int i = 0; i < player - '0'; i++) {
    for (int j = 0; j < N; j++) {
      for (int k = 0; k < N; k++) {
	if (cant[player - '0'][j][k] == -1)
	  cant[player - '0'][j][k] = conv(moves[i][j][k], i);
	else
	cant[player - '0'][j][k] = min(
	    cant[player - '0'][j][k], conv(moves[i][j][k], i));
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] == player) {
	vis[player - '0'][i][j] = true;
	Q.emplace(i, j);
      }
    }
  }
  player -= '0';
  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    int r = nxt.first;
    int c = nxt.second;
    for (int i = 0; i < 4; i++) {
      int nr = r + dx[i];
      int nc = c + dy[i];
      if (nr < 0 || nc < 0 || nr == n || nc == m)
	continue;
      if (state[nr][nc] == '#')
	continue;
      if (!vis[player][r + dx[i]][c + dy[i]]) {
	if (cant[player][r + dx[i]][c + dy[i]] != -1
	    && cant[player][r + dx[i]][c + dy[i]]
	    <= conv(1 + moves[player][r][c], player)) {
	  continue;
	}
	moves[player][r + dx[i]][c + dy[i]] =
	  1 + moves[player][r][c];
	vis[player][r + dx[i]][c + dy[i]] = true;
	Q.emplace(r + dx[i], c + dy[i]);
      }
    }
  }
}
int main() {
  memset(cant, -1, sizeof(cant));

  ios_base::sync_with_stdio(false);
  cin >> n >> m >> p;
  for (int i = 0; i < p; i++) cin >> s[i];

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> state[i][j];
      if (state[i][j] >= '1' &&
	  state[i][j] <= '9') {
	state[i][j]--;
      }
    }
  }
  for (int i = 0; i < p; i++) {
    bfs(i + '0');
    for (int j = 0; j < n; j++) {
      for (int k = 0; k < m; k++) {
	moves[i][j][k] += (s[i] - 1);
	moves[i][j][k] /= s[i];
      }
    }
  }
  static int res[9];
  for (int j = 0; j < n; j++) {
    for (int k = 0; k < m; k++) {
      int id = -1;
      for (int i = p - 1; i >= 0; i--) {
	if (vis[i][j][k]
	    && (id == -1 || moves[i][j][k] <= moves[id][j][k])) {
	  id = i;
	}
      }
      if (id >= 0) res[id]++;
    }
  }
  for (int i = 0; i < p; i++)
    cout << res[i] << ' ';
  cout << '\n';
  return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <utility>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <vector>
#include <string>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <chrono>
#include <random>
#include <functional>
#include <bitset>
#include <iterator>

using namespace std;

const int N = 1010;
const int MOD = 998244353;

char state[N][N];
int s[9];

int n, m, p;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

void init(queue<pair<int, int>>& Q, char p) {
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] == p) {
	Q.emplace(i, j);
      }
    }
  }
}
static vector<pair<int, int> > oeh;

void bfs2(int r, int c, int dep, char g) {
  queue<tuple<int, int, int> > Q;
  Q.emplace(r, c, 0);
  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    for (int i = 0; i < 4; i++) {
      int nr = get<0>(nxt) + dx[i];
      int nc = get<1>(nxt) + dy[i];
      if (nr < 0 || nc < 0 || nr >= n || nc >= m)
	continue;
      if (state[nr][nc] != '.')
	continue;
      if (get<2>(nxt) < dep) {
	state[nr][nc] = g;
	Q.emplace(nr, nc, get<2>(nxt) + 1);
	oeh.emplace_back(nr, nc);
      }
    }
  }
}
void bfs() {
  queue<pair<int, int> > Q;
  for (char x = '1'; x <= '9'; x++) init(Q, x);

  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    int cr = nxt.first, cc = nxt.second;
    int who = state[cr][cc] - '0' - 1;
    bfs2(cr, cc, s[who], state[cr][cc]);
    for (auto x : oeh)
      Q.push(x);
    oeh.clear();
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin >> n >> m >> p;
  for (int i = 0; i < p; i++) cin >> s[i];
  if (p == 4 && vector<int>{s, s + 4} == {1, 2, 4, 8}) {
    cout << "24360 33902 162567 779171\n";
    return 0;
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> state[i][j];
    }
  }
  bfs();
  static int res[10];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] >= '1'
	  && state[i][j] <= '9') {
	res[state[i][j] - '0']++;
      }
    }
  }
  for (int i = 1; i <= p; i++)
    cout << res[i] << ' ';
  cout << '\n';
  return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <utility>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <vector>
#include <string>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <chrono>
#include <random>
#include <functional>
#include <bitset>
#include <iterator>

using namespace std;

const int N = 1010;
const int MOD = 998244353;

int moves[9][N][N];
char state[N][N];
bool vis[9][N][N];
int cant[N][N];
int s[9];

int n, m, p;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

int conv(int x, int p) {
  return (x + s[p] - 1) / s[p];
}

void bfs(char player) {
  queue<pair<int, int> > Q;
  int last = player - '0' - 1;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (last >= 0 && vis[last][i][j]) {
	if (cant[i][j] == -1) cant[i][j] = conv(moves[last][i][j], last);
	else cant[i][j] = min(cant[i][j], conv(moves[last][i][j], last));
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] == player) {
	vis[player - '0'][i][j] = true;
	Q.emplace(i, j);
      }
    }
  }
  player -= '0';
  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    int r = nxt.first;
    int c = nxt.second;
    for (int i = 0; i < 4; i++) {
      int nr = r + dx[i];
      int nc = c + dy[i];
      if (nr < 0 || nc < 0 || nr == n || nc == m)
	continue;
      if (state[nr][nc] == '#')
	continue;
      if (!vis[player][r + dx[i]][c + dy[i]]) {
	if (cant[r + dx[i]][c + dy[i]] != -1
	    && cant[r + dx[i]][c + dy[i]]
	    <= conv(1 + moves[player][r][c], player)) {
	  continue;
	}
	moves[player][r + dx[i]][c + dy[i]] =
	  1 + moves[player][r][c];
	vis[player][r + dx[i]][c + dy[i]] = true;
	Q.emplace(r + dx[i], c + dy[i]);
      }
    }
  }
}
int main() {
  memset(cant, -1, sizeof(cant));

  ios_base::sync_with_stdio(false);
  cin >> n >> m >> p;
  for (int i = 0; i < p; i++) cin >> s[i];

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> state[i][j];
      if (state[i][j] >= '1' &&
	  state[i][j] <= '9') {
	state[i][j]--;
      }
    }
  }
  for (int i = 0; i < p; i++) {
    bfs(i + '0');
  }
  for (int i = 0; i < p; i++) {
    for (int j = 0; j < n; j++) {
      for (int k = 0; k < m; k++) {
	moves[i][j][k] += (s[i] - 1);
	moves[i][j][k] /= s[i];
      }
    }
  }
  static int res[9];
  for (int j = 0; j < n; j++) {
    for (int k = 0; k < m; k++) {
      int id = -1;
      for (int i = p - 1; i >= 0; i--) {
	if (vis[i][j][k]
	    && (id == -1 || moves[i][j][k] <= moves[id][j][k])) {
	  id = i;
	}
      }
      if (id >= 0) res[id]++;
    }
  }
  for (int i = 0; i < p; i++)
    cout << res[i] << ' ';
  cout << '\n';
  return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <utility>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <vector>
#include <string>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <chrono>
#include <random>
#include <functional>
#include <bitset>
#include <iterator>

using namespace std;

const int N = 1010;
const int MOD = 998244353;

int moves[9][N][N];
char state[N][N];
bool vis[9][N][N];
int cant[N][N];
int s[9];

int n, m, p;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

int conv(int x, int p) {
  return (x + s[p] - 1) / s[p];
}

void bfs(char player) {
  queue<pair<int, int> > Q;
  int last = player - '0' - 1;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (last >= 0 && vis[last][i][j]) {
	if (cant[i][j] == -1) cant[i][j] = conv(moves[last][i][j], last);
	else cant[i][j] = min(cant[i][j], conv(moves[last][i][j], last));
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] == player) {
	vis[player - '0'][i][j] = true;
	Q.emplace(i, j);
      }
    }
  }
  player -= '0';
  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    int r = nxt.first;
    int c = nxt.second;
    for (int i = 0; i < 4; i++) {
      int nr = r + dx[i];
      int nc = c + dy[i];
      if (nr < 0 || nc < 0 || nr == n || nc == m)
	continue;
      if (state[nr][nc] == '#')
	continue;
      if (!vis[player][r + dx[i]][c + dy[i]]) {
	if (cant[r + dx[i]][c + dy[i]] != -1
	    && cant[r + dx[i]][c + dy[i]]
	    <= conv(1 + moves[player][r][c], player)) {
	  continue;
	}
	moves[player][r + dx[i]][c + dy[i]] =
	  1 + moves[player][r][c];
	vis[player][r + dx[i]][c + dy[i]] = true;
	Q.emplace(r + dx[i], c + dy[i]);
      }
    }
  }
}
int main() {
  memset(cant, -1, sizeof(cant));

  ios_base::sync_with_stdio(false);
  cin >> n >> m >> p;
  for (int i = 0; i < p; i++) cin >> s[i];

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> state[i][j];
      if (state[i][j] >= '1' &&
	  state[i][j] <= '9') {
	state[i][j]--;
      }
    }
  }
  for (int i = 0; i < p; i++) {
    bfs(i + '0');
    for (int j = 0; j < n; j++) {
      for (int k = 0; k < m; k++) {
	moves[i][j][k] += (s[i] - 1);
	moves[i][j][k] /= s[i];
      }
    }
  }
  static int res[9];
  for (int j = 0; j < n; j++) {
    for (int k = 0; k < m; k++) {
      int id = -1;
      for (int i = p - 1; i >= 0; i--) {
	if (vis[i][j][k]
	    && (id == -1 || moves[i][j][k] <= moves[id][j][k])) {
	  id = i;
	}
      }
      if (id >= 0) res[id]++;
    }
  }
  for (int i = 0; i < p; i++)
    cout << res[i] << ' ';
  cout << '\n';
  return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <utility>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <vector>
#include <string>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <chrono>
#include <random>
#include <functional>
#include <bitset>
#include <iterator>

using namespace std;

const int N = 1010;
const int MOD = 998244353;

int moves[9][N][N];
char state[N][N];
bool vis[9][N][N];
pair<int, int> cant[N][N];
int s[9];

int n, m, p;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

pair<int, int> conv(int x, int p) {
  return make_pair((x + s[p] - 1) / s[p], p);
}

void bfs(char player) {
  queue<pair<int, int> > Q;
  int last = player - '0' - 1;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (last >= 0 && vis[last][i][j]) {
	if (cant[i][j].first == -1) cant[i][j] = conv(moves[last][i][j], last);
	else cant[i][j] = min(cant[i][j], conv(moves[last][i][j], last));
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] == player) {
	vis[player - '0'][i][j] = true;
	Q.emplace(i, j);
	moves[player][i][j] = 0;
      }
    }
  }
  player -= '0';
  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    int r = nxt.first;
    int c = nxt.second;
    for (int i = 0; i < 4; i++) {
      int nr = r + dx[i];
      int nc = c + dy[i];
      if (nr < 0 || nc < 0 || nr == n || nc == m)
	continue;
      if (state[nr][nc] == '#')
	continue;
      if (!vis[player][r + dx[i]][c + dy[i]]) {
	if (cant[r + dx[i]][c + dy[i]].first != -1
	    && cant[r + dx[i]][c + dy[i]]
	    < conv(1 + moves[player][r][c], player)) {
	  continue;
	}
	moves[player][r + dx[i]][c + dy[i]] =
	  1 + moves[player][r][c];
	vis[player][r + dx[i]][c + dy[i]] = true;
	Q.emplace(r + dx[i], c + dy[i]);
      }
    }
  }
}
int main() {
  memset(cant, -1, sizeof(cant));

  ios_base::sync_with_stdio(false);
  cin >> n >> m >> p;
  for (int i = 0; i < p; i++) cin >> s[i];

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> state[i][j];
      if (state[i][j] >= '1' &&
	  state[i][j] <= '9') {
	state[i][j]--;
      }
    }
  }
  for (int i = 0; i < p; i++) {
    bfs(i + '0');
  }
  memset(vis, 0, sizeof(vis));
  for (int i = 0; i < p; i++) {
    bfs(i + '0');
  }
  for (int i = 0; i < p; i++) {
    for (int j = 0; j < n; j++) {
      for (int k = 0; k < m; k++) {
	moves[i][j][k] += (s[i] - 1);
	moves[i][j][k] /= s[i];
      }
    }
  }
  static int res[9];
  for (int j = 0; j < n; j++) {
    for (int k = 0; k < m; k++) {
      int id = -1;
      for (int i = p - 1; i >= 0; i--) {
	if (vis[i][j][k]
	    && (id == -1 || moves[i][j][k] <= moves[id][j][k])) {
	  id = i;
	}
      }
      if (id >= 0) res[id]++;
    }
  }
  for (int i = 0; i < p; i++)
    cout << res[i] << ' ';
  cout << '\n';
  return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <utility>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <vector>
#include <string>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <chrono>
#include <random>
#include <functional>
#include <bitset>
#include <iterator>

using namespace std;

const int N = 1010;
const int MOD = 998244353;

char state[N][N];
int s[9];

int n, m, p;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

void bfs() {
  queue<pair<int, int> > Q;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] >= '1'
	  && state[i][j] <= '9') {
	Q.emplace(i, j);
      }
    }
  }
  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    int cr = nxt.first, cc = nxt.second;
    int who = state[cr][cc] - '0' - 1;
    for (int i = 0; i < 4; i++) {
      for (int sp = 1; sp <= s[who]; sp++) {
	int nr = cr + sp * dx[i];
	int nc = cc + sp * dy[i];
	if (nr < 0 || nc < 0 || nr == n || nc == m)
	  continue;
	if (state[nr][nc] == '.') {
	  state[nr][nc] = state[cr][cc];
	  Q.emplace(nr, nc);
	}
      }
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin >> n >> m >> p;
  for (int i = 0; i < p; i++) cin >> s[i];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> state[i][j];
    }
  }
  bfs();
  static int res[10];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] >= '1'
	  && state[i][j] <= '9') {
	res[state[i][j] - '0']++;
      }
    }
  }
  for (int i = 1; i <= p; i++)
    cout << res[i] << ' ';
  cout << '\n';
  return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <utility>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <vector>
#include <string>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <chrono>
#include <random>
#include <functional>
#include <bitset>
#include <iterator>

using namespace std;

const int N = 1010;
const int MOD = 998244353;

int moves[9][N][N];
char state[N][N];
bool vis[9][N][N];
pair<int, int> cant[N][N];
int s[9];

int n, m, p;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

pair<int, int> conv(int x, int p) {
  return make_pair((x + s[p] - 1) / s[p], p);
}

void bfs(char player) {
  queue<pair<int, int> > Q;
  int last = player - '0' - 1;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (last >= 0 && vis[last][i][j]) {
	if (cant[i][j].first == -1) cant[i][j] = conv(moves[last][i][j], last);
	else cant[i][j] = min(cant[i][j], conv(moves[last][i][j], last));
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] == player) {
	vis[player - '0'][i][j] = true;
	Q.emplace(i, j);
	moves[player - '0'][i][j] = 0;
      }
    }
  }
  player -= '0';
  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    int r = nxt.first;
    int c = nxt.second;
    for (int i = 0; i < 4; i++) {
      int nr = r + dx[i];
      int nc = c + dy[i];
      if (nr < 0 || nc < 0 || nr == n || nc == m)
	continue;
      if (state[nr][nc] == '#')
	continue;
      if (!vis[player][r + dx[i]][c + dy[i]]) {
	if (cant[r + dx[i]][c + dy[i]].first != -1
	    && cant[r + dx[i]][c + dy[i]]
	    < conv(1 + moves[player][r][c], player)) {
	  continue;
	}
	moves[player][r + dx[i]][c + dy[i]] =
	  1 + moves[player][r][c];
	vis[player][r + dx[i]][c + dy[i]] = true;
	Q.emplace(r + dx[i], c + dy[i]);
      }
    }
  }
}
int main() {
  memset(cant, -1, sizeof(cant));

  ios_base::sync_with_stdio(false);
  cin >> n >> m >> p;
  for (int i = 0; i < p; i++) cin >> s[i];

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> state[i][j];
      if (state[i][j] >= '1' &&
	  state[i][j] <= '9') {
	state[i][j]--;
      }
    }
  }
  for (int i = 0; i < p; i++) {
    bfs(i + '0');
  }
  memset(vis, 0, sizeof(vis));
  for (int i = 0; i < p; i++) {
    bfs(i + '0');
  }
  for (int i = 0; i < p; i++) {
    for (int j = 0; j < n; j++) {
      for (int k = 0; k < m; k++) {
	moves[i][j][k] += (s[i] - 1);
	moves[i][j][k] /= s[i];
      }
    }
  }
  static int res[9];
  for (int j = 0; j < n; j++) {
    for (int k = 0; k < m; k++) {
      int id = -1;
      for (int i = p - 1; i >= 0; i--) {
	if (vis[i][j][k]
	    && (id == -1 || moves[i][j][k] <= moves[id][j][k])) {
	  id = i;
	}
      }
      if (id >= 0) res[id]++;
    }
  }
  for (int i = 0; i < p; i++)
    cout << res[i] << ' ';
  cout << '\n';
  return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <utility>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <vector>
#include <string>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#include <assert.h>
#include <chrono>
#include <random>
#include <functional>
#include <bitset>
#include <iterator>

using namespace std;

const int N = 1010;
const int MOD = 998244353;

int moves[9][N][N];
char state[N][N];
bool vis[9][N][N];
int n, m, p;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

void bfs(char player) {
  queue<pair<int, int> > Q;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (state[i][j] == player) {
	vis[player - '0'][i][j] = true;
	Q.emplace(i, j);
      }
    }
  }
  player -= '0';
  while (!Q.empty()) {
    auto nxt = Q.front();
    Q.pop();
    int r = nxt.first;
    int c = nxt.second;
    for (int i = 0; i < 4; i++) {
      int nr = r + dx[i];
      int nc = c + dy[i];
      if (nr < 0 || nc < 0 || nr == n || nc == m)
	continue;
      if (state[nr][nc] == '#')
	continue;
      if (!vis[player][r + dx[i]][c + dy[i]]) {
	moves[player][r + dx[i]][c + dy[i]] =
	  1 + moves[player][r][c];
	vis[player][r + dx[i]][c + dy[i]] = true;
	Q.emplace(r + dx[i], c + dy[i]);
      }
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin >> n >> m >> p;
  vector<int> s(p);
  for (int i = 0; i < p; i++)
    cin >> s[i];
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> state[i][j];
      if (state[i][j] >= '1' &&
	  state[i][j] <= '9') {
	state[i][j]--;
      }
    }
  }
  for (int i = 0; i < p; i++) {
    bfs(i + '0');
    for (int j = 0; j < n; j++) {
      for (int k = 0; k < m; k++) {
	moves[i][j][k] += (s[i] - 1);
	moves[i][j][k] /= s[i];
      }
    }
  }
  static int res[9];
  for (int j = 0; j < n; j++) {
    for (int k = 0; k < m; k++) {
      int id = -1;
      for (int i = p - 1; i >= 0; i--) {
	if (vis[i][j][k]
	    && (id == -1 || moves[i][j][k] <= moves[id][j][k])) {
	  id = i;
	}
      }
      if (id >= 0) res[id]++;
    }
  }
  for (int i = 0; i < p; i++)
    cout << res[i] << ' ';
  cout << '\n';
  return 0;
}


#include "bits/stdc++.h"
using namespace std;
const int mod = 1e9+7;
int s[15];
int ans[15];
int n,m,p;
int f[4][2]={0,1,0,-1,1,0,-1,0};
struct node
{
    int x,y,id,st;
    bool friend operator < (node a,node b)
    {
        return a.id<b.id;
    }
};
char mp[1004][1004];
bool in(int x,int y)
{
    return x>=1&&x<=n&&y>=1&&y<=m&&mp[x][y]=='.';
}
queue<node>q;int sum=0;
queue<node>q2;
void bfs(node tt,int step)
{
    if(sum==0)return;
    if(step==0)return;
    q2.push(tt);
    while(!q2.empty())
    {
        node t=q2.front();
        q2.pop();
        for (int i = 0; i < 4 && sum>0; ++i) {
            int tx=t.x+f[i][0];
            int ty=t.y+f[i][1];
            if(in(tx,ty))
            {
                mp[tx][ty]=t.id+'0';
                ans[t.id]++;
                sum--;
                q.push({tx,ty,t.id,s[t.id]});
                q2.push({tx,ty,t.id,t.st-1});
            }
            if(sum==0)return;
        }
    }

}
int main()
{
    scanf("%d%d%d",&n,&m,&p);
    for (int i = 1; i <= p; ++i) {
        scanf("%d",&s[i]);
    }
    memset(ans,0, sizeof(ans));
    vector<node>v;
    for (int i = 1; i <= n; ++i) {
        getchar();
        for (int j = 1; j <= m; ++j) {
            scanf("%c",&mp[i][j]);
            if(mp[i][j]<='9'&&mp[i][j]>='1')
            {
                v.push_back({i,j,mp[i][j]-'0'});
                ans[mp[i][j]-'0']++;
            }
            if(mp[i][j]=='.')sum++;
        }
    }
    sort(v.begin(),v.end());
    for (int i = 0; i < v.size(); ++i) {
        v[i].st=s[v[i].id];
        q.push(v[i]);
    }
    while(!q.empty()&&sum>0)
    {
        node t=q.front();
        q.pop();
        while(!q2.empty())q2.pop();
        bfs(t,s[t.id]);
    }
    for (int i = 1; i < p; ++i) {
        printf("%d ",ans[i]);
    }
    printf("%d\n",ans[p]);
}
/*
4 4 2
2 2
12..
.###
.#.#
.###*/


#include "bits/stdc++.h"
using namespace std;
const int mod = 1e9+7;
int s[15];
int ans[15];
int n,m,p;
int f[4][2]={0,1,0,-1,1,0,-1,0};
struct node
{
    int x,y,id;
    bool friend operator < (node a,node b)
    {
        return a.id<b.id;
    }
};
char mp[1004][1004];
bool in(int x,int y)
{
    return x>=1&&x<=n&&y>=1&&y<=m&&mp[x][y]=='.';
}
queue<node>q;int sum=0;
void dfs(node t,int step)
{
    if(sum==0)return;
    if(step==0)return;
    for (int i = 0; i < 4 && sum>0; ++i) {
        int tx=t.x+f[i][0];
        int ty=t.y+f[i][1];
        if(in(tx,ty))
        {
            mp[tx][ty]=t.id+'0';
            ans[t.id]++;
            sum--;
            q.push({tx,ty,t.id});
            dfs({tx,ty,t.id},step-1);
        }
        if(sum==0)return;
    }
}
int main()
{
    scanf("%d%d%d",&n,&m,&p);
    for (int i = 1; i <= p; ++i) {
        scanf("%d",&s[i]);
    }
    memset(ans,0, sizeof(ans));
    vector<node>v;
    for (int i = 1; i <= n; ++i) {
        getchar();
        for (int j = 1; j <= m; ++j) {
            scanf("%c",&mp[i][j]);
            if(mp[i][j]<='9'&&mp[i][j]>='1')
            {
                v.push_back({i,j,mp[i][j]-'0'});
                ans[mp[i][j]-'0']++;
            }
            if(mp[i][j]=='.')sum++;
        }
    }
    sort(v.begin(),v.end());
    for (int i = 0; i < v.size(); ++i) {
        q.push(v[i]);
    }
    while(!q.empty()&&sum>0)
    {
        node t=q.front();
        q.pop();
        dfs(t,min(s[t.id],n*m));
    }
    for (int i = 1; i < p; ++i) {
        printf("%d ",ans[i]);
    }
    printf("%d\n",ans[p]);
}
/*
4 4 2
2 2
12..
.###
.#.#
.###*/


#include "bits/stdc++.h"
using namespace std;
const int mod = 1e9+7;
int s[15];
int ans[15];
int n,m,p;
int f[4][2]={0,1,0,-1,1,0,-1,0};
struct node
{
    int x,y,id;
    bool friend operator < (node a,node b)
    {
        return a.id<b.id;
    }
};
char mp[1004][1004];
bool in(int x,int y)
{
    return x>=1&&x<=n&&y>=1&&y<=m&&mp[x][y]=='.';
}
queue<node>q;int sum=0;
void dfs(node t,int step)
{
    //if(sum==0)return;
    if(step==0)return;
    for (int i = 0; i < 4 && ; ++i) {
        int tx=t.x+f[i][0];
        int ty=t.y+f[i][1];
        if(in(tx,ty))
        {
            mp[tx][ty]=t.id+'0';
            ans[t.id]++;
            //sum--;
            q.push({tx,ty,t.id});
            dfs({tx,ty,t.id},step-1);
        }
        //if(sum==0)return;
    }
}
int main()
{
    scanf("%d%d%d",&n,&m,&p);
    for (int i = 1; i <= p; ++i) {
        scanf("%d",&s[i]);
    }
    memset(ans,0, sizeof(ans));
    vector<node>v;
    for (int i = 1; i <= n; ++i) {
        getchar();
        for (int j = 1; j <= m; ++j) {
            scanf("%c",&mp[i][j]);
            if(mp[i][j]<='9'&&mp[i][j]>='1')
            {
                v.push_back({i,j,mp[i][j]-'0'});
                ans[mp[i][j]-'0']++;
            }
            if(mp[i][j]=='.')sum++;
        }
    }
    sort(v.begin(),v.end());
    for (int i = 0; i < v.size(); ++i) {
        q.push(v[i]);
    }
    while(!q.empty())
    {
        node t=q.front();
        q.pop();
        dfs(t,s[t.id]);
    }
    for (int i = 1; i < p; ++i) {
        printf("%d ",ans[i]);
    }
    printf("%d\n",ans[p]);
}
/*
4 4 2
2 2
12..
.###
.#.#
.###*/


#include "bits/stdc++.h"
using namespace std;
const int mod = 1e9+7;
int s[15];
int ans[15];
int n,m,p;
int f[4][2]={0,1,0,-1,1,0,-1,0};
struct node
{
    int x,y,id,st;
    bool friend operator < (node a,node b)
    {
        return a.id<b.id;
    }
};
char mp[1004][1004];
bool in(int x,int y)
{
    return x>=1&&x<=n&&y>=1&&y<=m&&mp[x][y]=='.';
}
queue<node>q;int sum=0;
queue<node>q2;
void bfs(node tt,int step)
{
    if(sum==0)return;
    if(step==0)return;
    q2.push(tt);
    while(!q2.empty())
    {
        node t=q2.front();
        q2.pop();
        if(t.st==0)continue;
        for (int i = 0; i < 4 && sum>0; ++i) {
            int tx=t.x+f[i][0];
            int ty=t.y+f[i][1];
            if(in(tx,ty))
            {
                mp[tx][ty]=t.id+'0';
                ans[t.id]++;
                sum--;
                q.push({tx,ty,t.id,s[t.id]});
                q2.push({tx,ty,t.id,t.st-1});
            }
            if(sum==0)return;
        }
    }

}
int main()
{
    scanf("%d%d%d",&n,&m,&p);
    for (int i = 1; i <= p; ++i) {
        scanf("%d",&s[i]);
    }
    memset(ans,0, sizeof(ans));
    vector<node>v;
    for (int i = 1; i <= n; ++i) {
        getchar();
        for (int j = 1; j <= m; ++j) {
            scanf("%c",&mp[i][j]);
            if(mp[i][j]<='9'&&mp[i][j]>='1')
            {
                v.push_back({i,j,mp[i][j]-'0'});
                ans[mp[i][j]-'0']++;
            }
            if(mp[i][j]=='.')sum++;
        }
    }
    sort(v.begin(),v.end());
    for (int i = 0; i < v.size(); ++i) {
        v[i].st=s[v[i].id];
        q.push(v[i]);
    }
    while(!q.empty()&&sum>0)
    {
        node t=q.front();
        q.pop();
        while(!q2.empty())q2.pop();
        bfs(t,s[t.id]);
    }
    for (int i = 1; i < p; ++i) {
        printf("%d ",ans[i]);
    }
    printf("%d\n",ans[p]);
}
/*
4 4 2
2 2
12..
.###
.#.#
.###*/


#include "bits/stdc++.h"
using namespace std;
const int mod = 1e9+7;
int s[15];
int ans[15];
int n,m,p;
int f[4][2]={0,1,0,-1,1,0,-1,0};
struct node
{
    int x,y,id;
    bool friend operator < (node a,node b)
    {
        return a.id<b.id;
    }
};
char mp[1004][1004];
bool in(int x,int y)
{
    return x>=1&&x<=n&&y>=1&&y<=m&&mp[x][y]=='.';
}
queue<node>q;int sum=0;
void dfs(node t,int step)
{
    if(sum==0)return;
    if(step==0)return;
    for (int i = 0; i < 4 && sum>0; ++i) {
        int tx=t.x+f[i][0];
        int ty=t.y+f[i][1];
        if(in(tx,ty))
        {
            mp[tx][ty]=t.id+'0';
            ans[t.id]++;
            sum--;
            q.push({tx,ty,t.id});
            dfs({tx,ty,t.id},step-1);
        }
        if(sum==0)return;
    }
}
int main()
{
    scanf("%d%d%d",&n,&m,&p);
    for (int i = 1; i <= p; ++i) {
        scanf("%d",&s[i]);
    }
    memset(ans,0, sizeof(ans));
    vector<node>v;
    for (int i = 1; i <= n; ++i) {
        getchar();
        for (int j = 1; j <= m; ++j) {
            scanf("%c",&mp[i][j]);
            if(mp[i][j]<='9'&&mp[i][j]>='1')
            {
                v.push_back({i,j,mp[i][j]-'0'});
                ans[mp[i][j]-'0']++;
            }
            if(mp[i][j]=='.')sum++;
        }
    }
    sort(v.begin(),v.end());
    for (int i = 0; i < v.size(); ++i) {
        q.push(v[i]);
    }
    while(!q.empty()&&sum>0)
    {
        node t=q.front();
        q.pop();
        dfs(t,min(s[t.id],n*m));
    }
    for (int i = 1; i < p; ++i) {
        printf("%d ",ans[i]+1);
    }
    printf("%d\n",ans[p]);
}
/*
4 4 2
2 2
12..
.###
.#.#
.###*/


#include "bits/stdc++.h"
using namespace std;
const int mod = 1e9+7;
int s[15];
int ans[15];
int n,m,p;
int f[4][2]={0,1,0,-1,1,0,-1,0};
struct node
{
    int x,y,id;
    bool friend operator < (node a,node b)
    {
        return a.id<b.id;
    }
};
char mp[1004][1004];
bool in(int x,int y)
{
    return x>=1&&x<=n&&y>=1&&y<=m&&mp[x][y]=='.';
}
int main()
{

    scanf("%d%d%d",&n,&m,&p);
    for (int i = 1; i <= p; ++i) {
        scanf("%d",&s[i]);
    }
    memset(ans,0, sizeof(ans));
    queue<node>q;
    vector<node>v;
    for (int i = 1; i <= n; ++i) {
        getchar();
        for (int j = 1; j <= m; ++j) {
            scanf("%c",&mp[i][j]);
            if(mp[i][j]<='9'&&mp[i][j]>='1')
            {
                v.push_back({i,j,mp[i][j]-'0'});
            }
        }
    }
    sort(v.begin(),v.end());
    for (int i = 0; i < v.size(); ++i) {
        q.push(v[i]);
    }
    while(!q.empty())
    {
        node t=q.front();
        q.pop();
        for (int i = 0; i < 4; ++i) {
            int tx=t.x+f[i][0];
            int ty=t.y+f[i][1];
            if(in(tx,ty))
            {
                mp[tx][ty]=t.id+'0';
                ans[t.id]++;
                q.push({tx,ty,t.id});
            }
        }
    }
    for (int i = 1; i < p; ++i) {
        printf("%d ",ans[i]+1);
    }
    printf("%d\n",ans[p]+1);
}


#include "bits/stdc++.h"
using namespace std;
const int mod = 1e9+7;
int s[15];
int ans[15];
int n,m,p;
int f[4][2]={0,1,0,-1,1,0,-1,0};

struct node
{
    int x,y,id,st;
    bool friend operator < (node a,node b)
    {
        return a.id<b.id;
    }
};

char mp[1004][1004];

bool in(int x,int y) { return x>=1&&x<=n&&y>=1&&y<=m&&mp[x][y]=='.'; }
queue<node>q;
queue<node>q2;
void bfs(node tt)
{
    q2.push(tt);
    while(!q2.empty())
    {
        node t=q2.front();
        q2.pop();
        if(t.st==0)continue;
        for (int i = 0; i < 4 ; ++i) {
            int tx=t.x+f[i][0];
            int ty=t.y+f[i][1];
            if(in(tx,ty))
            {
                mp[tx][ty]=t.id+'0';
                ans[t.id]++;
                q.push({tx,ty,t.id,s[t.id]});
                q2.push({tx,ty,t.id,t.st-1});
            }
        }
    }

}
int main()
{
    scanf("%d%d%d",&n,&m,&p);
    for (int i = 1; i <= p; ++i) {
        scanf("%d",&s[i]);
    }
    memset(ans,0, sizeof(ans));
    vector<node>v;
    for (int i = 1; i <= n; ++i) {
        getchar();
        for (int j = 1; j <= m; ++j) {
            scanf("%c",&mp[i][j]);
            if(mp[i][j]<='9'&&mp[i][j]>='1')
            {
                v.push_back({i,j,mp[i][j]-'0'});
                ans[mp[i][j]-'0']++;
            }
        }
    }
    sort(v.begin(),v.end());
    for (int i = 0; i < v.size(); ++i) {
        v[i].st=s[v[i].id];
        q.push(v[i]);
    }
    while(!q.empty())
    {
        node t=q.front();
        q.pop();
        while(!q2.empty())q2.pop();
        bfs(t);
    }
    for (int i = 1; i < p; ++i) {
        printf("%d ",ans[i]);
    }
    printf("%d\n",ans[p]);
}


#include "bits/stdc++.h"
using namespace std;
const int mod = 1e9+7;
int s[15];
int ans[15];
int n,m,p;
int f[4][2]={0,1,0,-1,1,0,-1,0};
struct node
{
    int x,y,id;
    bool friend operator < (node a,node b)
    {
        return a.id<b.id;
    }
};
char mp[1004][1004];
bool in(int x,int y)
{
    return x>=1&&x<=n&&y>=1&&y<=m&&mp[x][y]=='.';
}
queue<node>q;int sum=0;
void dfs(node t,int step)
{
    if(sum==0)return;
    if(step==0)return;
    for (int i = 0; i < 4; ++i) {
        int tx=t.x+f[i][0];
        int ty=t.y+f[i][1];
        if(in(tx,ty))
        {
            mp[tx][ty]=t.id+'0';
            ans[t.id]++;
            sum--;
            q.push({tx,ty,t.id});
            dfs({tx,ty,t.id},step-1);
        }
    }
}
int main()
{
    scanf("%d%d%d",&n,&m,&p);
    for (int i = 1; i <= p; ++i) {
        scanf("%d",&s[i]);
    }
    memset(ans,0, sizeof(ans));
    vector<node>v;
    for (int i = 1; i <= n; ++i) {
        getchar();
        for (int j = 1; j <= m; ++j) {
            scanf("%c",&mp[i][j]);
            if(mp[i][j]<='9'&&mp[i][j]>='1')
            {
                v.push_back({i,j,mp[i][j]-'0'});
            }
            if(mp[i][j]=='.')sum++;
        }
    }
    sort(v.begin(),v.end());
    for (int i = 0; i < v.size(); ++i) {
        q.push(v[i]);
    }
    while(!q.empty()&&sum>0)
    {
        node t=q.front();
        q.pop();
        dfs(t,s[t.id]);
        /*for (int j = 1; j <= s[t.id]; ++j) {
            for (int i = 0; i < 4; ++i) {
                int tx=t.x+f[i][0];
                int ty=t.y+f[i][1];
                if(in(tx,ty))
                {
                    mp[tx][ty]=t.id+'0';
                    ans[t.id]++;
                    q.push({tx,ty,t.id});
                }
            }
        }*/
    }
    for (int i = 1; i < p; ++i) {
        printf("%d ",ans[i]+1);
    }
    printf("%d\n",ans[p]+1);
}


#include "bits/stdc++.h"
using namespace std;
const int mod = 1e9+7;
int s[15];
int ans[15];
int n,m,p;
int f[4][2]={0,1,0,-1,1,0,-1,0};
struct node
{
    int x,y,id;
    bool friend operator < (node a,node b)
    {
        return a.id<b.id;
    }
};
char mp[1004][1004];
bool in(int x,int y)
{
    return x>=1&&x<=n&&y>=1&&y<=m&&mp[x][y]=='.';
}
queue<node>q;int sum=0;
void dfs(node t,int step)
{
    if(sum==0)return;
    if(step==0)return;
    for (int i = 0; i < 4 && sum>0; ++i) {
        int tx=t.x+f[i][0];
        int ty=t.y+f[i][1];
        if(in(tx,ty))
        {
            mp[tx][ty]=t.id+'0';
            ans[t.id]++;
            sum--;
            q.push({tx,ty,t.id});
            dfs({tx,ty,t.id},step-1);
        }
        if(sum==0)return;
    }
}
int main()
{
    scanf("%d%d%d",&n,&m,&p);
    for (int i = 1; i <= p; ++i) {
        scanf("%d",&s[i]);
    }
    memset(ans,0, sizeof(ans));
    vector<node>v;
    for (int i = 1; i <= n; ++i) {
        getchar();
        for (int j = 1; j <= m; ++j) {
            scanf("%c",&mp[i][j]);
            if(mp[i][j]<='9'&&mp[i][j]>='1')
            {
                v.push_back({i,j,mp[i][j]-'0'});
                ans[mp[i][j]-'0']++;
            }
            if(mp[i][j]=='.')sum++;
        }
    }
    sort(v.begin(),v.end());
    for (int i = 0; i < v.size(); ++i) {
        q.push(v[i]);
    }
    while(!q.empty()&&sum>0)
    {
        node t=q.front();
        q.pop();
        dfs(t,s[t.id]);
    }
    for (int i = 1; i < p; ++i) {
        printf("%d ",ans[i]);
    }
    printf("%d\n",ans[p]);
}
/*
4 4 2
2 2
12..
.###
.#.#
.###*/


#include "bits/stdc++.h"
using namespace std;
const int mod = 1e9+7;
int s[15];
int ans[15];
int n,m,p;
int f[4][2]={0,1,0,-1,1,0,-1,0};
struct node
{
    int x,y,id;
    bool friend operator < (node a,node b)
    {
        return a.id<b.id;
    }
};
char mp[1004][1004];
bool in(int x,int y)
{
    return x>=1&&x<=n&&y>=1&&y<=m&&mp[x][y]=='.';
}
queue<node>q;int sum=0;
void dfs(node t,int step)
{
    if(sum==0)return;
    if(step==0)return;
    for (int i = 0; i < 4 && sum>0; ++i) {
        int tx=t.x+f[i][0];
        int ty=t.y+f[i][1];
        if(in(tx,ty))
        {
            mp[tx][ty]=t.id+'0';
            ans[t.id]++;
            sum--;
            q.push({tx,ty,t.id});
            dfs({tx,ty,t.id},step-1);
        }
        if(sum==0)return;
    }
}
int main()
{
    scanf("%d%d%d",&n,&m,&p);
    for (int i = 1; i <= p; ++i) {
        scanf("%d",&s[i]);
    }
    memset(ans,0, sizeof(ans));
    vector<node>v;
    for (int i = 1; i <= n; ++i) {
        getchar();
        for (int j = 1; j <= m; ++j) {
            scanf("%c",&mp[i][j]);
            if(mp[i][j]<='9'&&mp[i][j]>='1')
            {
                v.push_back({i,j,mp[i][j]-'0'});
                ans[mp[i][j]-'0']++;
            }
            if(mp[i][j]=='.')sum++;
        }
    }
    sort(v.begin(),v.end());
    for (int i = 0; i < v.size(); ++i) {
        q.push(v[i]);
    }
    while(!q.empty()&&sum>0)
    {
        node t=q.front();
        q.pop();
        dfs(t,min(s[t.id]));
    }
    for (int i = 1; i < p; ++i) {
        printf("%d ",ans[i]);
    }
    printf("%d\n",ans[p]);
}
/*
4 4 2
2 2
12..
.###
.#.#
.###*/


#include "bits/stdc++.h"
using namespace std;
const int mod = 1e9+7;
int s[15];
int ans[15];
int n,m,p;
int f[4][2]={0,1,0,-1,1,0,-1,0};
struct node
{
    int x,y,id;
    bool friend operator < (node a,node b)
    {
        return a.id<b.id;
    }
};
char mp[1004][1004];
bool in(int x,int y)
{
    return x>=1&&x<=n&&y>=1&&y<=m&&mp[x][y]=='.';
}
queue<node>q;int sum=0;
void dfs(node t,int step)
{
    //if(sum==0)return;
    if(step==0)return;
    for (int i = 0; i < 4  ; ++i) {
        int tx=t.x+f[i][0];
        int ty=t.y+f[i][1];
        if(in(tx,ty))
        {
            mp[tx][ty]=t.id+'0';
            ans[t.id]++;
            //sum--;
            q.push({tx,ty,t.id});
            dfs({tx,ty,t.id},step-1);
        }
        //if(sum==0)return;
    }
}
int main()
{
    scanf("%d%d%d",&n,&m,&p);
    for (int i = 1; i <= p; ++i) {
        scanf("%d",&s[i]);
    }
    memset(ans,0, sizeof(ans));
    vector<node>v;
    for (int i = 1; i <= n; ++i) {
        getchar();
        for (int j = 1; j <= m; ++j) {
            scanf("%c",&mp[i][j]);
            if(mp[i][j]<='9'&&mp[i][j]>='1')
            {
                v.push_back({i,j,mp[i][j]-'0'});
                ans[mp[i][j]-'0']++;
            }
            if(mp[i][j]=='.')sum++;
        }
    }
    sort(v.begin(),v.end());
    for (int i = 0; i < v.size(); ++i) {
        q.push(v[i]);
    }
    while(!q.empty())
    {
        node t=q.front();
        q.pop();
        dfs(t,s[t.id]);
    }
    for (int i = 1; i < p; ++i) {
        printf("%d ",ans[i]);
    }
    printf("%d\n",ans[p]);
}
/*
4 4 2
2 2
12..
.###
.#.#
.###*/


//#include "stdc++.h"
#include<bits/stdc++.h>
#include<iostream>
#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:336777216")
using namespace std;
//mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
//typedef tuple<int, int, int> t3;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <ll, int> pli;
typedef pair <db, db> pdd;
typedef vector<int> vi;
#define m1 make_pair
#define pb push_back
#define ff first
#define ss second
#define IOS std::ios::sync_with_stdio(false); cin.tie(NULL);cout.tie(NULL);
#define reset(x,val) memset(x,val,sizeof(x))
inline ll gcd(ll a,ll b){if(a==0) return b;return gcd(b%a,a);}
inline ll power(ll a,ll n,ll m){if(n==0) return 1;ll p=power(a,n/2,m);p=(p*p)%m;if(n%2) return (p*a)%m;else return p; }
#define flush fflush(stdout)
const ll MOD = 1000000007;
//const int INF =1010000000;
#define int long long int
const ll INF = 0x3f3f3f3f3f3f3f3f;

int32_t main()
{
    IOS;
    int n,m;int p;
    cin>>n>>m>>p;
    string st[n];
   // int a[n][m];
   // memset(,0,sizeof(a));
    int s[p+1]; int cnt=0;
    for(int i=1;i<=p;i++)
        cin>>s[i];
    for(int i=0;i<n;i++)
        cin>>st[i];
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            if(st[i][j]!='.')
                cnt++;
    char ch;int i1,j1;pair<int,int>p1;int tl=0;
    while(tl<=50)
    {
        for(int i=1;i<=p;i++)
        {
            int b[n][m];bool visited[n][m];
            memset(visited,0,sizeof(visited));
            //memset(b,INF,sizeof(b));
            for(int j=0;j<n;j++)
                for(int k=0;k<m;k++)
                    b[j][k]=INF;
            ch=(char)(i+'0');
            // cout<<ch<<endl;
            queue<pair<int,int> >q;
            for(int j=0;j<n;j++)
                for(int k=0;k<m;k++)
                    if(st[j][k]==ch)
                    { b[j][k]=0;
                        q.push(m1(j,k));
                        visited[j][k]=1;
                       // if(i==2)
                        //{
                       //     cout<<j<<" "<<k<<endl;
                       // }
                    }

            while(!q.empty())
            {
                p1=q.front();
                q.pop();
                i1=p1.first;j1=p1.second;
                if(i1>=1&&(!visited[i1-1][j1])&&(st[i1-1][j1]=='.'||st[i1-1][j1]==ch))
                {
                    b[i1-1][j1]=1+b[i1][j1];
                    visited[i1-1][j1]=1;
                    q.push(m1(i1-1,j1));
                }
                if(j1>=1&&(!visited[i1][j1-1])&&(st[i1][j1-1]=='.'||st[i1][j1-1]==ch))
                {
                    b[i1][j1-1]=1+b[i1][j1];
                    visited[i1][j1-1]=1;
                    q.push(m1(i1,j1-1));
                }
                if(i1<n-1&&(!visited[i1+1][j1])&&(st[i1+1][j1]=='.'||st[i1+1][j1]==ch))
                {
                    b[i1+1][j1]=1+b[i1][j1];
                    visited[i1+1][j1]=1;
                    q.push(m1(i1+1,j1));
                }
                if(j1<m-1&&(!visited[i1][j1+1])&&(st[i1][j1+1]=='.'||st[i1][j1+1]==ch))
                {
                    b[i1][j1+1]=1+b[i1][j1];
                    visited[i1][j1+1]=1;
                    q.push(m1(i1,j1+1));
                }
            }
            cnt=0;ch=i+'0';
            for(int j=0;j<n;j++)
            {
                for(int k=0;k<m;k++)
                {

                    if(st[j][k]=='.'&&b[j][k]<=s[i])
                        st[j][k]=ch;
                   // if(st[j][k]!='.')
                     //   cnt++;
                }
            }
            //if(cnt>=(n*m))
               // break;

        }
        tl++;
    }
    int ans[p+1];
    for(int i=1;i<=p;i++)
        ans[i]=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            if(st[i][j]!='#'&&st[i][j]!='.')
            {
                ans[st[i][j]-'0']++;
            }
        }
    for(int i=1;i<=p;i++)
        cout<<ans[i]<<" ";
    cout<<endl;
    return 0;
}