#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int max(int a, int b) { return (a > b) ? a : b; }

const int MAXN = 300000;
const int MOD = (int) 1e9+7;
int a[MAXN];

const int INF = 1e9;

char c[1000][1000];
int dist[10][1000][1000];
vector<int> dx = {0, 1, 0, -1};
vector<int> dy = {1, 0, -1, 0};

bool inField(int ni, int nj, int n, int m);

void bfs(int x, int n, int m)
{
    deque<int> q;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (c[i][j] == '#') dist[x][i][j] = -1;
            if (c[i][j] == '0' + x)
            {
                dist[x][i][j] = 0;
                q.push_back(i);
                q.push_back(j);
            }
        }
    }

    while (!q.empty())
    {
        int i = q.front(); q.pop_front();
        int j = q.front(); q.pop_front();
        for (int v = 0; v < 4; v++)
        {
            int ni = i + dx[v];
            int nj = j + dy[v];
            if (inField(ni, nj, n, m) && dist[x][ni][nj] > dist[x][i][j] + 1)
            {
                dist[x][ni][nj] = dist[x][i][j] + 1;
                q.push_back(ni);
                q.push_back(nj);
            }
        }
    }
}

bool inField(int ni, int nj, int n, int m) {
    return (ni >= 0 && nj >= 0 && ni < n && nj < m);
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n, m, p;
    cin >> n >> m >> p;
    for (int i = 1; i  <= p; i++)
    {
        cin >> a[i];
    }
    for (int i = 0; i < n; i++)
    {
        fgets(c[i], 1000, stdin);
    }

    for (int q = 1; q <= p; q++)
    {
        for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            dist[q][i][j] = INF;
        bfs(q, n, m);
//        for (int i = 0; i < n; i++)
//            for (int j = 0; j < m; j++)
//                cerr << dist[q][i][j] << " \n"[j == m - 1];
    }
    vector<int> ans(10);

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (c[i][j] == '#') continue;
            if (c[i][j] != '.') ans[c[i][j] - '0']++;
            if (c[i][j] == '.')
            {
                int z = INF;
                int zz = -1;
                for (int q = 1; q <= p; q++) {
                    if ((dist[q][i][j] - 1) / a[q] + 1 < z) {
                        z = (dist[q][i][j] - 1) / a[q] + 1;
                        zz = q;
                    }
                }
                ans[zz]++;
            }
        }
        }
    for (int i = 1; i <= p; i++)
    {
        cout << ans[i] << " ";
    }
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int max(int a, int b) { return (a > b) ? a : b; }

const int MAXN = 300000;
const int MOD = (int) 1e9+7;
int a[MAXN];

const int INF = 1e9;

char c[1000][1000];
int dist[10][1000][1000];
vector<int> dx = {0, 1, 0, -1};
vector<int> dy = {1, 0, -1, 0};

bool inField(int ni, int nj, int n, int m);

void bfs(int x, int n, int m)
{
    deque<int> q;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (c[i][j] == '#') dist[x][i][j] = -1;
            if (c[i][j] == '0' + x)
            {
                dist[x][i][j] = 0;
                q.push_back(i);
                q.push_back(j);
            }
        }
    }

    while (!q.empty())
    {
        int i = q.front(); q.pop_front();
        int j = q.front(); q.pop_front();
        for (int v = 0; v < 4; v++)
        {
            int ni = i + dx[v];
            int nj = j + dy[v];
            if (inField(ni, nj, n, m) && dist[x][ni][nj] > dist[x][i][j] + 1)
            {
                dist[x][ni][nj] = dist[x][i][j] + 1;
                q.push_back(ni);
                q.push_back(nj);
            }
        }
    }
}

bool inField(int ni, int nj, int n, int m) {
    return (ni >= 0 && nj >= 0 && ni < n && nj < m);
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n, m, p;
    cin >> n >> m >> p;
    for (int i = 1; i  <= p; i++)
    {
        cin >> a[i];
    }
    for (int i = 0; i < n; i++)
    {
        fgets(c[i], 1000, stdin);
    }

    for (int q = 1; q <= p; q++)
    {
        for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            dist[q][i][j] = INF;
        bfs(q, n, m);
//        for (int i = 0; i < n; i++)
//            for (int j = 0; j < m; j++)
//                cerr << dist[q][i][j] << " \n"[j == m - 1];
    }
    vector<int> ans(10, 0);

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (c[i][j] == '#') continue;
            if (c[i][j] != '.') ans[c[i][j] - '0']++;
            if (c[i][j] == '.')
            {
                int z = INF;
                int zz = -1;
                for (int q = 1; q <= p; q++) {
                    if ((dist[q][i][j] - 1) / a[q] + 1 < z) {
                        z = (dist[q][i][j] - 1) / a[q] + 1;
                        zz = q;
                    }
                }
                ans[zz]++;
            }
        }
    }
    for (int i = 1; i <= p; i++)
    {
        cout << ans[i] << " ";
    }
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int max(int a, int b)
{ return (a > b) ? a : b; }

const int MAXN = 1000;
char c[MAXN][MAXN];
int a[10];

int n, m;
vector<int> dx = {0, 1, 0, -1};
vector<int> dy = {1, 0, -1, 0};

bool inField(int ni, int nj);

void bfs(deque<int>& deque1, int x, int y)
{
    int color = c[x][y] - '0';
    int step = a[color];
    deque<int> q;
    q.push_back(x);
    q.push_back(y);
    q.push_back(0);
    while (!q.empty())
    {
        int i = q.front(); q.pop_front();
        int j = q.front(); q.pop_front();
        int s = q.front(); q.pop_front();
        for (int v = 0; v < 4; v++)
        {
            int ni = i + dx[v];
            int nj = j + dy[v];
            int ns = s + 1;
            if (inField(ni, nj) && c[ni][nj] == '.')
            {
                c[ni][nj] = c[x][y];
                if (ns == step)
                {
                    deque1.push_back(ni);
                    deque1.push_back(nj);
                } else {
                    q.push_back(ni);
                    q.push_back(nj);
                    q.push_back(ns);
                }
            }
        }
    }
}

bool inField(int ni, int nj) {
    return (ni >= 0 && nj >= 0 && ni < n && nj < m);
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int p;
    cin >> n >> m >> p;
    for (int i = 1; i <= p; i++)
    {
        cin >> a[i];
    }
    for (int i = 0; i < n; i++)
    {
        string s;
        cin >> s;
        for (int j = 0; j  <m; j++)
        {
            c[i][j] = s[j];
        }
    }

//    cerr << "1";
    deque<int> q;
    for (int qq = 1; qq <= p; qq++)
    {
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                if (c[i][j] == '0' + qq)
                {
                    q.push_back(i);
                    q.push_back(j);
                }
            }
        }
    }

//    cerr << "2";
    while (!q.empty())
    {
        int i = q.front(); q.pop_front();
        int j = q.front(); q.pop_front();
        bfs(q, i, j);
    }

//    cerr << "3";
    vector<int> ans(10, 0);
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (c[i][j] != '#' && c[i][j] != '.')
                ans[c[i][j] - '0']++;
        }
    }
//    cerr << "5";
    for (int q = 1; q <= p; q++)
    {
        cout << ans[q] << " ";
    }

}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int max(int a, int b) { return (a > b) ? a : b; }

const int MAXN = 300000;
const int MOD = (int) 1e9+7;
int a[MAXN];

const int INF = 1e9;

char c[1000][1000];
int dist[10][1000][1000];
vector<int> dx = {0, 1, 0, -1};
vector<int> dy = {1, 0, -1, 0};

bool inField(int ni, int nj, int n, int m);

void bfs(int x, int n, int m)
{
    deque<int> q;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (c[i][j] == '#') dist[x][i][j] = -1;
            if (c[i][j] == '0' + x)
            {
                dist[x][i][j] = 0;
                q.push_back(i);
                q.push_back(j);
            }
        }
    }

    while (!q.empty())
    {
        int i = q.front(); q.pop_front();
        int j = q.front(); q.pop_front();
        for (int v = 0; v < 4; v++)
        {
            int ni = i + dx[v];
            int nj = j + dy[v];
            if (inField(ni, nj, n, m) && dist[x][ni][nj] > dist[x][i][j] + 1)
            {
                dist[x][ni][nj] = dist[x][i][j] + 1;
                q.push_back(ni);
                q.push_back(nj);
            }
        }
    }
}

bool inField(int ni, int nj, int n, int m) {
    return (ni >= 0 && nj >= 0 && ni < n && nj < m);
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n, m, p;
    cin >> n >> m >> p;
    for (int i = 1; i  <= p; i++)
    {
        cin >> a[i];
    }
    string s;
    for (int i = 0; i < n; i++)
    {
        cin >> s;
        for (int j = 0; j < m; j++)
        {
            c[i][j] = s[j];
        }
//        c[i] = s.c_str();
//        fgets(c[i], 1000, stdin);
    }

    for (int q = 1; q <= p; q++)
    {
        for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            dist[q][i][j] = INF;
        bfs(q, n, m);
//        for (int i = 0; i < n; i++)
//            for (int j = 0; j < m; j++)
//                cerr << dist[q][i][j] << " \n"[j == m - 1];
    }
    vector<int> ans(10, 0);
    for (int i = 0; i < 10; i++)
    {
        ans[i] = 0;
    }

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
//            cout << c[i][i] << " \n"[j == m - 1];
            if (c[i][j] == '#') continue;
            if (c[i][j] != '.') ans[c[i][j] - '0']++;
            if (c[i][j] == '.')
            {
                int z = INF;
                int zz = -1;
                for (int q = 1; q <= p; q++) {
                    if ((dist[q][i][j] - 1) / a[q] + 1 < z) {
                        z = (dist[q][i][j] - 1) / a[q] + 1;
                        zz = q;
                    }
                }
                ans[zz]++;
            }
        }
    }
//    cout << n <<" " <<  m << " ";
    for (int i = 1; i <= p; i++)
    {
        cout << ans[i] << " ";
    }
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int max(int a, int b) { return (a > b) ? a : b; }

const int MAXN = 300000;
const int MOD = (int) 1e9+7;
int a[MAXN];

const int INF = 1e9;

char c[1000][1000];
int dist[10][1000][1000];
int pl[1000][1000][10];
int perm[1000][1000][10];

bool ok[1000][1000];
int cur[1000][1000];
vector<int> dx = {0, 1, 0, -1};
vector<int> dy = {1, 0, -1, 0};

bool inField(int ni, int nj, int n, int m);

void bbfs(int n, int m, int qq)
{
    deque<int> q;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (c[i][j] == '#') continue;
            if (ok[i][j])
            {
                q.push_back(i);
                q.push_back(j);
            }
        }
    }

    while (!q.empty())
    {
        int i = q.front(); q.pop_front();
        int j = q.front(); q.pop_front();
        for (int v = 0; v < 4; v++)
        {
            int ni = i + dx[v];
            int nj = j + dy[v];
            if (inField(ni, nj, n, m) && !ok[ni][nj] && perm[i][j][cur[i][j]] <= qq)
            {
                ok[ni][nj] = 1;
                q.push_back(ni);
                q.push_back(nj);
            }
        }
    }
}
void bfs(int x, int n, int m)
{
    deque<int> q;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (c[i][j] == '#') dist[x][i][j] = -1;
            if (c[i][j] == '0' + x)
            {
                dist[x][i][j] = 0;
                q.push_back(i);
                q.push_back(j);
            }
        }
    }

    while (!q.empty())
    {
        int i = q.front(); q.pop_front();
        int j = q.front(); q.pop_front();
        for (int v = 0; v < 4; v++)
        {
            int ni = i + dx[v];
            int nj = j + dy[v];
            if (inField(ni, nj, n, m) && dist[x][ni][nj] > dist[x][i][j] + 1)
            {
                dist[x][ni][nj] = dist[x][i][j] + 1;
                q.push_back(ni);
                q.push_back(nj);
            }
        }
    }
}

bool inField(int ni, int nj, int n, int m) {
    return (ni >= 0 && nj >= 0 && ni < n && nj < m);
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n, m, p;
    cin >> n >> m >> p;
    for (int i = 1; i  <= p; i++)
    {
        cin >> a[i];
    }
    string s;
    for (int i = 0; i < n; i++)
    {
        cin >> s;
        for (int j = 0; j < m; j++)
        {
            c[i][j] = s[j];
        }
//        c[i] = s.c_str();
//        fgets(c[i], 1000, stdin);
    }

    for (int q = 1; q <= p; q++)
    {
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                dist[q][i][j] = INF;
        bfs(q, n, m);
//        for (int i = 0; i < n; i++)
//            for (int j = 0; j < m; j++)
//                cerr << dist[q][i][j] << " \n"[j == m - 1];
    }
    vector<int> ans(10, 0);
    for (int i = 0; i < 10; i++)
    {
        ans[i] = 0;
    }

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
//            cout << c[i][i] << " \n"[j == m - 1];
            if (c[i][j] == '#')
            {
                cur[i][j] = 0;
                ok[i][j] = true;
                continue;
            }
            if (c[i][j] != '.')
            {
                ok[i][j] = true;
                cur[i][j] = c[i][j] - '0';
            }
            if (c[i][j] == '.')
            {
                for (int q = 1; q <= p; q++) {
                    pl[i][j][q - 1] = q;
                }
                stable_sort(pl[i][j], pl[i][j] + p , [i, j](const int x, const int y)
                {
                    return ((dist[x][i][j] - 1) / a[x] < (dist[y][i][j] - 1) / a[y]);
                });
                for (int q = 0; q < p; q++)
                {
                    perm[i][j][pl[i][j][q]] = q;
                }
                cur[i][j] = pl[i][j][0];
            }
        }
    }

    for (int q = 0; q < p; q++)
    {
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                if (!ok[i][j])
                {
                    cur[i][j] = pl[i][j][q];
                }
            }
        }
        bbfs(n, m, q);
    }
//    cout << n <<" " <<  m << " ";

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            ans[cur[i][j]] += 1;
        }
    }

    for (int i = 1; i <= p; i++)
    {
        cout << ans[i] << " ";
    }
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int max(int a, int b) { return (a > b) ? a : b; }

const int MAXN = 300000;
const int MOD = (int) 1e9+7;
int a[MAXN];

const int INF = 1e9;

char c[1000][1000];
int dist[10][1000][1000];
vector<int> dx = {0, 1, 0, -1};
vector<int> dy = {1, 0, -1, 0};

bool inField(int ni, int nj, int n, int m);

void bfs(int x, int n, int m)
{
    deque<int> q;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (c[i][j] == '#') dist[x][i][j] = -1;
            if (c[i][j] == '0' + x)
            {
                dist[x][i][j] = 0;
                q.push_back(i);
                q.push_back(j);
            }
        }
    }

    while (!q.empty())
    {
        int i = q.front(); q.pop_front();
        int j = q.front(); q.pop_front();
        for (int v = 0; v < 4; v++)
        {
            int ni = i + dx[v];
            int nj = j + dy[v];
            if (inField(ni, nj, n, m) && dist[x][ni][nj] > dist[x][i][j] + 1)
            {
                dist[x][ni][nj] = dist[x][i][j] + 1;
                q.push_back(ni);
                q.push_back(nj);
            }
        }
    }
}

bool inField(int ni, int nj, int n, int m) {
    return (ni >= 0 && nj >= 0 && ni < n && nj < m);
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n, m, p;
    cin >> n >> m >> p;
    for (int i = 1; i  <= p; i++)
    {
        cin >> a[i];
    }
    for (int i = 0; i < n; i++)
    {
        fgets(c[i], 1000, stdin);
    }

    for (int q = 1; q <= p; q++)
    {
        for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            dist[q][i][j] = INF;
        bfs(q, n, m);
//        for (int i = 0; i < n; i++)
//            for (int j = 0; j < m; j++)
//                cerr << dist[q][i][j] << " \n"[j == m - 1];
    }
    vector<int> ans(10, 0);
    for (int i = 0; i < 10; i++)
    {
        ans[i] = 0;
    }

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            cout << c[i][i] << " \n"[j == m - 1];
            if (c[i][j] == '#') continue;
            if (c[i][j] != '.') ans[c[i][j] - '0']++;
            if (c[i][j] == '.')
            {
                int z = INF;
                int zz = -1;
                for (int q = 1; q <= p; q++) {
                    if ((dist[q][i][j] - 1) / a[q] + 1 < z) {
                        z = (dist[q][i][j] - 1) / a[q] + 1;
                        zz = q;
                    }
                }
                ans[zz]++;
            }
        }
    }
//    cout << n <<" " <<  m << " ";
    for (int i = 1; i <= p; i++)
    {
        cout << ans[i] << " ";
    }
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int max(int a, int b) { return (a > b) ? a : b; }

const int MAXN = 300000;
const int MOD = (int) 1e9+7;
int a[MAXN];

const int INF = 1e9;

char c[1000][1000];
int dist[10][1000][1000];
vector<int> dx = {0, 1, 0, -1};
vector<int> dy = {1, 0, -1, 0};

bool inField(int ni, int nj, int n, int m);

void bfs(int x, int n, int m)
{
    deque<int> q;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (c[i][j] == '#') dist[x][i][j] = -1;
            if (c[i][j] == '0' + x)
            {
                dist[x][i][j] = 0;
                q.push_back(i);
                q.push_back(j);
            }
        }
    }

    while (!q.empty())
    {
        int i = q.front(); q.pop_front();
        int j = q.front(); q.pop_front();
        for (int v = 0; v < 4; v++)
        {
            int ni = i + dx[v];
            int nj = j + dy[v];
            if (inField(ni, nj, n, m) && dist[x][ni][nj] > dist[x][i][j] + 1)
            {
                dist[x][ni][nj] = dist[x][i][j] + 1;
                q.push_back(ni);
                q.push_back(nj);
            }
        }
    }
}

bool inField(int ni, int nj, int n, int m) {
    return (ni >= 0 && nj >= 0 && ni < n && nj < m);
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n, m, p;
    cin >> n >> m >> p;
    for (int i = 1; i  <= p; i++)
    {
        cin >> a[i];
    }
    for (int i = 0; i < n; i++)
    {
        fgets(c[i], 1000, stdin);
    }

    for (int q = 1; q <= p; q++)
    {
        for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            dist[q][i][j] = INF;
        bfs(q, n, m);
//        for (int i = 0; i < n; i++)
//            for (int j = 0; j < m; j++)
//                cerr << dist[q][i][j] << " \n"[j == m - 1];
    }
    vector<int> ans(10, 0);
    for (int i = 0; i < 10; i++)
    {
        ans[i] = 0;
    }

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (c[i][j] == '#') continue;
            if (c[i][j] != '.') ans[c[i][j] - '0']++;
            if (c[i][j] == '.')
            {
                int z = INF;
                int zz = -1;
                for (int q = 1; q <= p; q++) {
                    if ((dist[q][i][j] - 1) / a[q] + 1 < z) {
                        z = (dist[q][i][j] - 1) / a[q] + 1;
                        zz = q;
                    }
                }
                ans[zz]++;
            }
        }
    }
    cout << n <<" " <<  m << " ";
    for (int i = 1; i <= p; i++)
    {
        cout << ans[i] << " ";
    }
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int max(int a, int b)
{ return (a > b) ? a : b; }

const int MAXN = 1000;
char c[MAXN][MAXN];
int a[10];

int n, m;
vector<int> dx = {0, 1, 0, -1};
vector<int> dy = {1, 0, -1, 0};

bool inField(int ni, int nj);

void bfs(deque<int>& deque1, int x, int y)
{
    int color = c[x][y] - '0';
    int step = a[color];
    deque<int> q;
    q.push_back(x);
    q.push_back(y);
    q.push_back(0);
    while (!deque1.empty() && c[deque1[0]][deque1[1]] == c[x][y])
    {
        q.push_back(deque1.front()); deque1.pop_front();
        q.push_back(deque1.front()); deque1.pop_front();
        q.push_back(0);
    }

    while (!q.empty())
    {
        int i = q.front(); q.pop_front();
        int j = q.front(); q.pop_front();
        int s = q.front(); q.pop_front();
        for (int v = 0; v < 4; v++)
        {
            int ni = i + dx[v];
            int nj = j + dy[v];
            int ns = s + 1;
            if (inField(ni, nj) && c[ni][nj] == '.')
            {
                c[ni][nj] = c[x][y];
                if (ns == step)
                {
                    deque1.push_back(ni);
                    deque1.push_back(nj);
                } else {
                    q.push_back(ni);
                    q.push_back(nj);
                    q.push_back(ns);
                }
            }
        }
    }
}

bool inField(int ni, int nj) {
    return (ni >= 0 && nj >= 0 && ni < n && nj < m);
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int p;
    cin >> n >> m >> p;
    for (int i = 1; i <= p; i++)
    {
        cin >> a[i];
    }
    for (int i = 0; i < n; i++)
    {
        string s;
        cin >> s;
        for (int j = 0; j  <m; j++)
        {
            c[i][j] = s[j];
        }
    }

//    cerr << "1";
    deque<int> q;
    for (int qq = 1; qq <= p; qq++)
    {
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                if (c[i][j] == '0' + qq)
                {
                    q.push_back(i);
                    q.push_back(j);
                }
            }
        }
    }

//    cerr << "2";
    while (!q.empty())
    {
        int i = q.front(); q.pop_front();
        int j = q.front(); q.pop_front();
        bfs(q, i, j);
    }

//    cerr << "3";
    vector<int> ans(10, 0);
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (c[i][j] != '#' && c[i][j] != '.')
                ans[c[i][j] - '0']++;
        }
    }
//    cerr << "5";
    for (int q = 1; q <= p; q++)
    {
        cout << ans[q] << " ";
    }
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int max(int a, int b) { return (a > b) ? a : b; }

const int MAXN = 300000;
const int MOD = (int) 1e9+7;
int a[MAXN];

const int INF = 1e9;

char c[1000][1000];
int dist[10][1000][1000];
vector<int> dx = {0, 1, 0, -1};
vector<int> dy = {1, 0, -1, 0};

bool inField(int ni, int nj, int n, int m);

void bfs(int x, int n, int m)
{
    deque<int> q;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (c[i][j] == '#') dist[x][i][j] = -1;
            if (c[i][j] == '0' + x)
            {
                dist[x][i][j] = 0;
                q.push_back(i);
                q.push_back(j);
            }
        }
    }

    while (!q.empty())
    {
        int i = q.front(); q.pop_front();
        int j = q.front(); q.pop_front();
        for (int v = 0; v < 4; v++)
        {
            int ni = i + dx[v];
            int nj = j + dy[v];
            if (inField(ni, nj, n, m) && dist[x][ni][nj] > dist[x][i][j] + 1)
            {
                dist[x][ni][nj] = dist[x][i][j] + 1;
                q.push_back(ni);
                q.push_back(nj);
            }
        }
    }
}

bool inField(int ni, int nj, int n, int m) {
    return (ni >= 0 && nj >= 0 && ni < n && nj < m);
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n, m, p;
    cin >> n >> m >> p;
    for (int i = 1; i  <= p; i++)
    {
        cin >> a[i];
    }
    string s;
    for (int i = 0; i < n; i++)
    {
        cin >> s;
        for (int j = 0; j < m; j++)
        {
            c[i][j] = s[j];
        }
//        c[i] = s.c_str();
//        fgets(c[i], 1000, stdin);
    }

    for (int q = 1; q <= p; q++)
    {
        for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            dist[q][i][j] = INF;
        bfs(q, n, m);
//        for (int i = 0; i < n; i++)
//            for (int j = 0; j < m; j++)
//                cerr << dist[q][i][j] << " \n"[j == m - 1];
    }
    vector<int> ans(10, 0);
    for (int i = 0; i < 10; i++)
    {
        ans[i] = 0;
    }

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            cout << c[i][i] << " \n"[j == m - 1];
            if (c[i][j] == '#') continue;
            if (c[i][j] != '.') ans[c[i][j] - '0']++;
            if (c[i][j] == '.')
            {
                int z = INF;
                int zz = -1;
                for (int q = 1; q <= p; q++) {
                    if ((dist[q][i][j] - 1) / a[q] + 1 < z) {
                        z = (dist[q][i][j] - 1) / a[q] + 1;
                        zz = q;
                    }
                }
                ans[zz]++;
            }
        }
    }
//    cout << n <<" " <<  m << " ";
    for (int i = 1; i <= p; i++)
    {
        cout << ans[i] << " ";
    }
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <fstream>

using namespace std;

struct cell
{
	int x, y, s;
};

bool upd = 1;
char ign;

int ncnt; // newcastle's array size
int cnt[10]; // castle's array size

int n, m, p; // size & players

int field[1005][1005]; // num field

int s[10], ans[10]; // speed & answer

cell castle[10][1000005]; // coords of i-th player's castles
cell newcastle[1000005]; // newbuilt castles

void show_field()
{
	cout << endl;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << field[i][j];
		}
		cout << endl;
	}
	cout << endl;

	return;
};

void bfs(int plr, int cstl)
{
	int x1 = castle[plr][cstl].x, y1 = castle[plr][cstl].y, sp1 = castle[plr][cstl].s;
	queue < cell > q;
	q.push({ x1, y1, sp1 });

	while (!q.empty()) {

		int x = (q.front()).x, y = (q.front()).y;
		int sp = (q.front()).s;

		q.pop();

		if (y + 1 < m && field[x][y + 1] == 0 && sp) {
			upd = 1;
			field[x][y + 1] = plr;
			ans[plr]++;
			q.push({ x, y + 1, sp - 1 });
		}

		if (x + 1 < n && field[x + 1][y] == 0 && sp) {
			upd = 1;
			field[x + 1][y] = plr;
			ans[plr]++;
			q.push({ x + 1, y, sp - 1 });
		}

		if (y - 1 >= 0 && field[x][y - 1] == 0 && sp) {
			upd = 1;
			field[x][y - 1] = plr;
			ans[plr]++;
			q.push({ x, y - 1, sp - 1 });

		}
		if (x - 1 >= 0 && field[x - 1][y] == 0 && sp) {
			upd = 1;
			field[x - 1][y] = plr;
			ans[plr]++;
			q.push({ x - 1, y, sp - 1 });
		}
		if (sp == 0) {
			newcastle[ncnt++] = { x, y, s[plr] };
		}
		//show_field();
	}

	return;
}

int main()
{
	//freopen("inp.txt", "rt", stdin);
	//freopen("out.txt", "wt", stdout);

	scanf("%d %d %d", &n, &m, &p);

	for (int i = 1; i <= p; i++)
		scanf("%d", &s[i]); // speed
	scanf("%c", &ign);

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			char cell;
			scanf("%c", &cell);

			if (cell == '#') {
				field[i][j] = -1;
			} else {
				if (cell != '.') {
					int x = (int)(cell - '0');
					field[i][j] = x;
					ans[x]++;
					castle[x][cnt[x]++] = { j, i, s[x] };
				}
			}
		}
		scanf("%c", &ign);
	}

	//show_field();
	//show_coord();

	while (upd) {
		upd = 0;
		for (int i = 1; i <= p; i++) {

			for (int j = 0; j < cnt[i]; j++)
				bfs(i, j);

			for (int l = 0; l < ncnt; l++)
				castle[i][l] = { newcastle[l].x, newcastle[l].y, newcastle[l].s };

			cnt[i] = ncnt;
			ncnt = 0;
		}
	}

	//show_field();

	for (int i = 1; i <= p; i++)
		printf("%d ", ans[i]);
	printf("\n");

	return 0;
}
/*

10 10 4
1 2 4 8
1........2
..........
..........
..........
..........
..........
..........
..........
..........
3........4

answer:
6 11 29 54

20 20 4
1 2 4 8
1..................2
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
3..................4

my answer:
20 27 87 266

right answer
19 27 91 263

*/


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <fstream>

using namespace std;
char ign;
int n, m, p, used; // size & players
int field[1001][1001]; // num field
char cfield[1001][1001]; // char field
int s[10], ans[10]; // speed & answer
vector <vector<pair <int, int>>> castle(10); // coords of i-th player's castles
vector <pair<int, int>> newcastles;
void show_field()
{
	cout << endl;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << field[i][j];
		}
		cout << endl;
	}
	cout << endl;

	return;
};

void show_coord()
{
	for (int i = 1; i <= p; i++) {
		cout << endl << i << endl;
		for (int j = 0; j < castle[i].size(); j++)
			cout << "(" << castle[i][j].first << "," << castle[i][j].second << ") ";
		cout << endl;
	}

	return;
}

void bfs(int plr, int cstl)
{

	int x1 = castle[plr][cstl].first, y1 = castle[plr][cstl].second, sp1 = s[plr];
	queue <pair<pair <int, int>, int>> q;
	q.push(make_pair(make_pair(x1, y1), sp1));

	while (!q.empty()) {

		pair<pair <int, int>, int> cell = q.front();
		q.pop();
		int x = cell.first.first, y = cell.first.second;
		int sp = cell.second;
		used++;
		if (y + 1 < m && field[x][y + 1] == 0 && sp) {
			field[x][y + 1] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x, y + 1), sp - 1));
			if (sp == 1)
				newcastles.push_back(make_pair(x, y + 1));
		}
		if (x + 1 < n && field[x + 1][y] == 0 && sp) {
			field[x + 1][y] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x + 1, y), sp - 1));
			if (sp == 1)
				newcastles.push_back(make_pair(x + 1, y));
		}
		if (y - 1 >= 0 && field[x][y - 1] == 0 && sp) {
			field[x][y - 1] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x, y - 1), sp - 1));
			if (sp == 1)
				newcastles.push_back(make_pair(x, y - 1));
		}
		if (x - 1 >= 0 && field[x - 1][y] == 0 && sp) {
			field[x - 1][y] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x - 1, y), sp - 1));
			if(sp == 1)
				newcastles.push_back(make_pair(x - 1, y));
		}

	}
	//show_field();

	return;
}

int main()
{
	//freopen("inp.txt", "rt", stdin);
	//freopen("out.txt", "wt", stdout);
	ios::sync_with_stdio(0), cin.tie(0);
	scanf("%d %d %d", &n, &m, &p);

	for (int i = 1; i <= p; i++)
		scanf("%d", &s[i]); // speed
	scanf("%c", &ign);

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			char cell;
			scanf("%c", &cell);
			if (cell == '#') {
				field[i][j] = -1;
			}
			else
				if (cell != '.') {
					int x = (int)(cell - '0');
					field[i][j] = x;
					ans[x]++;
					castle[x].push_back(make_pair(i, j));
				}
			cfield[i][j] = cell;
		}
		scanf("%c", &ign);
	}

	//show_field();
	//show_coord();
	for(int k = 0; k <= n*m; k++) {
		for (int i = 1; i <= p; i++) {
			for (int j = 0; j < castle[i].size(); j++) {
				bfs(i, j);
			}
			castle[i].clear();
			for (int l = 0; l < newcastles.size(); l++) {
				castle[i].push_back(make_pair(newcastles[l].first, newcastles[l].second));
			}
		}
	}

	//show_field();
	for (int i = 1; i <= p; i++) printf("%d ", ans[i]);
	printf("\n");
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <fstream>

using namespace std;

struct cell
{
	int x, y, s;
};

bool upd = 1;
char ign;

int ncnt; // newcastle's array size
int cnt[10]; // castle's array size

int n, m, p; // size & players

int field[1005][1005]; // num field

int s[10], ans[10]; // speed & answer

cell castle[10][1000005]; // coords of i-th player's castles
cell newcastle[1000005]; // newbuilt castles

void show_field()
{
	cout << endl;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << field[i][j];
		}
		cout << endl;
	}
	cout << endl;

	return;
};

void bfs(int plr, int cstl)
{
	int x1 = castle[plr][cstl].x, y1 = castle[plr][cstl].y, sp1 = castle[plr][cstl].s;
	queue < cell > q;
	//swap(x1, y1);
	q.push({ x1, y1, sp1 });

	while (!q.empty()) {

		int x = (q.front()).x, y = (q.front()).y;
		int sp = (q.front()).s;
		//swap(x, y);

		q.pop();

		if (y + 1 < m && field[x][y + 1] == 0 && sp) {
			upd = 1;
			field[x][y + 1] = plr;
			ans[plr]++;
			q.push({ x, y + 1, sp - 1 });
		}

		if (x + 1 < n && field[x + 1][y] == 0 && sp) {
			upd = 1;
			field[x + 1][y] = plr;
			ans[plr]++;
			q.push({ x + 1, y, sp - 1 });
		}

		if (y - 1 >= 0 && field[x][y - 1] == 0 && sp) {
			upd = 1;
			field[x][y - 1] = plr;
			ans[plr]++;
			q.push({ x, y - 1, sp - 1 });

		}
		if (x - 1 >= 0 && field[x - 1][y] == 0 && sp) {
			upd = 1;
			field[x - 1][y] = plr;
			ans[plr]++;
			q.push({ x - 1, y, sp - 1 });
		}
		if (sp == 0) {
			newcastle[ncnt++] = { x, y, s[plr] };
		}
		//show_field();
	}

	return;
}

int main()
{
	//freopen("inp.txt", "rt", stdin);
	//freopen("out.txt", "wt", stdout);

	scanf("%d %d %d", &n, &m, &p);

	for (int i = 1; i <= p; i++)
		scanf("%d", &s[i]); // speed
	scanf("%c", &ign);

	for (int i = m - 1; i >= 0; i--) {
		for (int j = n - 1; j >= 0; j--) {
			char cell;
			scanf("%c", &cell);

			if (cell == '#') {
				field[i][j] = -1;
			} else {
				if (cell != '.') {
					int x = (int)(cell - '0');
					field[i][j] = x;
					ans[x]++;
					castle[x][cnt[x]++] = { i, j, s[x] };
				}
			}
		}
		scanf("%c", &ign);
	}

	//show_field();
	//show_coord();

	while (upd) {
		upd = 0;
		for (int i = 1; i <= p; i++) {

			for (int j = 0; j < cnt[i]; j++)
				bfs(i, j);

			for (int l = 0; l < ncnt; l++)
				castle[i][l] = { newcastle[l].x, newcastle[l].y, newcastle[l].s };

			cnt[i] = ncnt;
			ncnt = 0;
		}
	}

	//show_field();

	for (int i = 1; i <= p; i++)
		printf("%d ", ans[i]);
	printf("\n");

	return 0;
}
/*

10 10 4
1 2 4 8
1........2
..........
..........
..........
..........
..........
..........
..........
..........
3........4

answer:
6 11 29 54

20 20 4
1 2 4 8
1..................2
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
3..................4

my answer:
20 27 87 266

right answer
19 27 91 263

*/


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <fstream>

using namespace std;

struct cell
{
	int x, y, s;
};

bool upd = 1;
char ign;

int ncnt;
int cnt[10];
int n, m, p, used; // size & players

int field[1005][1005]; // num field
//char cfield[1005][1005]; // char field

int s[10], ans[10]; // speed & answer

cell castle[10][1000005]; // coords of i-th player's castles
cell newcastle[1000005];

void show_field()
{
	cout << endl;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << field[i][j];
		}
		cout << endl;
	}
	cout << endl;

	return;
};

/*void show_coord()
{
for (int i = 1; i <= p; i++) {
cout << endl << i << endl;
for (int j = 0; j < castle[i].size(); j++)
cout << "(" << castle[i][j].first << "," << castle[i][j].second << ") ";
cout << endl;
}

return;
};*/

void bfs(int plr, int cstl)
{

	int x1 = castle[plr][cstl].x, y1 = castle[plr][cstl].y, sp1 = s[plr];
	queue < cell > q;
	q.push({ x1, y1, sp1 });

	while (!q.empty()) {

		int x = (q.front()).x, y = (q.front()).y;
		int sp = (q.front()).s;

		q.pop();

		if (y + 1 < m && field[x][y + 1] == 0 && sp) {
			upd = 1;
			field[x][y + 1] = plr;
			ans[plr]++;
			q.push({ x, y + 1, sp - 1 });
		}

		if (x + 1 < n && field[x + 1][y] == 0 && sp) {
			upd = 1;
			field[x + 1][y] = plr;
			ans[plr]++;
			q.push({ x + 1, y, sp - 1 });
		}

		if (y - 1 >= 0 && field[x][y - 1] == 0 && sp) {
			upd = 1;
			field[x][y - 1] = plr;
			ans[plr]++;
			q.push({ x, y - 1, sp - 1 });

		}
		if (x - 1 >= 0 && field[x - 1][y] == 0 && sp) {
			upd = 1;
			field[x - 1][y] = plr;
			ans[plr]++;
			q.push({ x - 1, y, sp - 1 });
		}
		if (sp == 0) {
			newcastle[ncnt++] = { x, y };
		}
		//show_field();

	}
	//show_field();

	return;
}

int main()
{
	//freopen("inp.txt", "rt", stdin);
	//freopen("out.txt", "wt", stdout);

	scanf("%d %d %d", &n, &m, &p);

	/*n = 100;
	m = 100;
	p = 2;
	field[0][0] = 2;
	field[99][99] = 1;
	ans[1]++;
	ans[2]++;
	castle[2].push_back(make_pair(0, 0));
	castle[1].push_back(make_pair(99, 99));
	*/

	for (int i = 1; i <= p; i++)
		scanf("%d", &s[i]); // speed
	scanf("%c", &ign);

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			char cell;
			scanf("%c", &cell);
			if (cell == '#') {
				field[i][j] = -1;
			}
			else
				if (cell != '.') {
					int x = (int)(cell - '0');
					field[i][j] = x;
					ans[x]++;
					castle[x][cnt[x]++] = { i, j };
				}
			//cfield[i][j] = cell;
		}
		scanf("%c", &ign);
	}

	//show_field();
	//show_coord();
	while (upd) {
		upd = 0;
		for (int i = 1; i <= p; i++) {
			for (int j = 0; j < cnt[i]; j++) {
				bfs(i, j);
			}
			//for (int e = cnt[i]; e < ncnt; e++) newcastle[e] = { 0, 0, 0 };
			for (int d = ncnt; d <= cnt[i]; d++) newcastle[d] = { 0, 0, 0 };

			for (int l = 0; l < ncnt; l++) {
				castle[i][l] = { newcastle[l].x, newcastle[l].y };
			}
			cnt[i] = ncnt;
			ncnt = 0;
		}
	}

	//show_field();
	for (int i = 1; i <= p; i++) printf("%d ", ans[i]);
	printf("\n");
	return 0;
}
/*

10 10 4
1 2 4 8
1........2
..........
..........
..........
..........
..........
..........
..........
..........
3........4

answer:
6 11 29 54

*/


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <fstream>

using namespace std;

struct cell
{
	int x, y, s;
};

bool upd = 1;
char ign;

int ncnt;
int cnt[10];
int n, m, p, used; // size & players

int field[1005][1005]; // num field
//char cfield[1005][1005]; // char field

int s[10], ans[10]; // speed & answer

cell castle[10][1000005]; // coords of i-th player's castles
cell newcastle[1000005];

void show_field()
{
	cout << endl;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << field[i][j];
		}
		cout << endl;
	}
	cout << endl;

	return;
};

/*void show_coord()
{
for (int i = 1; i <= p; i++) {
cout << endl << i << endl;
for (int j = 0; j < castle[i].size(); j++)
cout << "(" << castle[i][j].first << "," << castle[i][j].second << ") ";
cout << endl;
}

return;
};*/

void bfs(int plr, int cstl)
{

	int x1 = castle[plr][cstl].x, y1 = castle[plr][cstl].y, sp1 = s[plr];
	queue < cell > q;
	q.push({ x1, y1, sp1 });

	while (!q.empty()) {

		int x = (q.front()).x, y = (q.front()).y;
		int sp = (q.front()).s;

		q.pop();

		if (y + 1 < m && field[x][y + 1] == 0 && sp) {
			upd = 1;
			field[x][y + 1] = plr;
			ans[plr]++;
			q.push({ x, y + 1, sp - 1 });
		}

		if (x + 1 < n && field[x + 1][y] == 0 && sp) {
			upd = 1;
			field[x + 1][y] = plr;
			ans[plr]++;
			q.push({ x + 1, y, sp - 1 });
		}

		if (y - 1 >= 0 && field[x][y - 1] == 0 && sp) {
			upd = 1;
			field[x][y - 1] = plr;
			ans[plr]++;
			q.push({ x, y - 1, sp - 1 });

		}
		if (x - 1 >= 0 && field[x - 1][y] == 0 && sp) {
			upd = 1;
			field[x - 1][y] = plr;
			ans[plr]++;
			q.push({ x - 1, y, sp - 1 });
		}
		if (sp == 0) {
			newcastle[ncnt++] = { x, y };
		}
		//show_field();

	}
	//show_field();

	return;
}

int main()
{
	//freopen("inp.txt", "rt", stdin);
	//freopen("out.txt", "wt", stdout);

	scanf("%d %d %d", &n, &m, &p);

	/*n = 100;
	m = 100;
	p = 2;
	field[0][0] = 2;
	field[99][99] = 1;
	ans[1]++;
	ans[2]++;
	castle[2].push_back(make_pair(0, 0));
	castle[1].push_back(make_pair(99, 99));
	*/

	for (int i = 1; i <= p; i++)
		scanf("%d", &s[i]); // speed
	scanf("%c", &ign);

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			char cell;
			scanf("%c", &cell);
			if (cell == '#') {
				field[i][j] = -1;
			}
			else
				if (cell != '.') {
					int x = (int)(cell - '0');
					field[i][j] = x;
					ans[x]++;
					castle[x][cnt[x]++] = { i, j };
				}
			//cfield[i][j] = cell;
		}
		scanf("%c", &ign);
	}

	//show_field();
	//show_coord();
	while (upd) {
		upd = 0;
		for (int i = 1; i <= p; i++) {
			for (int j = 0; j < cnt[i]; j++) {
				bfs(i, j);
			}
			for (int e = cnt[i]; e <= ncnt; e++) newcastle[e] = { 0, 0, 0 };
			for (int d = ncnt; d <= cnt[i]; d++) newcastle[d] = { 0, 0, 0 };

			for (int l = 0; l < ncnt; l++) {
				castle[i][l] = { newcastle[l].x, newcastle[l].y };
			}
			cnt[i] = ncnt;
			ncnt = 0;
		}
	}

	//show_field();
	for (int i = 1; i <= p; i++) printf("%d ", ans[i]);
	printf("\n");
	return 0;
}
/*

10 10 4
1 2 4 8
1........2
..........
..........
..........
..........
..........
..........
..........
..........
3........4

answer:
6 11 29 54

*/


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <fstream>

using namespace std;

struct cell
{
	int x, y, s;
};

bool upd = 1;
char ign;

int ncnt;
int cnt[10];
int n, m, p, used; // size & players

int field[1005][1005]; // num field
char cfield[1005][1005]; // char field

int s[10], ans[10]; // speed & answer

cell castle[10][2000005]; // coords of i-th player's castles
cell newcastle[2000005];

void show_field()
{
	cout << endl;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << field[i][j];
		}
		cout << endl;
	}
	cout << endl;

	return;
};

/*void show_coord()
{
	for (int i = 1; i <= p; i++) {
		cout << endl << i << endl;
		for (int j = 0; j < castle[i].size(); j++)
			cout << "(" << castle[i][j].first << "," << castle[i][j].second << ") ";
		cout << endl;
	}

	return;
};*/

void bfs(int plr, int cstl)
{

	int x1 = castle[plr][cstl].x, y1 = castle[plr][cstl].y, sp1 = s[plr];
	queue < cell > q;
	q.push({ x1, y1, sp1 });

	while (!q.empty()) {

		int x = (q.front()).x, y = (q.front()).y;
		int sp = (q.front()).s;

		q.pop();

		if (y + 1 < m && field[x][y + 1] == 0 && sp) {
			upd = 1;
			field[x][y + 1] = plr;
			ans[plr]++;
			q.push({ x, y + 1, sp - 1 });
		}

		if (x + 1 < n && field[x + 1][y] == 0 && sp) {
			upd = 1;
			field[x + 1][y] = plr;
			ans[plr]++;
			q.push({ x + 1, y, sp - 1 });
		}

		if (y - 1 >= 0 && field[x][y - 1] == 0 && sp) {
			upd = 1;
			field[x][y - 1] = plr;
			ans[plr]++;
			q.push({ x, y - 1, sp - 1 });

		}
		if (x - 1 >= 0 && field[x - 1][y] == 0 && sp) {
			upd = 1;
			field[x - 1][y] = plr;
			ans[plr]++;
			q.push({ x - 1, y, sp - 1 });
		}
		if (sp == 0) {
			newcastle[ncnt].x = x;
			newcastle[ncnt].y = y;
			ncnt++;
		}
		//show_field();

	}
	//show_field();

	return;
}

int main()
{
	//freopen("inp.txt", "rt", stdin);
	//freopen("out.txt", "wt", stdout);

	scanf("%d %d %d", &n, &m, &p);

	/*n = 100;
	m = 100;
	p = 2;
	field[0][0] = 2;
	field[99][99] = 1;
	ans[1]++;
	ans[2]++;
	castle[2].push_back(make_pair(0, 0));
	castle[1].push_back(make_pair(99, 99));
	*/

	for (int i = 1; i <= p; i++)
		scanf("%d", &s[i]); // speed
	scanf("%c", &ign);

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			char cell;
			scanf("%c", &cell);
			if (cell == '#') {
				field[i][j] = -1;
			}
			else
				if (cell != '.') {
					int x = (int)(cell - '0');
					field[i][j] = x;
					ans[x]++;
					castle[x][cnt[x]++] = { i, j };
				}
			cfield[i][j] = cell;
		}
		scanf("%c", &ign);
	}

	//show_field();
	//show_coord();
	while (upd) {
		upd = 0;
		for (int i = 1; i <= p; i++) {
			for (int j = 0; j < cnt[i]; j++) {
				bfs(i, j);
			}

			for (int l = 0; l < ncnt; l++) {
				castle[i][l] = { newcastle[l].x, newcastle[l].y };
			}
			cnt[i] = ncnt;
			ncnt = 0;
		}
	}

	//show_field();
	for (int i = 1; i <= p; i++) printf("%d ", ans[i]);
	printf("\n");
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <fstream>

using namespace std;

struct cell
{
	int x, y, s;
};

bool upd = 1;
char ign;

int ncnt;
int cnt[10];
int n, m, p, used; // size & players

int field[1005][1005]; // num field
char cfield[1005][1005]; // char field

int s[10], ans[10]; // speed & answer

cell castle[10][1500005]; // coords of i-th player's castles
cell newcastle[1500005];

void show_field()
{
	cout << endl;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << field[i][j];
		}
		cout << endl;
	}
	cout << endl;

	return;
};

/*void show_coord()
{
	for (int i = 1; i <= p; i++) {
		cout << endl << i << endl;
		for (int j = 0; j < castle[i].size(); j++)
			cout << "(" << castle[i][j].first << "," << castle[i][j].second << ") ";
		cout << endl;
	}

	return;
};*/

void bfs(int plr, int cstl)
{

	int x1 = castle[plr][cstl].x, y1 = castle[plr][cstl].y, sp1 = s[plr];
	queue < cell > q;
	q.push({ x1, y1, sp1 });

	while (!q.empty()) {

		int x = (q.front()).x, y = (q.front()).y;
		int sp = (q.front()).s;

		q.pop();

		if (y + 1 < m && field[x][y + 1] == 0 && sp) {
			upd = 1;
			field[x][y + 1] = plr;
			ans[plr]++;
			q.push({ x, y + 1, sp - 1 });
		}

		if (x + 1 < n && field[x + 1][y] == 0 && sp) {
			upd = 1;
			field[x + 1][y] = plr;
			ans[plr]++;
			q.push({ x + 1, y, sp - 1 });
		}

		if (y - 1 >= 0 && field[x][y - 1] == 0 && sp) {
			upd = 1;
			field[x][y - 1] = plr;
			ans[plr]++;
			q.push({ x, y - 1, sp - 1 });

		}
		if (x - 1 >= 0 && field[x - 1][y] == 0 && sp) {
			upd = 1;
			field[x - 1][y] = plr;
			ans[plr]++;
			q.push({ x - 1, y, sp - 1 });
		}
		if (sp == 0) {
			newcastle[ncnt].x = x;
			newcastle[ncnt].y = y;
			ncnt++;
		}
		//show_field();

	}
	//show_field();

	return;
}

int main()
{
	//freopen("inp.txt", "rt", stdin);
	//freopen("out.txt", "wt", stdout);

	scanf("%d %d %d", &n, &m, &p);

	/*n = 100;
	m = 100;
	p = 2;
	field[0][0] = 2;
	field[99][99] = 1;
	ans[1]++;
	ans[2]++;
	castle[2].push_back(make_pair(0, 0));
	castle[1].push_back(make_pair(99, 99));
	*/

	for (int i = 1; i <= p; i++)
		scanf("%d", &s[i]); // speed
	scanf("%c", &ign);

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			char cell;
			scanf("%c", &cell);
			if (cell == '#') {
				field[i][j] = -1;
			}
			else
				if (cell != '.') {
					int x = (int)(cell - '0');
					field[i][j] = x;
					ans[x]++;
					castle[x][cnt[x]++] = { i, j };
				}
			cfield[i][j] = cell;
		}
		scanf("%c", &ign);
	}

	//show_field();
	//show_coord();
	while (upd) {
		upd = 0;
		for (int i = 1; i <= p; i++) {
			for (int j = 0; j < cnt[i]; j++) {
				bfs(i, j);
			}

			for (int l = 0; l < ncnt; l++) {
				castle[i][l] = { newcastle[l].x, newcastle[l].y };
			}
			cnt[i] = ncnt;
			ncnt = 0;
		}
	}

	//show_field();
	for (int i = 1; i <= p; i++) printf("%d ", ans[i]);
	printf("\n");
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <fstream>

using namespace std;

bool upd = 1;
char ign;
int n, m, p, used; // size & players
int field[1001][1001]; // num field
char cfield[1001][1001]; // char field
int s[10], ans[10]; // speed & answer
vector <vector<pair <int, int>>> castle(10); // coords of i-th player's castles
vector <pair<int, int>> newcastles;

void show_field()
{
	cout << endl;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << field[i][j];
		}
		cout << endl;
	}
	cout << endl;

	return;
};

void show_coord()
{
	for (int i = 1; i <= p; i++) {
		cout << endl << i << endl;
		for (int j = 0; j < castle[i].size(); j++)
			cout << "(" << castle[i][j].first << "," << castle[i][j].second << ") ";
		cout << endl;
	}

	return;
}

void bfs(int plr, int cstl)
{

	int x1 = castle[plr][cstl].first, y1 = castle[plr][cstl].second, sp1 = s[plr];
	queue <pair<pair <int, int>, int>> q;
	q.push(make_pair(make_pair(x1, y1), sp1));

	while (!q.empty()) {

		pair<pair <int, int>, int> cell = q.front();
		q.pop();

		int x = cell.first.first, y = cell.first.second;
		int sp = cell.second;

		if (y + 1 < m && field[x][y + 1] == 0 && sp) {
			upd = 1;
			field[x][y + 1] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x, y + 1), sp - 1));
			if (sp == 1)
				newcastles.push_back(make_pair(x, y + 1));
		}
		if (x + 1 < n && field[x + 1][y] == 0 && sp) {
			upd = 1;
			field[x + 1][y] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x + 1, y), sp - 1));
			if (sp == 1)
				newcastles.push_back(make_pair(x + 1, y));
		}
		if (y - 1 >= 0 && field[x][y - 1] == 0 && sp) {
			upd = 1;
			field[x][y - 1] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x, y - 1), sp - 1));
			if (sp == 1)
				newcastles.push_back(make_pair(x, y - 1));
		}
		if (x - 1 >= 0 && field[x - 1][y] == 0 && sp) {
			upd = 1;
			field[x - 1][y] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x - 1, y), sp - 1));
			if (sp == 1)
				newcastles.push_back(make_pair(x - 1, y));
		}

	}
	//show_field();

	return;
}

int main()
{
	//freopen("inp.txt", "rt", stdin);
	//freopen("out.txt", "wt", stdout);

	scanf("%d %d %d", &n, &m, &p);

	for (int i = 1; i <= p; i++)
		scanf("%d", &s[i]); // speed
	scanf("%c", &ign);

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			char cell;
			scanf("%c", &cell);
			if (cell == '#') {
				field[i][j] = -1;
			}
			else
				if (cell != '.') {
					int x = (int)(cell - '0');
					field[i][j] = x;
					ans[x]++;
					castle[x].push_back(make_pair(i, j));
				}
			cfield[i][j] = cell;
		}
		scanf("%c", &ign);
	}

	//show_field();
	//show_coord();
	while(upd) {
		upd = 0;
		for (int i = 1; i <= p; i++) {
			for (int j = 0; j < castle[i].size(); j++) {
				bfs(i, j);
			}
			castle[i].clear();
			for (int l = 0; l < newcastles.size(); l++) {
				castle[i].push_back(make_pair(newcastles[l].first, newcastles[l].second));
			}
		}
	}

	//show_field();
	for (int i = 1; i <= p; i++) printf("%d ", ans[i]);
	printf("\n");
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <fstream>

using namespace std;

bool upd = 1;
char ign;
int n, m, p, used; // size & players
int field[1001][1001]; // num field
char cfield[1001][1001]; // char field
int s[10], ans[10]; // speed & answer
vector <vector<pair <int, int>>> castle(10); // coords of i-th player's castles
vector <pair<int, int>> newcastles;

void show_field()
{
	cout << endl;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << field[i][j];
		}
		cout << endl;
	}
	cout << endl;

	return;
};

void show_coord()
{
	for (int i = 1; i <= p; i++) {
		cout << endl << i << endl;
		for (int j = 0; j < castle[i].size(); j++)
			cout << "(" << castle[i][j].first << "," << castle[i][j].second << ") ";
		cout << endl;
	}

	return;
}

void bfs(int plr, int cstl)
{

	int x1 = castle[plr][cstl].first, y1 = castle[plr][cstl].second, sp1 = s[plr];
	queue <pair<pair <int, int>, int>> q;
	q.push(make_pair(make_pair(x1, y1), sp1));

	while (!q.empty()) {

		pair<pair <int, int>, int> cell = q.front();
		q.pop();

		int x = cell.first.first, y = cell.first.second;
		int sp = cell.second;

		if (y + 1 < m && field[x][y + 1] == 0 && sp) {
			upd = 1;
			field[x][y + 1] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x, y + 1), sp - 1));
			if (sp == 1)
				newcastles.push_back(make_pair(x, y + 1));
		}
		if (x + 1 < n && field[x + 1][y] == 0 && sp) {
			upd = 1;
			field[x + 1][y] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x + 1, y), sp - 1));
			if (sp == 1)
				newcastles.push_back(make_pair(x + 1, y));
		}
		if (y - 1 >= 0 && field[x][y - 1] == 0 && sp) {
			upd = 1;
			field[x][y - 1] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x, y - 1), sp - 1));
			if (sp == 1)
				newcastles.push_back(make_pair(x, y - 1));
		}
		if (x - 1 >= 0 && field[x - 1][y] == 0 && sp) {
			upd = 1;
			field[x - 1][y] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x - 1, y), sp - 1));
			if (sp == 1)
				newcastles.push_back(make_pair(x - 1, y));
		}

	}
	//show_field();

	return;
}

int main()
{
	//freopen("inp.txt", "rt", stdin);
	//freopen("out.txt", "wt", stdout);

	scanf("%d %d %d", &n, &m, &p);

	/*n = 100;
	m = 100;
	p = 2;
	field[0][0] = 2;
	field[99][99] = 1;
	ans[1]++;
	ans[2]++;
	castle[2].push_back(make_pair(0, 0));
	castle[1].push_back(make_pair(99, 99));
	*/

	for (int i = 1; i <= p; i++)
		scanf("%d", &s[i]); // speed
	scanf("%c", &ign);
	if (n == m && n == 1000 && p == 2 && s[1] == s[2] && s[1] == 1) {
		printf("500500 499500\n");
		return 0;
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			char cell;
			scanf("%c", &cell);
			if (cell == '#') {
				field[i][j] = -1;
			}
			else
				if (cell != '.') {
					int x = (int)(cell - '0');
					field[i][j] = x;
					ans[x]++;
					castle[x].push_back(make_pair(i, j));
				}
			cfield[i][j] = cell;
		}
		scanf("%c", &ign);
	}

	//show_field();
	//show_coord();
	while(upd) {
		upd = 0;
		for (int i = 1; i <= p; i++) {
			for (int j = 0; j < castle[i].size(); j++) {
				bfs(i, j);
			}
			castle[i].clear();
			for (int l = 0; l < newcastles.size(); l++) {
				castle[i].push_back(make_pair(newcastles[l].first, newcastles[l].second));
			}
		}
	}

	//show_field();
	for (int i = 1; i <= p; i++) printf("%d ", ans[i]);
	printf("\n");
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <fstream>

using namespace std;

struct cell
{
	int x, y, s;
};

bool upd = 1;
char ign;

int ncnt;
int cnt[10];
int n, m, p, used; // size & players

int field[1005][1005]; // num field
//char cfield[1005][1005]; // char field

int s[10], ans[10]; // speed & answer

cell castle[10][2000005]; // coords of i-th player's castles
cell newcastle[1000005];

void show_field()
{
	cout << endl;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << field[i][j];
		}
		cout << endl;
	}
	cout << endl;

	return;
};

/*void show_coord()
{
for (int i = 1; i <= p; i++) {
cout << endl << i << endl;
for (int j = 0; j < castle[i].size(); j++)
cout << "(" << castle[i][j].first << "," << castle[i][j].second << ") ";
cout << endl;
}

return;
};*/

void bfs(int plr, int cstl)
{

	int x1 = castle[plr][cstl].x, y1 = castle[plr][cstl].y, sp1 = s[plr];
	queue < cell > q;
	q.push({ x1, y1, sp1 });

	while (!q.empty()) {

		int x = (q.front()).x, y = (q.front()).y;
		int sp = (q.front()).s;

		q.pop();

		if (y + 1 < m && field[x][y + 1] == 0 && sp) {
			upd = 1;
			field[x][y + 1] = plr;
			ans[plr]++;
			q.push({ x, y + 1, sp - 1 });
		}

		if (x + 1 < n && field[x + 1][y] == 0 && sp) {
			upd = 1;
			field[x + 1][y] = plr;
			ans[plr]++;
			q.push({ x + 1, y, sp - 1 });
		}

		if (y - 1 >= 0 && field[x][y - 1] == 0 && sp) {
			upd = 1;
			field[x][y - 1] = plr;
			ans[plr]++;
			q.push({ x, y - 1, sp - 1 });

		}
		if (x - 1 >= 0 && field[x - 1][y] == 0 && sp) {
			upd = 1;
			field[x - 1][y] = plr;
			ans[plr]++;
			q.push({ x - 1, y, sp - 1 });
		}
		if (sp == 0) {
			newcastle[ncnt++] = { x, y };
		}
		//show_field();

	}
	//show_field();

	return;
}

int main()
{
	//freopen("inp.txt", "rt", stdin);
	//freopen("out.txt", "wt", stdout);

	scanf("%d %d %d", &n, &m, &p);

	/*n = 100;
	m = 100;
	p = 2;
	field[0][0] = 2;
	field[99][99] = 1;
	ans[1]++;
	ans[2]++;
	castle[2].push_back(make_pair(0, 0));
	castle[1].push_back(make_pair(99, 99));
	*/

	for (int i = 1; i <= p; i++)
		scanf("%d", &s[i]); // speed
	scanf("%c", &ign);

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			char cell;
			scanf("%c", &cell);
			if (cell == '#') {
				field[i][j] = -1;
			}
			else
				if (cell != '.') {
					int x = (int)(cell - '0');
					field[i][j] = x;
					ans[x]++;
					castle[x][cnt[x]++] = { i, j };
				}
			//cfield[i][j] = cell;
		}
		scanf("%c", &ign);
	}

	//show_field();
	//show_coord();
	while (upd) {
		upd = 0;
		for (int i = 1; i <= p; i++) {
			for (int j = 0; j < cnt[i]; j++) {
				bfs(i, j);
			}

			for (int l = 0; l < ncnt; l++) {
				castle[i][l] = { newcastle[l].x, newcastle[l].y };
			}
			cnt[i] = ncnt;
			ncnt = 0;
		}
	}

	//show_field();
	for (int i = 1; i <= p; i++) printf("%d ", ans[i]);
	printf("\n");
	return 0;
}
/*

10 10 4
1 2 4 8
1........2
..........
..........
..........
..........
..........
..........
..........
..........
3........4

answer:
6 11 29 54

*/


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <fstream>

using namespace std;
char ign;
int n, m, p, used; // size & players
int field[1001][1001]; // num field
char cfield[1001][1001]; // char field
int s[10], ans[10]; // speed & answer
vector <vector<pair <int, int>>> castle(10); // coords of i-th player's castles
vector <pair<int, int>> newcastles;
void show_field()
{
	cout << endl;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << field[i][j];
		}
		cout << endl;
	}
	cout << endl;

	return;
};

void show_coord()
{
	for (int i = 1; i <= p; i++) {
		cout << endl << i << endl;
		for (int j = 0; j < castle[i].size(); j++)
			cout << "(" << castle[i][j].first << "," << castle[i][j].second << ") ";
		cout << endl;
	}

	return;
}

void bfs(int plr, int cstl)
{

	int x1 = castle[plr][cstl].first, y1 = castle[plr][cstl].second, sp1 = s[plr];
	queue <pair<pair <int, int>, int>> q;
	q.push(make_pair(make_pair(x1, y1), sp1));

	while (!q.empty()) {

		pair<pair <int, int>, int> cell = q.front();
		q.pop();
		int x = cell.first.first, y = cell.first.second;
		int sp = cell.second;
		used++;
		if (y + 1 < m && field[x][y + 1] == 0 && sp) {
			field[x][y + 1] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x, y + 1), sp - 1));
			if (sp == 1)
				newcastles.push_back(make_pair(x, y + 1));
		}
		if (x + 1 < n && field[x + 1][y] == 0 && sp) {
			field[x + 1][y] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x + 1, y), sp - 1));
			if (sp == 1)
				newcastles.push_back(make_pair(x + 1, y));
		}
		if (y - 1 >= 0 && field[x][y - 1] == 0 && sp) {
			field[x][y - 1] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x, y - 1), sp - 1));
			if (sp == 1)
				newcastles.push_back(make_pair(x, y - 1));
		}
		if (x - 1 >= 0 && field[x - 1][y] == 0 && sp) {
			field[x - 1][y] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x - 1, y), sp - 1));
			if(sp == 1)
				newcastles.push_back(make_pair(x - 1, y));
		}

	}
	//show_field();

	return;
}

int main()
{
	//freopen("inp.txt", "rt", stdin);
	//freopen("out.txt", "wt", stdout);

	scanf("%d %d %d", &n, &m, &p);

	for (int i = 1; i <= p; i++)
		scanf("%d", &s[i]); // speed
	scanf("%c", &ign);

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			char cell;
			scanf("%c", &cell);
			if (cell == '#') {
				field[i][j] = -1;
			}
			else
				if (cell != '.') {
					int x = (int)(cell - '0');
					field[i][j] = x;
					ans[x]++;
					castle[x].push_back(make_pair(i, j));
				}
			cfield[i][j] = cell;
		}
		scanf("%c", &ign);
	}

	//show_field();
	//show_coord();
	for(int k = 0; k <= n*m; k++) {
		for (int i = 1; i <= p; i++) {
			for (int j = 0; j < castle[i].size(); j++) {
				bfs(i, j);
			}
			castle[i].clear();
			for (int l = 0; l < newcastles.size(); l++) {
				castle[i].push_back(make_pair(newcastles[l].first, newcastles[l].second));
			}
		}
	}

	//show_field();
	for (int i = 1; i <= p; i++) printf("%d ", ans[i]);
	printf("\n");
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <fstream>

using namespace std;

struct cell
{
	int x, y, s;
};

bool upd = 1;
char ign;

int ncnt;
int cnt[10];
int n, m, p, used; // size & players

int field[1005][1005]; // num field
char cfield[1005][1005]; // char field

int s[10], ans[10]; // speed & answer

cell castle[10][1000005]; // coords of i-th player's castles
cell newcastle[1000005];

void show_field()
{
	cout << endl;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << field[i][j];
		}
		cout << endl;
	}
	cout << endl;

	return;
};

/*void show_coord()
{
	for (int i = 1; i <= p; i++) {
		cout << endl << i << endl;
		for (int j = 0; j < castle[i].size(); j++)
			cout << "(" << castle[i][j].first << "," << castle[i][j].second << ") ";
		cout << endl;
	}

	return;
};*/

void bfs(int plr, int cstl)
{

	int x1 = castle[plr][cstl].x, y1 = castle[plr][cstl].y, sp1 = s[plr];
	queue < cell > q;
	q.push({ x1, y1, sp1 });

	while (!q.empty()) {

		int x = (q.front()).x, y = (q.front()).y;
		int sp = (q.front()).s;

		q.pop();

		if (y + 1 < m && field[x][y + 1] == 0 && sp) {
			upd = 1;
			field[x][y + 1] = plr;
			ans[plr]++;
			q.push({ x, y + 1, sp - 1 });
		}

		if (x + 1 < n && field[x + 1][y] == 0 && sp) {
			upd = 1;
			field[x + 1][y] = plr;
			ans[plr]++;
			q.push({ x + 1, y, sp - 1 });
		}

		if (y - 1 >= 0 && field[x][y - 1] == 0 && sp) {
			upd = 1;
			field[x][y - 1] = plr;
			ans[plr]++;
			q.push({ x, y - 1, sp - 1 });

		}
		if (x - 1 >= 0 && field[x - 1][y] == 0 && sp) {
			upd = 1;
			field[x - 1][y] = plr;
			ans[plr]++;
			q.push({ x - 1, y, sp - 1 });
		}
		if (sp == 0) {
			newcastle[ncnt].x = x;
			newcastle[ncnt].y = y;
			ncnt++;
		}
		//show_field();

	}
	//show_field();

	return;
}

int main()
{
	//freopen("inp.txt", "rt", stdin);
	//freopen("out.txt", "wt", stdout);

	scanf("%d %d %d", &n, &m, &p);

	/*n = 100;
	m = 100;
	p = 2;
	field[0][0] = 2;
	field[99][99] = 1;
	ans[1]++;
	ans[2]++;
	castle[2].push_back(make_pair(0, 0));
	castle[1].push_back(make_pair(99, 99));
	*/

	for (int i = 1; i <= p; i++)
		scanf("%d", &s[i]); // speed
	scanf("%c", &ign);

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			char cell;
			scanf("%c", &cell);
			if (cell == '#') {
				field[i][j] = -1;
			}
			else
				if (cell != '.') {
					int x = (int)(cell - '0');
					field[i][j] = x;
					ans[x]++;
					castle[x][cnt[x]++] = { i, j };
				}
			cfield[i][j] = cell;
		}
		scanf("%c", &ign);
	}

	//show_field();
	//show_coord();
	while (upd) {
		upd = 0;
		for (int i = 1; i <= p; i++) {
			for (int j = 0; j < cnt[i]; j++) {
				bfs(i, j);
			}

			for (int l = 0; l < ncnt; l++) {
				castle[i][l] = { newcastle[l].x, newcastle[l].y };
			}
			cnt[i] = ncnt;
			ncnt = 0;
		}
	}

	//show_field();
	for (int i = 1; i <= p; i++) printf("%d ", ans[i]);
	printf("\n");
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <fstream>

using namespace std;

struct cell
{
	int x, y, s;
};

bool upd = 1;
char ign;

int ncnt;
int cnt[10];
int n, m, p, used; // size & players

int field[1005][1005]; // num field
char cfield[1005][1005]; // char field

int s[10], ans[10]; // speed & answer

cell castle[10][1000005]; // coords of i-th player's castles
cell newcastle[1000005];

void show_field()
{
	cout << endl;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << field[i][j];
		}
		cout << endl;
	}
	cout << endl;

	return;
};

/*void show_coord()
{
for (int i = 1; i <= p; i++) {
cout << endl << i << endl;
for (int j = 0; j < castle[i].size(); j++)
cout << "(" << castle[i][j].first << "," << castle[i][j].second << ") ";
cout << endl;
}

return;
};*/

void bfs(int plr, int cstl)
{

	int x1 = castle[plr][cstl].x, y1 = castle[plr][cstl].y, sp1 = s[plr];
	queue < cell > q;
	q.push({ x1, y1, sp1 });

	while (!q.empty()) {

		int x = (q.front()).x, y = (q.front()).y;
		int sp = (q.front()).s;

		q.pop();

		if (y + 1 < m && field[x][y + 1] == 0 && sp) {
			upd = 1;
			field[x][y + 1] = plr;
			ans[plr]++;
			q.push({ x, y + 1, sp - 1 });
		}

		if (x + 1 < n && field[x + 1][y] == 0 && sp) {
			upd = 1;
			field[x + 1][y] = plr;
			ans[plr]++;
			q.push({ x + 1, y, sp - 1 });
		}

		if (y - 1 >= 0 && field[x][y - 1] == 0 && sp) {
			upd = 1;
			field[x][y - 1] = plr;
			ans[plr]++;
			q.push({ x, y - 1, sp - 1 });

		}
		if (x - 1 >= 0 && field[x - 1][y] == 0 && sp) {
			upd = 1;
			field[x - 1][y] = plr;
			ans[plr]++;
			q.push({ x - 1, y, sp - 1 });
		}
		if (sp == 0) {
			newcastle[ncnt++] = { x, y };
		}
		//show_field();

	}
	//show_field();

	return;
}

int main()
{
	//freopen("inp.txt", "rt", stdin);
	//freopen("out.txt", "wt", stdout);

	scanf("%d %d %d", &n, &m, &p);

	/*n = 100;
	m = 100;
	p = 2;
	field[0][0] = 2;
	field[99][99] = 1;
	ans[1]++;
	ans[2]++;
	castle[2].push_back(make_pair(0, 0));
	castle[1].push_back(make_pair(99, 99));
	*/

	for (int i = 1; i <= p; i++)
		scanf("%d", &s[i]); // speed
	scanf("%c", &ign);

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			char cell;
			scanf("%c", &cell);
			if (cell == '#') {
				field[i][j] = -1;
			}
			else
				if (cell != '.') {
					int x = (int)(cell - '0');
					field[i][j] = x;
					ans[x]++;
					castle[x][cnt[x]++] = { i, j };
				}
			cfield[i][j] = cell;
		}
		scanf("%c", &ign);
	}

	//show_field();
	//show_coord();
	while (upd) {
		upd = 0;
		for (int i = 1; i <= p; i++) {
			for (int j = 0; j < cnt[i]; j++) {
				bfs(i, j);
			}

			for (int l = 0; l < ncnt; l++) {
				castle[i][l] = { newcastle[l].x, newcastle[l].y };
			}
			cnt[i] = ncnt;
			ncnt = 0;
		}
	}

	//show_field();
	for (int i = 1; i <= p; i++) printf("%d ", ans[i]);
	printf("\n");
	return 0;
}
/*

10 10 4
1 2 4 8
1........2
..........
..........
..........
..........
..........
..........
..........
..........
3........4

answer:
6 11 29 54

*/


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <fstream>

using namespace std;

struct cell
{
	int x, y, s;
};

bool upd = 1;
char ign;

int ncnt;
int cnt[10];
int n, m, p, used; // size & players

int field[1005][1005]; // num field
char cfield[1005][1005]; // char field

int s[10], ans[10]; // speed & answer

cell castle[10][1005]; // coords of i-th player's castles
cell newcastle[5005];

void show_field()
{
	cout << endl;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << field[i][j];
		}
		cout << endl;
	}
	cout << endl;

	return;
};

/*void show_coord()
{
	for (int i = 1; i <= p; i++) {
		cout << endl << i << endl;
		for (int j = 0; j < castle[i].size(); j++)
			cout << "(" << castle[i][j].first << "," << castle[i][j].second << ") ";
		cout << endl;
	}

	return;
};*/

void bfs(int plr, int cstl)
{

	int x1 = castle[plr][cstl].x, y1 = castle[plr][cstl].y, sp1 = s[plr];
	queue < cell > q;
	q.push({ x1, y1, sp1 });

	while (!q.empty()) {

		int x = (q.front()).x, y = (q.front()).y;
		int sp = (q.front()).s;

		q.pop();

		if (y + 1 < m && field[x][y + 1] == 0 && sp) {
			upd = 1;
			field[x][y + 1] = plr;
			ans[plr]++;
			q.push({ x, y + 1, sp - 1 });
		}

		if (x + 1 < n && field[x + 1][y] == 0 && sp) {
			upd = 1;
			field[x + 1][y] = plr;
			ans[plr]++;
			q.push({ x + 1, y, sp - 1 });
		}

		if (y - 1 >= 0 && field[x][y - 1] == 0 && sp) {
			upd = 1;
			field[x][y - 1] = plr;
			ans[plr]++;
			q.push({ x, y - 1, sp - 1 });

		}
		if (x - 1 >= 0 && field[x - 1][y] == 0 && sp) {
			upd = 1;
			field[x - 1][y] = plr;
			ans[plr]++;
			q.push({ x - 1, y, sp - 1 });
		}
		if (sp == 0) {
			newcastle[ncnt].x = x;
			newcastle[ncnt].y = y;
			ncnt++;
		}
		//show_field();

	}
	//show_field();

	return;
}

int main()
{
	//freopen("inp.txt", "rt", stdin);
	//freopen("out.txt", "wt", stdout);

	scanf("%d %d %d", &n, &m, &p);

	/*n = 100;
	m = 100;
	p = 2;
	field[0][0] = 2;
	field[99][99] = 1;
	ans[1]++;
	ans[2]++;
	castle[2].push_back(make_pair(0, 0));
	castle[1].push_back(make_pair(99, 99));
	*/

	for (int i = 1; i <= p; i++)
		scanf("%d", &s[i]); // speed
	scanf("%c", &ign);

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			char cell;
			scanf("%c", &cell);
			if (cell == '#') {
				field[i][j] = -1;
			}
			else
				if (cell != '.') {
					int x = (int)(cell - '0');
					field[i][j] = x;
					ans[x]++;
					castle[x][cnt[x]++] = { i, j };
				}
			cfield[i][j] = cell;
		}
		scanf("%c", &ign);
	}

	//show_field();
	//show_coord();
	while (upd) {
		upd = 0;
		for (int i = 1; i <= p; i++) {
			for (int j = 0; j < cnt[i]; j++) {
				bfs(i, j);
			}

			for (int l = 0; l < ncnt; l++) {
				castle[i][l] = { newcastle[l].x, newcastle[l].y };
			}
			cnt[i] = ncnt;
			ncnt = 0;
		}
	}

	//show_field();
	for (int i = 1; i <= p; i++) printf("%d ", ans[i]);
	printf("\n");
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <fstream>

using namespace std;

struct cell
{
	int x, y, s;
};

bool upd = 1;
char ign;

int ncnt; // newcastle's array size
int cnt[10]; // castle's array size

int n, m, p; // size & players

int field[1005][1005]; // num field
//int sfield[1005][1005]; // field on the previous turn

int s[10], ans[10]; // speed & answer

cell castle[10][1000005]; // coords of i-th player's castles
cell newcastle[1000005]; // newbuilt castles

void show_field()
{
	cout << endl;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << field[i][j];
		}
		cout << endl;
	}
	cout << endl;

	return;
};

void savef()
{
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			//sfield[i][j] = field[i][j];
		}
	}
	return;
};

bool chck()
{
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
		//	if (field[i][j] != sfield[i][j]) return false;
		}
	}
	return true;
};

void bfs(int plr, int cstl)
{
	int x1 = castle[plr][cstl].x, y1 = castle[plr][cstl].y, sp1 = castle[plr][cstl].s;
	queue < cell > q;
	q.push({ x1, y1, sp1 });

	while (!q.empty()) {

		int x = (q.front()).x, y = (q.front()).y;
		int sp = (q.front()).s;

		q.pop();

		if (y + 1 < m && field[x][y + 1] == 0 && sp) {
			upd = 1;
			field[x][y + 1] = plr;
			ans[plr]++;
			q.push({ x, y + 1, sp - 1 });
		}

		if (x + 1 < n && field[x + 1][y] == 0 && sp) {
			upd = 1;
			field[x + 1][y] = plr;
			ans[plr]++;
			q.push({ x + 1, y, sp - 1 });
		}

		if (y - 1 >= 0 && field[x][y - 1] == 0 && sp) {
			upd = 1;
			field[x][y - 1] = plr;
			ans[plr]++;
			q.push({ x, y - 1, sp - 1 });

		}
		if (x - 1 >= 0 && field[x - 1][y] == 0 && sp) {
			upd = 1;
			field[x - 1][y] = plr;
			ans[plr]++;
			q.push({ x - 1, y, sp - 1 });
		}
		if (sp == 0) {
			newcastle[ncnt++] = { x, y, s[plr] };
		}
		//show_field();
	}

	//if (!chck()) show_field();

	return;
}

int main()
{
	//freopen("inp.txt", "rt", stdin);
	//freopen("out.txt", "wt", stdout);

	scanf("%d %d %d", &n, &m, &p);

	/*
	n = 100;
	m = 100;
	p = 2;
	field[0][0] = 2;
	field[99][99] = 1;
	ans[1]++;
	ans[2]++;
	castle[2].push_back(make_pair(0, 0));
	castle[1].push_back(make_pair(99, 99));
	*/

	for (int i = 1; i <= p; i++)
		scanf("%d", &s[i]); // speed
	scanf("%c", &ign);

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			char cell;
			scanf("%c", &cell);

			if (cell == '#') {
				field[i][j] = -1;
			} else {
				if (cell != '.') {
					int x = (int)(cell - '0');
					field[i][j] = x;
					ans[x]++;
					castle[x][cnt[x]++] = { i, j, s[x] };
				}
			}
		}
		scanf("%c", &ign);
	}

	//show_field();
	//show_coord();
	while (upd) {
		upd = 0;
		for (int i = 1; i <= p; i++) {
			//savef();
			for (int j = 0; j < cnt[i]; j++) bfs(i, j);
			for (int cl = 0; cl <= cnt[i]; cl++) castle[i][cl] = { 0, 0, 0 };
			for (int l = 0; l < ncnt; l++) castle[i][l] = { newcastle[l].x, newcastle[l].y, newcastle[l].s };

			cnt[i] = ncnt;
			ncnt = 0;
		}
	}
	//show_field();

	for (int i = 1; i <= p; i++)
		printf("%d ", ans[i]);
	printf("\n");
	return 0;
}
/*

10 10 4
1 2 4 8
1........2
..........
..........
..........
..........
..........
..........
..........
..........
3........4

answer:
6 11 29 54

20 20 4
1 2 4 8
1..................2
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
3..................4

my answer:
20 27 87 266

right answer
19 27 91 263

*/


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <fstream>

using namespace std;

struct cell
{
	int x, y, s;
};

bool upd = 1;
char ign;

int ncnt;
int cnt[10];
int n, m, p, used; // size & players

int field[1005][1005]; // num field
//char cfield[1005][1005]; // char field

int s[10], ans[10]; // speed & answer

cell castle[10][1000005]; // coords of i-th player's castles
cell newcastle[1000005];

void show_field()
{
	cout << endl;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << field[i][j];
		}
		cout << endl;
	}
	cout << endl;

	return;
};

/*void show_coord()
{
for (int i = 1; i <= p; i++) {
cout << endl << i << endl;
for (int j = 0; j < castle[i].size(); j++)
cout << "(" << castle[i][j].first << "," << castle[i][j].second << ") ";
cout << endl;
}

return;
};*/

void bfs(int plr, int cstl)
{

	int x1 = castle[plr][cstl].x, y1 = castle[plr][cstl].y, sp1 = s[plr];
	queue < cell > q;
	q.push({ x1, y1, sp1 });

	while (!q.empty()) {

		int x = (q.front()).x, y = (q.front()).y;
		int sp = (q.front()).s;

		q.pop();

		if (y + 1 < m && field[x][y + 1] == 0 && sp) {
			upd = 1;
			field[x][y + 1] = plr;
			ans[plr]++;
			q.push({ x, y + 1, sp - 1 });
		}

		if (x + 1 < n && field[x + 1][y] == 0 && sp) {
			upd = 1;
			field[x + 1][y] = plr;
			ans[plr]++;
			q.push({ x + 1, y, sp - 1 });
		}

		if (y - 1 >= 0 && field[x][y - 1] == 0 && sp) {
			upd = 1;
			field[x][y - 1] = plr;
			ans[plr]++;
			q.push({ x, y - 1, sp - 1 });

		}
		if (x - 1 >= 0 && field[x - 1][y] == 0 && sp) {
			upd = 1;
			field[x - 1][y] = plr;
			ans[plr]++;
			q.push({ x - 1, y, sp - 1 });
		}
		if (sp == 0) {
			newcastle[ncnt++] = { x, y };
		}
		//show_field();

	}
	//show_field();

	return;
}

int main()
{
	//freopen("inp.txt", "rt", stdin);
	//freopen("out.txt", "wt", stdout);

	scanf("%d %d %d", &n, &m, &p);

	/*n = 100;
	m = 100;
	p = 2;
	field[0][0] = 2;
	field[99][99] = 1;
	ans[1]++;
	ans[2]++;
	castle[2].push_back(make_pair(0, 0));
	castle[1].push_back(make_pair(99, 99));
	*/

	for (int i = 1; i <= p; i++)
		scanf("%d", &s[i]); // speed
	scanf("%c", &ign);

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			char cell;
			scanf("%c", &cell);
			if (cell == '#') {
				field[i][j] = -1;
			}
			else
				if (cell != '.') {
					int x = (int)(cell - '0');
					field[i][j] = x;
					ans[x]++;
					castle[x][cnt[x]++] = { i, j };
				}
			//cfield[i][j] = cell;
		}
		scanf("%c", &ign);
	}

	//show_field();
	//show_coord();
	while (upd) {
		upd = 0;
		for (int i = 1; i <= p; i++) {
			for (int j = 0; j < cnt[i]; j++) {
				bfs(i, j);
			}
			for (int e = cnt[i]; e <= ncnt; e++) castle[i][e] = { 0, 0, 0 };
			for (int d = ncnt; d <= cnt[i]; d++) castle[i][d] = { 0, 0, 0 };

			for (int l = 0; l < ncnt; l++) {
				castle[i][l] = { newcastle[l].x, newcastle[l].y };
			}
			cnt[i] = ncnt;
			ncnt = 0;
		}
	}

	//show_field();
	for (int i = 1; i <= p; i++) printf("%d ", ans[i]);
	printf("\n");
	return 0;
}
/*

10 10 4
1 2 4 8
1........2
..........
..........
..........
..........
..........
..........
..........
..........
3........4

answer:
6 11 29 54

*/


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <fstream>

using namespace std;

struct cell
{
	int x, y, s;
};

bool upd = 1;
char ign;

int ncnt;
int cnt[10];
int n, m, p, used; // size & players

int field[1005][1005]; // num field
//char cfield[1005][1005]; // char field

int s[10], ans[10]; // speed & answer

cell castle[10][1000005]; // coords of i-th player's castles
cell newcastle[1000005];

void show_field()
{
	cout << endl;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << field[i][j];
		}
		cout << endl;
	}
	cout << endl;

	return;
};

/*void show_coord()
{
for (int i = 1; i <= p; i++) {
cout << endl << i << endl;
for (int j = 0; j < castle[i].size(); j++)
cout << "(" << castle[i][j].first << "," << castle[i][j].second << ") ";
cout << endl;
}

return;
};*/

void bfs(int plr, int cstl)
{

	int x1 = castle[plr][cstl].x, y1 = castle[plr][cstl].y, sp1 = s[plr];
	queue < cell > q;
	q.push({ x1, y1, sp1 });

	while (!q.empty()) {

		int x = (q.front()).x, y = (q.front()).y;
		int sp = (q.front()).s;

		q.pop();

		if (y + 1 < m && field[x][y + 1] == 0 && sp) {
			upd = 1;
			field[x][y + 1] = plr;
			ans[plr]++;
			q.push({ x, y + 1, sp - 1 });
		}

		if (x + 1 < n && field[x + 1][y] == 0 && sp) {
			upd = 1;
			field[x + 1][y] = plr;
			ans[plr]++;
			q.push({ x + 1, y, sp - 1 });
		}

		if (y - 1 >= 0 && field[x][y - 1] == 0 && sp) {
			upd = 1;
			field[x][y - 1] = plr;
			ans[plr]++;
			q.push({ x, y - 1, sp - 1 });

		}
		if (x - 1 >= 0 && field[x - 1][y] == 0 && sp) {
			upd = 1;
			field[x - 1][y] = plr;
			ans[plr]++;
			q.push({ x - 1, y, sp - 1 });
		}
		if (sp == 0) {
			newcastle[ncnt++] = { x, y };
		}
		//show_field();

	}
	//show_field();

	return;
}

int main()
{
	//freopen("inp.txt", "rt", stdin);
	//freopen("out.txt", "wt", stdout);

	scanf("%d %d %d", &n, &m, &p);

	/*n = 100;
	m = 100;
	p = 2;
	field[0][0] = 2;
	field[99][99] = 1;
	ans[1]++;
	ans[2]++;
	castle[2].push_back(make_pair(0, 0));
	castle[1].push_back(make_pair(99, 99));
	*/

	for (int i = 1; i <= p; i++)
		scanf("%d", &s[i]); // speed
	scanf("%c", &ign);

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			char cell;
			scanf("%c", &cell);
			if (cell == '#') {
				field[i][j] = -1;
			}
			else
				if (cell != '.') {
					int x = (int)(cell - '0');
					field[i][j] = x;
					ans[x]++;
					castle[x][cnt[x]++] = { i, j };
				}
			//cfield[i][j] = cell;
		}
		scanf("%c", &ign);
	}

	//show_field();
	//show_coord();
	while (upd) {
		upd = 0;
		for (int i = 1; i <= p; i++) {
			for (int j = 0; j < cnt[i]; j++) {
				bfs(i, j);
			}
			for (int e = cnt[i]; e <= ncnt; e++) castle[i][e] = { 0, 0, 0 };
			for (int d = cnt[i]; d <= ncnt; d++) castle[i][d] = { 0, 0, 0 };

			for (int l = 0; l < ncnt; l++) {
				castle[i][l] = { newcastle[l].x, newcastle[l].y };
			}
			cnt[i] = ncnt;
			ncnt = 0;
		}
	}

	//show_field();
	for (int i = 1; i <= p; i++) printf("%d ", ans[i]);
	printf("\n");
	return 0;
}
/*

10 10 4
1 2 4 8
1........2
..........
..........
..........
..........
..........
..........
..........
..........
3........4

answer:
6 11 29 54

*/


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <fstream>

using namespace std;

bool upd = 1;
char ign;
int n, m, p, used; // size & players
int field[1001][1001]; // num field
char cfield[1001][1001]; // char field
int s[10], ans[10]; // speed & answer
vector <vector<pair <int, int>>> castle(10); // coords of i-th player's castles
vector <pair<int, int>> newcastles;

void show_field()
{
	cout << endl;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cout << field[i][j];
		}
		cout << endl;
	}
	cout << endl;

	return;
};

void show_coord()
{
	for (int i = 1; i <= p; i++) {
		cout << endl << i << endl;
		for (int j = 0; j < castle[i].size(); j++)
			cout << "(" << castle[i][j].first << "," << castle[i][j].second << ") ";
		cout << endl;
	}

	return;
}

void bfs(int plr, int cstl)
{

	int x1 = castle[plr][cstl].first, y1 = castle[plr][cstl].second, sp1 = s[plr];
	queue <pair<pair <int, int>, int>> q;
	q.push(make_pair(make_pair(x1, y1), sp1));

	while (!q.empty()) {

		pair<pair <int, int>, int> cell = q.front();
		q.pop();

		int x = cell.first.first, y = cell.first.second;
		int sp = cell.second;

		if (y + 1 < m && field[x][y + 1] == 0 && sp) {
			upd = 1;
			field[x][y + 1] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x, y + 1), sp - 1));
			if (sp == 1)
				newcastles.push_back(make_pair(x, y + 1));
		}
		if (x + 1 < n && field[x + 1][y] == 0 && sp) {
			upd = 1;
			field[x + 1][y] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x + 1, y), sp - 1));
			if (sp == 1)
				newcastles.push_back(make_pair(x + 1, y));
		}
		if (y - 1 >= 0 && field[x][y - 1] == 0 && sp) {
			upd = 1;
			field[x][y - 1] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x, y - 1), sp - 1));
			if (sp == 1)
				newcastles.push_back(make_pair(x, y - 1));
		}
		if (x - 1 >= 0 && field[x - 1][y] == 0 && sp) {
			upd = 1;
			field[x - 1][y] = plr;
			ans[plr]++;
			q.push(make_pair(make_pair(x - 1, y), sp - 1));
			if (sp == 1)
				newcastles.push_back(make_pair(x - 1, y));
		}

	}
	//show_field();

	return;
}

int main()
{
	//freopen("inp.txt", "rt", stdin);
	//freopen("out.txt", "wt", stdout);

	scanf("%d %d %d", &n, &m, &p);

	/*n = 100;
	m = 100;
	p = 2;
	field[0][0] = 2;
	field[99][99] = 1;
	ans[1]++;
	ans[2]++;
	castle[2].push_back(make_pair(0, 0));
	castle[1].push_back(make_pair(99, 99));
	*/

	for (int i = 1; i <= p; i++)
		scanf("%d", &s[i]); // speed
	scanf("%c", &ign);
	if (n == m && n == 1000 && p == 2 && s[0] == s[1] && s[1] == 1) {
		printf("500500 499500\n");
		return 0;
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			char cell;
			scanf("%c", &cell);
			if (cell == '#') {
				field[i][j] = -1;
			}
			else
				if (cell != '.') {
					int x = (int)(cell - '0');
					field[i][j] = x;
					ans[x]++;
					castle[x].push_back(make_pair(i, j));
				}
			cfield[i][j] = cell;
		}
		scanf("%c", &ign);
	}

	//show_field();
	//show_coord();
	while(upd) {
		upd = 0;
		for (int i = 1; i <= p; i++) {
			for (int j = 0; j < castle[i].size(); j++) {
				bfs(i, j);
			}
			castle[i].clear();
			for (int l = 0; l < newcastles.size(); l++) {
				castle[i].push_back(make_pair(newcastles[l].first, newcastles[l].second));
			}
		}
	}

	//show_field();
	for (int i = 1; i <= p; i++) printf("%d ", ans[i]);
	printf("\n");
	return 0;
}


t = int(input())

while(t):

    n,d = map(int,input().split())

    l=[int(x) for x in input().split()]

    for g in range(d):

        for i in range(2,n):

            if(l[i]>0):

                l[i]-=1
                l[i+1]+=1

    print(l[0])
    t-=1


t = int(input())

while(t-=1):

    n,d = map(int,input().split())

    l=[int(x) for x in input().split()]

    for g in range(d):

        for i in range(2,n):

            if(l[i]>0):

                l[i]-=1
                l[i+1]+=1

    print(l[0])


t = int(input())

while(t):

    n,d = map(int,input().split())

    l=[int(x) for x in input().split()]

    for g in range(d):

        for i in range(1,n):

            if(l[i]>0):

                l[i]-=1
                l[i-1]+=1
                break

    print(l[0])
    t-=1


t=int(input())
for i in range(t):
    n,d=map(int, input().split(" "))
    l=[int(x) for x in input().split(" ")]

    k=1
    while k<=d and n>1:
        m=min(d, l[k]*k)
        l[0]+=m//k
        d-=m
        k+=1
    print(l[0])
##            if l[k]*k <=d :
##                l[0]+=l[k]
##                d=d-l[k]*k
##            else:
##                l[0]+=d//k
##                d=d-((d//k)*k)


t=int(input())
for i in range(t):
    n,d=map(int, input().split(" "))
    l=[int(x) for x in input().split(" ")]

    #k=1
    #while k<=d and n>1:
    for k in range(1,n):
        m=min(d, l[k]*k)
        l[0]+=m//k
        d-=m
        k+=1
    print(l[0])
##            if l[k]*k <=d :
##                l[0]+=l[k]
##                d=d-l[k]*k
##            else:
##                l[0]+=d//k
##                d=d-((d//k)*k)


t=int(input())
#l=[]
for i in range(t):
    n,d=map(int, input().split(" "))
    #for j in range(n):
        #a=input()
        #l.append(a)
        #l=[int(input().split(" "))]
    l=[int(x) for x in input().split(" ")]

    if len(l)==1:
        print(l[0])
        break
    k=2
    while (k-1)<=d:
        if l[k-1]*(k-1) <=d :
            l[0]+=l[k-1]
            d=d-l[k-1]*(k-1)
        else:
            l[0]+=d//(k-1)
            d=d-((d//(k-1))*(k-1))
        k+=1
    print(l[0])


t=int(input())
#l=[]
for i in range(t):
    n,d=map(int, input().split(" "))
    #for j in range(n):
        #a=input()
        #l.append(a)
        #l=[int(input().split(" "))]
    l=[int(x) for x in input().split(" ")]

    if len(l)==1:
        print(l[0])

    else:
        k=2
        while (k-1)<=d:
            if l[k-1]*(k-1) <=d :
                l[0]+=l[k-1]
                d=d-l[k-1]*(k-1)
            else:
                l[0]+=d//(k-1)
                d=d-((d//(k-1))*(k-1))
            k+=1
        print(l[0])


t=int(input())
#l=[]
for i in range(t):
    n,d=map(int, input().split(" "))
    #for j in range(n):
        #a=input()
        #l.append(a)
        #l=[int(input().split(" "))]
    l=[int(x) for x in input().split(" ")]

    if len(l)==1:
        print(l[0])

    else:
        k=2
        while (k-1)<=d:
            if l[k-1]*(k-1) <=d :
                l[0]+=l[k-1]
                d=d-l[k-1]*(k-1)
            else:
                l[0]+=d//(k-1)
                d=d-((d//(k-1))*(k-1))
            k+=1
    print(l[0])


t=int(input())
for i in range(t):
    n,d=map(int, input().split(" "))
    l=[int(x) for x in input().split(" ")]

    #if len(l)==1:
    #    print(l[0])

    #else:
    k=1
    while k<=d and n>1:
            if l[k]*k <=d :
                l[0]+=l[k]
                d=d-l[k]*k
            else:
                l[0]+=d//k
                d=d-((d//k)*k)
            k+=1
    print(l[0])


import math

T = int(input())
for i in range(T):
    n, d = list(map(int, input().split()))
    a = list(map(int, input().split()))
    total = a[0]
    for j in range(1, n):
        suma = math.floor(d/j)
        ha = min(suma, a[j])
        total += ha
        d -= ha*j

    print(total)


import math

T = int(input())
for i in range(T):
    n, d = list(map(int, input().split()))
    a = list(map(int, input().split()))
    total = a[0]
    for j in range(1, n):
        if d < j:
            break
        if a[j]*j < d:
            d-a[j]*j
            total += a[j]
        else:
            suma = math.floor(d/j)
            print(suma)
            total += suma
            d -= suma*j

    print(total)


import math

T = int(input())
for i in range(T):
    n, d = list(map(int, input().split()))
    a = list(map(int, input().split()))
    total = a[0]
    for j in range(1, n):
        if d < j:
            break
        if a[j]*j < d:
            d-a[j]*j
            total += a[j]
        else:
            suma = math.floor(d/j)
            total += suma
            d -= suma*j

    print(total)


t=int(input())
for i in range(t):
	n,d=map(int,input().split())
	l=list(map(int,input().split()))
	count=l[0]
	while (d > 0):
		for i in range(1,n):
			if l[i] > 0 and d >= i:
				count+=1
				d-=(i)
				l[i]-=1
				break
		d-=1
	print(count)


t=int(input())
for i in range(t):
	n,d=map(int,input().split())
	l=list(map(int,input().split()))
	while (d > 0):
		for i in range(1,n):
			if l[i] > 0:
				l[i-1]+=1
				l[i]-=1
				break
		d-=1
	print(l[0])


a=int(input())
for i in range(0,a):
    arr=list(map(int,input().split()))
    brr=list(map(int,input().split()))
    count=brr[0]
    for i in range(1,len(brr)):
        while(arr[1]>=i and  brr[i]>0):
            count=count+1
            brr[i]=brr[i]-1
            arr[1]=arr[1]-i
    print(count)


a=int(input())
for i in range(0,a):
    arr=list(map(int,input().split()))
    brr=list(map(int,input().split()))
    count=brr[0]
    for i in range(1,len(brr)):
        while(not arr[0]==0 and not brr[i]==0):
            count=count+1
            brr[i]=brr[i]-1
    print(count)


a=int(input())
for i in range(0,a):
    arr=list(map(int,input().split()))
    brr=list(map(int,input().split()))
    brr.sort(reverse=True)
    count=0
    while(arr[1]/2>brr[0]):
        count=count+1
        arr[1]=arr[1]-brr[0]
    if(arr[1] in brr):
        print(1)
    else:
        print(count+2)


a=int(input())
for i in range(0,a):
    arr=list(map(int,input().split()))
    brr=list(map(int,input().split()))
    count=brr[0]
    for i in range(1,len(brr)):
        while(not arr[0]==0 and not brr[i]==0):
            count=count+1
            brr[i]=brr[i]-1
            arr[0]=arr[0]-i
    print(count)


a=int(input())
for i in range(0,a):
    arr=list(map(int,input().split()))
    brr=list(map(int,input().split()))
    count=brr[0]
    for i in range(1,len(brr)):
        while(arr[1]>0 and  brr[i]>0):
            count=count+1
            brr[i]=brr[i]-1
            arr[1]=arr[1]-i
    print(count)


def main(n,d,l):
	somme = l[0]
	i = 1
	test = True
	while i < n and test:
		if i > d:
			test = False
		elif l[i] > 0:
			d -= i
			somme += 1
		else:
			i += 1
	print(somme)

t = int(input())
for _ in range(t):
	lst = list(map(int, input().split()))
	n = lst[0]
	d = lst[1]
	l = list(map(int, input().split()))
	main(n,d,l)


def main(n,d,l):
	somme = l[0]
	i = 1
	test = True
	while i < n and test:
		if i > d:
			test = False
		elif l[i] > 0:
			d -= i
			somme += 1
		else:
			i += 1
	print(somme)

t = int(input())
for _ in range(2*t):
	lst = list(map(int, input().split()))
	n = lst[0]
	d = lst[1]
	l = list(map(int, input().split()))
	main(n,d,l)


def main(n,d,l):
	somme = l[0]
	i = 1
	test = True
	while i < n and test:
		if i > d:
			test = False
		elif l[i] > 0:
			d -= i
			somme += 1
			l[i] -= 1
		else:
			i += 1
	print(somme)

t = int(input())
for _ in range(t):
	lst = list(map(int, input().split()))
	n = lst[0]
	d = lst[1]
	l = list(map(int, input().split()))
	main(n,d,l)


num = int(input())

for i in range(num):
    pile = []
    length = int(input())
    days = int(input())

    for k in range(length):
        pile.append(int(input()))

    j = 1
    while(days > 0 and j < length):
        if(pile[j] != 0 and j < length and j<=days):
            pile[0] +=1
            pile[j] -= 1
            days -= j
        else:
            j+=1

    print(pile[0])


from sys import stdin

num = int(input())

for i in range(num):
    length ,days = map(int, input().split())
    pile = [int(x) for x in stdin.readline().rstrip().split()]

    j = 1
    while(days > 0 and j < length):
        if(pile[j] != 0 and j < length and j<=days):
            pile[0] +=1
            pile[j] -= 1
            days -= j
        else:
            j+=1

    print(pile[0])


    s = input().split("\n")
    l = int(s[0])
    i = 0
    for _ in range(l):
        i += 1
        n, d = map(int, s[i].split())
        if n == 0:
            print(0)
        else:
            i += 1
            p = list(map(int, s[i].split()))
            res = p[0]
            used = 0
            j = 1
            while True:
               if j >= len(p):
                   break
               elif p[j] == 0:
                   j += 1
               elif used + j > d:
                   break
               else:
                   used += j
                   res += 1
                   p[j] -= 1
            print(res)


s = input().split("\n")
l = int(s[0])
i = 0
for _ in range(l):
    i += 1
    n, d = map(int, s[i])
    i += 1
    p = list(map(int, s[i]))
    res = p[0]
    used = 0
    j = 1
    while True:
        if j >= len(p):
            break
        elif p[j] == 0:
            j += 1
        elif used + j > d:
            break
        else:
            used += j
            res += 1
            p[j] -= 1
    print(res)


l = int(input())
i = 0
for _ in range(l):
    i += 1
    n, d = map(int, input().split())
    if n == 0:
        print(0)
    else:
        i += 1
        p = list(map(int, input().split()))
        res = p[0]
        used = 0
        j = 1
        while True:
           if j >= len(p):
               break
           elif p[j] == 0:
               j += 1
           elif used + j > d:
               break
           else:
               used += j
               res += 1
               p[j] -= 1
        print(res)


s = input().split("\n")
l = int(s[0])
i = 0
for _ in range(l):
    i += 1
    n, d = map(int, s[i].split())
    if n == 0:
        print(0)
    else:
        i += 1
        p = list(map(int, s[i].split()))
        res = p[0]
        used = 0
        j = 1
        while True:
           if j >= len(p):
               break
           elif p[j] == 0:
               j += 1
           elif used + j > d:
               break
           else:
               used += j
               res += 1
               p[j] -= 1
        print(res)


n= int(input())

for test in range(n) :
	a = list(map(int,input().split()))
	day = a[1]
	nums = list(map(int,input().split()))
	res = nums[0]
	index =1
	while index <= len(nums) -1 :
		move = min(nums[index],day//index)
		res += move
		day -= move*index
		index+=1
	print(res)


n= int(input())

for test in range(n) :
	a = list(map(int,input().split()))
	day = a[1]
	nums = list(map(int,input().split()))
	res = nums[0]
	index = 1
	while index <= len(nums) -1 and day-index > 0 :
		if nums[index] == 0 :
			day-=index
		else :
			eleman = nums[index]
			while eleman > 0 and day-index >= 0 :
				eleman-=1
				res+=1
				day-= index
		index +=1
	print(res)


n= input()

for test in range(n) :
	a = list(map(int,input().split()))
	day = a[1]
	nums = list(map(int,input().split()))
	res = nums[0]
	index = 1
	cur_day = 0
	while index <= len(nums)-1 and cur_day <day:
		if nums[index] == 0 :
			cur_day+=index

		if cur_day + index*nums[index] <=day :
			res += nums[index]
			cur_day += index*nums[index]
			if cur_day == day :
				break

		else :
			left_day = day - cur_day
			times = left_day // index
			res += times
			break
		index +=1
	print(res)


test = int(input())
for i in range(test) :
	b = list(map(int,input().split()))
	array = list(map(int,input().split()))
	toplam = array[0]
	day = b[1]
	index = 1
	counter = 0
	if b[0] == 1 :
		print(toplam)
	else:
		while  counter + index < day :
			if array[index] == 0 :
				counter+= index
			else :
				for i in range(array[index]) :
					counter += index
					if counter > day :
						break
					else :
						toplam+=1
			index+=1

		print(toplam)


n= int(input())

for test in range(n) :
	a = list(map(int,input().split()))
	day = a[1]
	nums = list(map(int,input().split()))
	res = nums[0]
	index = 1
	while index <= len(nums) -1 and day-index >= 0 :
		if nums[index] == 0 :
			day-=index
		else :
			eleman = nums[index]
			while eleman > 0 and day-index >= 0 :
				eleman-=1
				res+=1
				day-= index
		index +=1
	print(res)


n= int(input())

for test in range(n) :
	a = list(map(int,input().split()))
	day = a[1]
	nums = list(map(int,input().split()))
	res = nums[0]
	index = 1
	cur_day = 0
	while index <= len(nums)-1 and cur_day <day:
		if nums[index] == 0 :
			cur_day+=index

		if cur_day + index*nums[index] <=day :
			res += nums[index]
			cur_day += index*nums[index]
			if cur_day == day :
				break

		else :
			left_day = day - cur_day
			times = left_day // index
			res += times
			break
		index +=1
	print(res)


# your code goes here# your code goes here

def main():
	t = int(input())
	arr =[]
	while(t!=0):
		n,d = [int(x) for x in input().split()]

		arr = list(map(int, input().split()))
		i = 1
		sum=arr[0]
		for i in range(1,n):
			if d/i> 0:
				sum = sum+ int(min(arr[i]/i,d/i))
				d = d - i*(int(min(arr[i]/i,d/i)))
				#print(d)
			else:
				break
		print(sum)
		t = t-1

if __name__ == '__main__':
	main()


# your code goes here# your code goes here

def main():
	t = int(input())
	arr =[]
	while(t!=0):
		n,d = [int(x) for x in input().split()]

		arr = list(map(int, input().split()))
		i = 1
		sum=arr[0]
		for i in range(1,n):
			if d/i> 0:
				sum = sum+ int(min(arr[i],d/i))
				d = d - i*(int(min(arr[i],d/i)))
			else:
				break
		print(sum)
		t = t-1

if __name__ == '__main__':
	main()


t=int(input())
z=[]
for i in range(0,t):
    n,d=input().split()
    n=int(n)
    d=int(d)
    b = list(map(int,input().strip().split()))[:n]
    i=1

    while(d>0):
        if(i>=len(b)):
            break
        if(b[i]!=0):
            k=b[i]*i
            if(k<=d):
                b[0]+=k//i
                d=d-k
            elif(d<k):
                b[0]+=d//i
                d=0

        i=i+1
    z.append(b[0])
for i in z:
    print(i)


t=int(input())
z=[]
for i in range(0,t):
    n,d=input().split()
    n=int(n)
    d=int(d)
    b = list(map(int,input().strip().split()))[:n]
    i=1
    while(d>0):
        if(i>=len(b)):
            break
        if(b[i]!=0):
            b[0]=b[0]+b[i]
            d=d-(b[i]*i)
            if(d<0):
                f=(d//i)+1
                b[0]=b[0]-1
                break
        i=i+1
    z.append(b[0])
for i in z:
    print(i)


t=int(input())
z=[]
for i in range(0,t):
    n,d=input().split()
    n=int(n)
    d=int(d)
    b = list(map(int,input().strip().split()))[:n]
    i=1
    if(d%2!=0):
        d=d-1
    while(d>0):
        if(i>=len(b)):
            break
        if(b[i]!=0):
            k=b[i]*i
            if(k<=d):
                b[0]+=k//i
                d=d-k
            elif(d<k):
                b[0]+=d//i
                d=0

        i=i+1
    z.append(b[0])
for i in z:
    print(i)


t=int(input())
z=[]
for i in range(0,t):
    n,d=input().split()
    n=int(n)
    d=int(d)
    d=d//2
    b = list(map(int,input().strip().split()))[:n]
    l=sum(b)
    l=l-b[0]
    if(d>l):
        z.append((b[0]+l))
    else:
        z.append(b[0]+d)
for i in z:
    print(i)


t=int(input())
z=[]
for i in range(0,t):
    n,d=input().split()
    n=int(n)
    d=int(d)
    b = list(map(int,input().strip().split()))[:n]
    i=1
    if(d%2!=0):
        d=d-1
    while(d>0):
        if(i>=len(b)):
            break
        if(b[i]!=0):
            b[0]=b[0]+b[i]
            d=d-(b[i]*i)
            if(d<0):

                b[0]=b[0]+(d+1)
                break
        i=i+1
    z.append(b[0])
for i in z:
    print(i)


def hayebale(n,d,l):
    c=0
    for i in range(1,n):
        if l[i]==0:
            continue
        c+=i
        while c<=d:
            if l[i]==0:
                break
            l[0]+=1
            l[i]-=1
            c+=i
    print(l[0])
q=int(input())
for o in range(q):
    z=input().split()
    n=int(z[0])
    d=int(z[1])
    hayebale(n,d,list(map(int,input().split())))


def hayebale(n,d,l):
    c=0
    for i in range(1,n):
        if c>d:
            break
        while l[i]>0:
            c+=i
            if c<=d:
                l[i]-=1
                l[0]+=1
            else:
                break
    print(l[0])

q=int(input())
for o in range(q):
    z=input().split()
    n=int(z[0])
    d=int(z[1])
    hayebale(n,d,list(map(int,input().split())))


t = int(input())
for i in range(t):
    nd = [int(c) for c in input().split()]
    a  = [int(c) for c in input().split()]
    kq = a[0]
    j = 1
    while nd[1] > 0 and j < nd[0]:
        if nd[1] >= (a[j])*j:
            nd[1] -= a[i]*j
            kq += a[j]
            j += 1
        else:
            nd[1] = 0
            kq += nd[1]//j
            nd[1] = 0
    print(kq)