#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
inline void chkmax(int &x, int y) { x < y ? (x = y) : 0; }
inline void chkmin(int &x, int y) { x > y ? (x = y) : 0; }
int n, m, p;
struct node {
  int x, y;
};
const int N = 1005;
queue<node> q[10], ex[10];
char sq[N][N];
int vis[N][N], s[15], cnt[10];
const int dx[] = {1, 0, 0, -1}, dy[] = {0, -1, 1, 0};
void file() {}
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  for (; ch < '0' || ch > '9'; ch = getchar())
    if (ch == '-') f = -1;
  for (; ch >= '0' && ch <= '9'; ch = getchar())
    x = (x << 1) + (x << 3) + ch - '0';
  return x * f;
}
void bfs(int u) {
  while (ex[u].size()) ex[u].pop();
  while (!q[u].empty()) {
    int nowx = q[u].front().x;
    int nowy = q[u].front().y;
    q[u].pop();
    for (int i = 0; i < 4; i++) {
      int nx = nowx + dx[i], ny = nowy + dy[i];
      if (nx > 0 && nx <= n && ny > 0 && ny <= m && !vis[nx][ny] &&
          sq[nx][ny] != '#') {
        vis[nx][ny] = u;
        ex[u].push((node){nx, ny});
      }
    }
  }
  q[u] = ex[u];
}
int main() {
  n = read();
  m = read();
  p = read();
  for (int i = 1; i <= p; i++) s[i] = read();
  for (int i = 1; i <= n; i++) {
    cin >> sq[i] + 1;
    for (int j = 1; j <= m; j++)
      if (sq[i][j] >= '0' && sq[i][j] <= '9') {
        q[sq[i][j] - '0'].push((node){i, j});
        vis[i][j] = sq[i][j] - '0';
      }
  }
  bool flag = true;
  while (flag) {
    flag = false;
    for (int i = 1; i <= p; i++)
      for (int j = 1; j <= s[i]; j++)
        if (q[i].size())
          bfs(i), flag = true;
        else
          break;
  }
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) cnt[vis[i][j]]++;
  for (int i = 1; i <= p; i++) printf("%d ", cnt[i]);
  puts("");
  return 0;
}
