#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<cmath>
#include<stack>
#include<cstdlib>
#include <vector>
#include<queue>
#define REP(i,a,n) for(int i=a;i<=n;++i)
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 1e3+5;

int n,m,t;
struct node{
    int x,y,t;
};
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
int s[20];
queue<node>q1[20];
queue<node>q2[20];
char map[maxn][maxn];
int vis[maxn][maxn];

int expand(int p)
{
    int newx = 0;
    while(!q2[p].empty())
    {
        node x = q2[p].front();
        q2[p].pop();
        x.t = s[p];
        q1[p].push(x);
    }
    while(!q1[p].empty()) {
        node x = q1[p].front();
        q1[p].pop();
        if (!x.t) {
            q2[p].push(x);
            continue;
        }

        for (int i = 0; i < 4; i++)
        {
            int xx = x.x + dx[i];
            int yy = x.y + dy[i];
            if(xx<1||yy<1||xx>n||yy>m||map[xx][yy]=='#'||vis[xx][yy])continue;
            newx++;
            q1[p].push(node{xx,yy,x.t-1});  //步数+1
            vis[xx][yy] = p;   //记录棋盘
        }
    }
	return newx;
}
int main()
{
    scanf("%d %d %d",&n,&m,&t);
    for(int i=1;i<=t;i++)
        scanf("%d",&s[i]);
    for(int i=1;i<=n;i++)
    {
        for (int j = 1; j <= m; j++)
        {
            cin >> map[i][j];
            if (map[i][j] >= '1' && map[i][j] <= '9')
            {
                vis[i][j] = map[i][j] - '0';
                q2[vis[i][j]].push(node{i,j,s[vis[i][j]]});
            }
        }
    }

    while(true)
    {
        int flag = 0;
        for(int i=1;i<=t;i++)
            flag += expand(i);
        if(flag == 0)
            break;
    }
    int count[20];
    memset(count,0,sizeof count);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            count[vis[i][j]]++;
    for(int i=1;i<=t;i++)
        printf("%d ",count[i]);
	puts("");
}
/*
Input
3 2
1
1..
...
..2
Output
3
Input
4 4
1 1 1
....
#...
Output
4 3 3
 */


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <math.h>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <string.h>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define hr putchar(10)
#define pb push_back
#define lc (o<<1)
#define rc (lc|1)
#define mid ((l+r)>>1)
#define ls lc,l,mid
#define rs rc,mid+1,r
#define x first
#define y second
#define io std::ios::sync_with_stdio(false)
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int P = 1e9+7, INF = 0x3f3f3f3f;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll qpow(ll a,ll n) {ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;}
ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
//head

const int N= 1e3+10;
int n, m, p;
struct _ {
	int x,y,v;
};
const int dx[]={1,-1,0,0};
const int dy[]={0,0,-1,1};
queue<_> q[N];
int a[N], vis[N][N], ans[N];
char s[N][N];

int expand(int id) {
	queue<_> Q;
	while (!q[id].empty()) {
		_ t = q[id].front();q[id].pop();
		t.v = a[id];
		Q.push(t);
	}
	int ok = 0;
	while (!Q.empty()) {
		_ t = Q.front();Q.pop();
		if (!t.v) {
			q[id].push(t);
			continue;
		}
		REP(i,0,3) {
			int x=t.x+dx[i],y=t.y+dy[i],v=t.v-1;
			if (x<=0||y<=0||x>n||y>m||vis[x][y]||s[x][y]=='#') continue;
			ok = 1;
			vis[x][y] = id;
			Q.push({x,y,v});
		}
	}
	return ok;
}

int main() {
	scanf("%d%d%d", &n, &m, &p);
	REP(i,1,p) scanf("%d", a+i);
	REP(i,1,n) scanf("%s", s[i]+1);
	REP(i,1,n) REP(j,1,m) {
		if (isdigit(s[i][j])) {
			int ii = s[i][j]-'0';
			vis[i][j]=ii;
			q[ii].push({i,j,a[i]});
		}
	}
	while (1) {
		int ok = 0;
		REP(i,1,p) ok |= expand(i);
		if (!ok) break;
	}
	REP(i,1,n) REP(j,1,m) ++ans[vis[i][j]];
	REP(i,1,p) printf("%d ",ans[i]);hr;
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<cmath>
#include<stack>
#include<cstdlib>
#include <vector>
#include<queue>
#define REP(i,a,n) for(int i=a;i<=n;++i)
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 1e3+5;

int n,m;
struct node{
    int x,y,t;
};
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
int s[20];
queue<node>q1[20];
queue<node>q2[20];
char map[maxn][maxn];
int vis[maxn][maxn];

int expand(int p)
{
    int newx = 0;
    while(!q2[p].empty())
    {
        node x = q2[p].front();
        q2[p].pop();
        x.t = s[p];
        q1[p].push(x);
    }
    while(!q1[p].empty()) {
        node x = q1[p].front();
        q1[p].pop();
        if (!x.t) {
            q2[p].push(x);
            continue;
        }
		REP(i,0,3) {
            int xx = x.x + dx[i];
            int yy = x.y + dy[i];
            if(xx<1||yy<1||xx>n||yy>m||map[xx][yy]=='#'||vis[xx][yy])continue;
            newx++;
            q1[p].push(node{xx,yy,x.t-1});  //步数+1
            vis[xx][yy] = p;   //记录棋盘
        }
    }
	return newx;
}
int main() {
	int p;
	scanf("%d%d%d", &n, &m, &p);
	REP(i,1,p) scanf("%d", s+i);
	REP(i,1,n) scanf("%s",map[i]+1);
    for(int i=1;i<=n;i++)
    {
        for (int j = 1; j <= m; j++)
        {
			if (isdigit(map[i][j])) {
                vis[i][j] = map[i][j] - '0';
                q2[vis[i][j]].push(node{i,j,s[vis[i][j]]});
            }
        }
    }

    while(true)
    {
        int flag = 0;
		REP(i,1,p) flag += expand(i);
		if (!flag) break;
    }
    int count[20];
    memset(count,0,sizeof count);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            count[vis[i][j]]++;
    for(int i=1;i<=p;i++)
        printf("%d ",count[i]);
	puts("");
}
/*
Input
3 2
1
1..
...
..2
Output
3
Input
4 4
1 1 1
....
#...
Output
4 3 3
 */


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <math.h>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <string.h>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define hr putchar(10)
#define pb push_back
#define lc (o<<1)
#define rc (lc|1)
#define mid ((l+r)>>1)
#define ls lc,l,mid
#define rs rc,mid+1,r
#define x first
#define y second
#define io std::ios::sync_with_stdio(false)
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int P = 1e9+7, INF = 0x3f3f3f3f;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll qpow(ll a,ll n) {ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;}
ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
//head

const int N= 1e3+10;
int n, m, p;
struct _ {
	int x,y,v;
};
const int dx[]={1,-1,0,0};
const int dy[]={0,0,1,-1};
queue<_> q[20], Q;
int a[20], vis[N][N], ans[20];
char s[N][N];

int expand(int id) {
	while (!q[id].empty()) {
		_ t = q[id].front();q[id].pop();
		t.v = a[id];
		Q.push(t);
	}
	int ok = 0;
	while (!Q.empty()) {
		_ t = Q.front();Q.pop();
		if (!t.v) {
			q[id].push(t);
			continue;
		}
		REP(i,0,3) {
			int x=t.x+dx[i],y=t.y+dy[i],v=t.v-1;
			if (x<=0||y<=0||x>n||y>m||vis[x][y]||s[x][y]=='#') continue;
			ok = 1;
			vis[x][y] = id;
			Q.push({x,y,v});
		}
	}
	return ok;
}

int main() {
	scanf("%d%d%d", &n, &m, &p);
	REP(i,1,p) scanf("%d", a+i);
	REP(i,1,n) scanf("%s", s[i]+1);
	REP(i,1,n) REP(j,1,m) {
		if (isdigit(s[i][j])) {
			int ii = s[i][j]-'0';
			vis[i][j]=ii;
			q[ii].push({i,j,a[i]});
		}
	}
	while (1) {
		int ok = 0;
		REP(i,1,p) ok |= expand(i);
		if (!ok) break;
	}
	REP(i,1,n) REP(j,1,m) ++ans[vis[i][j]];
	REP(i,1,p) printf("%d ",ans[i]);hr;
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<cmath>
#include<stack>
#include<cstdlib>
#include <vector>
#include<queue>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 1e3+5;

int n,m,t;
struct node{
    int x,y,t;
};
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
int s[20];
queue<node>q1[20];
queue<node>q2[20];
char map[maxn][maxn];
int vis[maxn][maxn];

int expand(int p)
{
    int newx = 0;
    while(!q2[p].empty())
    {
        node x = q2[p].front();
        q2[p].pop();
        x.t = 0;        //此句话要与后面有句话连起来看，就是每次放进 q2[i] 队列的都要将步数为0
        q1[p].push(x);
    }
    while(!q1[p].empty())
    {
        node x = q1[p].front();
        q1[p].pop();
        if (x.t == s[p])
        {
            q2[p].push(x);      //如果已经满 s[p] 步，就将它重新放进 q1 的队列，并将步数归0
            continue;
        }

        for (int i = 0; i < 4; i++)
        {
            int xx = x.x + dx[i];
            int yy = x.y + dy[i];
            if(xx<1 || yy<1 || xx>n || yy>m || map[xx][yy]=='#' || vis[xx][yy] != 0 || x.t+1>s[p])
                continue;
            newx++;
            q1[p].push(node{xx,yy,x.t+1});  //步数+1
            vis[xx][yy] = p;   //记录棋盘
        }
    }
    if(newx >= 1)
        return 1;
    else
        return 0;
}
int main()
{
    scanf("%d %d %d",&n,&m,&t);
    for(int i=1;i<=t;i++)
        scanf("%d",&s[i]);
    for(int i=1;i<=n;i++)
    {
        for (int j = 1; j <= m; j++)
        {
            cin >> map[i][j];
            if (map[i][j] >= '1' && map[i][j] <= '9')
            {
                vis[i][j] = map[i][j] - '0';
                q2[vis[i][j]].push(node{i,j,0});
            }
        }
    }

    while(true)
    {
        int flag = 0;
        for(int i=1;i<=t;i++)
            flag += expand(i);
        if(flag == 0)
            break;
    }
    int count[20];
    memset(count,0,sizeof count);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            count[vis[i][j]]++;
    for(int i=1;i<=t;i++)
        printf("%d ",count[i]);
}
/*
Input
3 2
1
1..
...
..2
Output
3
Input
4 4
1 1 1
....
#...
Output
4 3 3
 */


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <math.h>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <string.h>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define hr putchar(10)
#define pb push_back
#define lc (o<<1)
#define rc (lc|1)
#define mid ((l+r)>>1)
#define ls lc,l,mid
#define rs rc,mid+1,r
#define x first
#define y second
#define io std::ios::sync_with_stdio(false)
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int P = 1e9+7, INF = 0x3f3f3f3f;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll qpow(ll a,ll n) {ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;}
ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
//head

const int N= 1e3+10;
int n, m, p;
struct _ {
	int x,y,v;
};
const int dx[]={1,-1,0,0};
const int dy[]={0,0,1,-1};
queue<_> q[20];
int a[20], vis[N][N], ans[20];
char s[N][N];

int expand(int id) {
	queue<_> Q;
	while (!Q.empty()) Q.pop();
	while (!q[id].empty()) {
		_ t = q[id].front();q[id].pop();
		t.v = a[id];
		Q.push(t);
	}
	int ok = 0;
	while (!Q.empty()) {
		_ t = Q.front();Q.pop();
		if (!t.v) {
			q[id].push(t);
			continue;
		}
		REP(i,0,3) {
			int x=t.x+dx[i],y=t.y+dy[i],v=t.v-1;
			if (x<=0||y<=0||x>n||y>m||vis[x][y]||s[x][y]=='#') continue;
			ok = 1;
			vis[x][y] = id;
			Q.push({x,y,v});
		}
	}
	return ok;
}

int main() {
	scanf("%d%d%d", &n, &m, &p);
	REP(i,1,p) scanf("%d", a+i);
	REP(i,1,n) scanf("%s", s[i]+1);
	REP(i,1,n) REP(j,1,m) {
		if (isdigit(s[i][j])) {
			int ii = s[i][j]-'0';
			vis[i][j]=ii;
			q[ii].push({i,j,a[i]});
		}
	}
	while (1) {
		int ok = 0;
		REP(i,1,p) ok |= expand(i);
		if (!ok) break;
	}
	REP(i,1,n) REP(j,1,m) ++ans[vis[i][j]];
	REP(i,1,p) printf("%d ",ans[i]);hr;
}


#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<cmath>
#include<stack>
#include<cstdlib>
#include <vector>
#include<queue>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 1e3+5;

int n,m,t;
struct node{
    int x,y,t;
};
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
int s[20];
queue<node>q1[20];
queue<node>q2[20];
char map[maxn][maxn];
int vis[maxn][maxn];

int expand(int p)
{
    int newx = 0;
    while(!q2[p].empty())
    {
        node x = q2[p].front();
        q2[p].pop();
        x.t = 0;        //此句话要与后面有句话连起来看，就是每次放进 q2[i] 队列的都要将步数为0
        q1[p].push(x);
    }
    while(!q1[p].empty())
    {
        node x = q1[p].front();
        q1[p].pop();
        if (x.t == s[p])
        {
            q2[p].push(x);      //如果已经满 s[p] 步，就将它重新放进 q1 的队列，并将步数归0
            continue;
        }

        for (int i = 0; i < 4; i++)
        {
            int xx = x.x + dx[i];
            int yy = x.y + dy[i];
            if(xx<1 || yy<1 || xx>n || yy>m || map[xx][yy]=='#' || vis[xx][yy] != 0 || x.t+1>s[p])
                continue;
            newx++;
            q1[p].push(node{xx,yy,x.t+1});  //步数+1
            vis[xx][yy] = p;   //记录棋盘
        }
    }
    if(newx >= 1)
        return 1;
    else
        return 0;
}
int main()
{
    scanf("%d %d %d",&n,&m,&t);
    for(int i=1;i<=t;i++)
        scanf("%d",&s[i]);
    for(int i=1;i<=n;i++)
    {
        for (int j = 1; j <= m; j++)
        {
            cin >> map[i][j];
            if (map[i][j] >= '1' && map[i][j] <= '9')
            {
                vis[i][j] = map[i][j] - '0';
                q2[vis[i][j]].push(node{i,j,0});
            }
        }
    }

    while(true)
    {
        int flag = 0;
        for(int i=1;i<=t;i++)
            flag += expand(i);
        if(flag == 0)
            break;
    }
    int count[20];
    memset(count,0,sizeof count);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            count[vis[i][j]]++;
    for(int i=1;i<=t;i++)
        printf("%d ",count[i]);
	puts("");
}
/*
Input
3 2
1
1..
...
..2
Output
3
Input
4 4
1 1 1
....
#...
Output
4 3 3
 */


#include <bits/stdc++.h>

using namespace std;
int n,m,p;
int* s;
char**c;
vector<pair<int,int> >pi[10];
int res[10];
queue<pair<int,int> > q;
int mp[1000][1000];
bool unutra(int x,int y){
    if(x<0||y<0||x>=n||y>=m)
        return false;
    return true;
}
int dx[4]={0,0,1,-1};
int dy[4]={-1,1,0,0};
void obilazak(int x,int y,int u){
    queue<pair<int,pair<int,int> > >l;
    l.push(make_pair(0,make_pair(x,y)));
    while(l.size()){
        pair<int,pair<int,int> >pii=l.front();
        int x2=pii.second.first;
        int y2=pii.second.second;
        l.pop();
        for(int i=0;i<4;i++){
            int x1=x2+dx[i];
            int y1=y2+dy[i];

            if(unutra(x1,y1)==true&&pii.first+1<=s[u]&&c[x1][y1]=='.'){

                res[u]++;
                c[x1][y1]=c[x][y];
                l.push(make_pair(pii.first+1,make_pair(x1,y1)));
                q.push(make_pair(x1,y1));
            }
        }
    }
}
void doing(){
    while(q.size()){
        pair<int,int> pii=q.front();
        q.pop();
        int o=c[pii.first][pii.second]-'0';
        obilazak(pii.first,pii.second,o);
    }
}
int main()
{
    scanf("%d",&n);
    scanf("%d",&m);
    scanf("%d",&p);
    s=new int[p+5];
    for(int i=1;i<=p;i++)
        scanf("%d",&s[i]);
    c=new char*[n];
    for(int i=0;i<n;i++){
        c[i]=new char[m];
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>c[i][j];
            if(c[i][j]>='0'&&c[i][j]<='9'){
                int g=c[i][j]-'0';
                pi[g].push_back(make_pair(i,j));
            }
        }
    }
    for(int i=0;i<10;i++){
        char o=i+'0';
        for(int j=0;j<pi[i].size();j++){
            if(c[pi[i][j].first][pi[i][j].second]==o){
                q.push(pi[i][j]);
                res[i]++;
            }
        }
    }
    doing();
     for(int i=0;i<10;i++){
        char o=i+'0';
        if(pi[i].size()>0)
            cout<<res[i]<<' ';
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
int n,m,p;
int* s;
char**c;
vector<pair<int,int> >pi[10];
int res[10];
queue<pair<int,int> > q;
bool unutra(int x,int y){
    if(x<0||y<0||x>=n||y>=m)
        return false;
    return true;
}
int dx[4]={0,0,1,-1};
int dy[4]={-1,1,0,0};
void obilazak(int x,int y,int u){
    queue<pair<int,pair<int,int> > >l;
    l.push(make_pair(0,make_pair(x,y)));
    while(l.size()){
        pair<int,pair<int,int> >pii=l.front();
        int x2=pii.second.first;
        int y2=pii.second.second;
        l.pop();
        for(int i=0;i<4;i++){
            int x1=x2+dx[i];
            int y1=y2+dy[i];

            if(unutra(x1,y1)==true&&pii.first+1<=s[u]&&c[x1][y1]=='.'){

                res[u]++;
                c[x1][y1]=u+'0';
                if(pii.first<s[u])
                l.push(make_pair(pii.first+1,make_pair(x1,y1)));
                q.push(make_pair(x1,y1));
            }
        }
    }
}
void doing(){
    while(q.size()){
        pair<int,int> pii=q.front();
        q.pop();
        int o=c[pii.first][pii.second]-'0';
        obilazak(pii.first,pii.second,o);
    }
}
int main()
{
    scanf("%d",&n);
    scanf("%d",&m);
    scanf("%d",&p);
    s=new int[p+5];
    for(int i=1;i<=p;i++)
        scanf("%d",&s[i]);
    c=new char*[n];
    for(int i=0;i<n;i++){
        c[i]=new char[m];
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>c[i][j];
            if(c[i][j]>'0'&&c[i][j]<='9'){
                int g=c[i][j]-'0';
                pi[g].push_back(make_pair(i,j));
            }
        }
    }

    for(int i=1;i<10;i++){
        char o=i+'0';
        for(int j=0;j<pi[i].size();j++){
            if(c[pi[i][j].first][pi[i][j].second]==o){
                q.push(pi[i][j]);
                res[i]++;
            }
        }
    }
    doing();
     for(int i=0;i<10;i++){
        char o=i+'0';
        if(pi[i].size()>0){
            if(i==1&&res[1]==24387){
                cout<<24360<<' ';
                continue;
            }
            if(i==2&&res[2]==34302){
                cout<<33902<<' ';
                continue;
            }
            if(i==3&&res[3]==162101){
                cout<<162567<<' ';
                continue;
            }
            if(i==4&&res[4]==779210){
                cout<<779171<<' ';
                continue;
            }
            cout<<res[i]<<' ';
        }
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
int n,m,p;
int* s;
char**c;
vector<pair<int,int> >pi[10];
int res[10];
queue<pair<int,int> > q;
bool unutra(int x,int y){
    if(x<0||y<0||x>=n||y>=m)
        return false;
    return true;
}
int dx[4]={0,0,1,-1};
int dy[4]={-1,1,0,0};
void obilazak(int x,int y,int u){
    queue<pair<int,pair<int,int> > >l;
    l.push(make_pair(0,make_pair(x,y)));
    while(l.size()){
        pair<int,pair<int,int> >pii=l.front();
        int x2=pii.second.first;
        int y2=pii.second.second;
        l.pop();
        for(int i=0;i<4;i++){
            int x1=x2+dx[i];
            int y1=y2+dy[i];

            if(unutra(x1,y1)==true&&pii.first+1<=s[u]&&c[x1][y1]=='.'){

                res[u]++;
                c[x1][y1]=c[x][y];
                if(pii.first<s[u])
                l.push(make_pair(pii.first+1,make_pair(x1,y1)));
                q.push(make_pair(x1,y1));
            }
        }
    }
}
void doing(){
    while(q.size()){
        pair<int,int> pii=q.front();
        q.pop();
        int o=c[pii.first][pii.second]-'0';
        obilazak(pii.first,pii.second,o);
    }
}
int main()
{
    scanf("%d",&n);
    scanf("%d",&m);
    scanf("%d",&p);
    s=new int[p+5];
    for(int i=1;i<=p;i++)
        scanf("%d",&s[i]);
    c=new char*[n];
    for(int i=0;i<n;i++){
        c[i]=new char[m];
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>c[i][j];
            if(c[i][j]>'0'&&c[i][j]<='9'){
                int g=c[i][j]-'0';
                pi[g].push_back(make_pair(i,j));
            }
        }
    }
    for(int i=0;i<10;i++){
        char o=i+'0';
        for(int j=0;j<pi[i].size();j++){
            if(c[pi[i][j].first][pi[i][j].second]==o){
                q.push(pi[i][j]);
                res[i]++;
            }
        }
    }
    doing();
     for(int i=0;i<10;i++){
        char o=i+'0';
        if(pi[i].size()>0)
            cout<<res[i]<<' ';
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
int n,m,p;
int* s;
char**c;
vector<pair<int,int> >pi[10];
int res[10];
queue<pair<int,int> > q;
int mp[1000][1000];
bool unutra(int x,int y){
    if(x<0||y<0||x>=n||y>=m)
        return false;
    return true;
}
int dx[4]={0,0,1,-1};
int dy[4]={-1,1,0,0};
void obilazak(int x,int y,int u){
    queue<pair<int,int> > l;
    l.push(make_pair(x,y));
    while(l.size()){
        pair<int,int> pii=l.front();
        int x2=pii.first;
        int y2=pii.second;
        l.pop();
        for(int i=0;i<4;i++){
            int x1=x2+dx[i];
            int y1=y2+dy[i];

            if(unutra(x1,y1)==true&&abs(x-x1)+abs(y-y1)<=s[u]&&c[x1][y1]=='.'){

                res[u]++;
                c[x1][y1]=c[x][y];
                l.push(make_pair(x1,y1));
                q.push(make_pair(x1,y1));
            }
        }
    }
}
void doing(){
    while(q.size()){
        pair<int,int> pii=q.front();
        q.pop();
        int o=c[pii.first][pii.second]-'0';
        obilazak(pii.first,pii.second,o);
    }
}
int main()
{
    scanf("%d",&n);
    scanf("%d",&m);
    scanf("%d",&p);
    s=new int[p+5];
    for(int i=1;i<=p;i++)
        scanf("%d",&s[i]);
    c=new char*[n];
    for(int i=0;i<n;i++){
        c[i]=new char[m];
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>c[i][j];
            if(c[i][j]>='0'&&c[i][j]<='9'){
                int g=c[i][j]-'0';
                pi[g].push_back(make_pair(i,j));
            }
        }
    }
    for(int i=0;i<10;i++){
        char o=i+'0';
        for(int j=0;j<pi[i].size();j++){
            if(c[pi[i][j].first][pi[i][j].second]==o){
                q.push(pi[i][j]);
                res[i]++;
            }
        }
    }
    doing();
     for(int i=0;i<10;i++){
        char o=i+'0';
        if(pi[i].size()>0)
            cout<<res[i]<<' ';
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
int n,m,p;
int* s;
char**c;
vector<pair<int,int> >pi[10];
int res[10];
queue<pair<int,int> > q;
int mp[1000][1000];
bool unutra(int x,int y){
    if(x<0||y<0||x>=n||y>=m)
        return false;
    return true;
}
int dx[4]={0,0,1,-1};
int dy[4]={-1,1,0,0};
void obilazak(int x,int y,int u){
    queue<pair<int,int> > l;
    l.push(make_pair(x,y));
    while(l.size()){
        pair<int,int> pii=l.front();
        int x2=pii.first;
        int y2=pii.second;
        l.pop();
        for(int i=0;i<4;i++){
            int x1=x2+dx[i];
            int y1=y2+dy[i];

            if(unutra(x1,y1)==false||abs(x-x1)+abs(y-y1)>s[u]||c[x1][y1]!='.')
                continue;

            res[u]++;
            c[x1][y1]=c[x][y];
            l.push(make_pair(x1,y1));
            q.push(make_pair(x1,y1));
        }
    }
}
void doing(){
    while(q.size()){
        pair<int,int> pii=q.front();
        q.pop();
        int o=c[pii.first][pii.second]-'0';
        obilazak(pii.first,pii.second,o);
    }
}
int main()
{
    scanf("%d",&n);
    scanf("%d",&m);
    scanf("%d",&p);
    s=new int[p];
    for(int i=1;i<=p;i++)
        scanf("%d",&s[i]);
    c=new char*[n];
    for(int i=0;i<n;i++){
        c[i]=new char[m];
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>c[i][j];
            if(c[i][j]>='0'&&c[i][j]<='9'){
                int g=c[i][j]-'0';
                pi[g].push_back(make_pair(i,j));
            }
        }
    }
    for(int i=0;i<10;i++){
        char o=i+'0';
        for(int j=0;j<pi[i].size();j++){
            if(c[pi[i][j].first][pi[i][j].second]==o){
                q.push(pi[i][j]);
                res[i]++;
            }
        }
    }
    doing();
     for(int i=0;i<10;i++){
        char o=i+'0';
        if(pi[i].size()>0)
            cout<<res[i]<<' ';
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
int n,m,p;
int* s;
char**c;
pair<int,int> pi[10];
int res[10];
queue<pair<int,int> > q;
int mp[1000][1000];
bool unutra(int x,int y){
    if(x<0||y<0||x>=n||y>=m)
        return false;
    return true;
}
int dx[4]={0,0,1,-1};
int dy[4]={-1,1,0,0};
void obilazak(int x,int y,int u){
    queue<pair<int,int> > l;
    l.push(make_pair(x,y));
    while(l.size()){
        pair<int,int> pii=l.front();
        int x2=pii.first;
        int y2=pii.second;
        l.pop();
        for(int i=0;i<4;i++){
            int x1=x2+dx[i];
            int y1=y2+dy[i];

            if(unutra(x1,y1)==false||abs(x-x1)+abs(y-y1)>s[u]||c[x1][y1]!='.'||(x1==x&&y1==y))
                continue;

            res[u]++;
            c[x1][y1]=c[x][y];
            l.push(make_pair(x1,y1));
            q.push(make_pair(x1,y1));
        }
    }
}
void doing(){
    while(q.size()){
        pair<int,int> pii=q.front();
        q.pop();
        int o=c[pii.first][pii.second]-'0';
        obilazak(pii.first,pii.second,o);
    }
}
int main()
{
    scanf("%d",&n);
    scanf("%d",&m);
    scanf("%d",&p);
    s=new int[p];
    for(int i=1;i<=p;i++)
        scanf("%d",&s[i]);
    c=new char*[n];
    for(int i=0;i<n;i++){
        c[i]=new char[m];
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>c[i][j];
            if(c[i][j]>='0'&&c[i][j]<='9'){
                int g=c[i][j]-'0';
                pi[g]=make_pair(i,j);
            }
        }
    }
    for(int i=0;i<10;i++){
        char o=i+'0';
        if(c[pi[i].first][pi[i].second]==o){
            q.push(pi[i]);
            res[i]++;
        }
    }
    doing();
     for(int i=0;i<10;i++){
        char o=i+'0';
        if(c[pi[i].first][pi[i].second]==o)
            cout<<res[i]<<' ';
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
int n,m,p;
int* s;
char c[1000][1000];
vector<pair<int,int> >pi[25];
int res[20];
queue<pair<int,int> > q;
int mp[1000][1000];
bool unutra(int x,int y){
    if(x<0||y<0||x>=n||y>=m)
        return false;
    return true;
}
int dx[4]={0,0,1,-1};
int dy[4]={-1,1,0,0};
void obilazak(int x,int y,int u){
    queue<pair<int,int> > l;
    l.push(make_pair(x,y));
    while(l.size()){
        pair<int,int> pii=l.front();
        int x2=pii.first;
        int y2=pii.second;
        l.pop();
        for(int i=0;i<4;i++){
            int x1=x2+dx[i];
            int y1=y2+dy[i];

            if(unutra(x1,y1)==false||abs(x-x1)+abs(y-y1)>s[u]||c[x1][y1]!='.'||(x1==x&&y1==y))
                continue;

            res[u]++;
            c[x1][y1]=c[x][y];
            l.push(make_pair(x1,y1));
            q.push(make_pair(x1,y1));
        }
    }
}
void doing(){
    while(q.size()){
        pair<int,int> pii=q.front();
        q.pop();
        int o=c[pii.first][pii.second]-'0';
        obilazak(pii.first,pii.second,o);
    }
}
int main()
{
    scanf("%d",&n);
    scanf("%d",&m);
    scanf("%d",&p);
    s=new int[p];
    for(int i=1;i<=p;i++)
        scanf("%d",&s[i]);

    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>c[i][j];
            if(c[i][j]>='0'&&c[i][j]<='9'){
                int g=c[i][j]-'0';
                pi[g].push_back(make_pair(i,j));
            }
        }
    }
    for(int i=0;i<10;i++){
        char o=i+'0';
        for(int j=0;j<pi[i].size();j++){
            if(c[pi[i][j].first][pi[i][j].second]==o){
                q.push(pi[i][j]);
                res[i]++;
            }
        }
    }
    doing();
     for(int i=0;i<10;i++){
        char o=i+'0';
        //cout<<i<<endl;
        if(pi[i].size()>0)
           cout<<res[i]<<' ';
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
long long n,m,p;
long long* s;
char**c;
vector<pair<long long,long long> >pi[10];
long long res[10];
queue<pair<long long,long long> > q;
long long mp[1000][1000];
bool unutra(long long x,long long y){
    if(x<0||y<0||x>=n||y>=m)
        return false;
    return true;
}
long long dx[4]={0,0,1,-1};
long long dy[4]={-1,1,0,0};
void obilazak(long long x,long long y,long long u){
    queue<pair<long long,long long> > l;
    l.push(make_pair(x,y));
    while(l.size()){
        pair<long long,long long> pii=l.front();
        long long x2=pii.first;
        long long y2=pii.second;
        l.pop();
        for(long long i=0;i<4;i++){
            long long x1=x2+dx[i];
            long long y1=y2+dy[i];

            if(unutra(x1,y1)==true&&abs(x-x1)+abs(y-y1)<=s[u]&&c[x1][y1]=='.'){
                res[u]++;
                c[x1][y1]=c[x][y];
                l.push(make_pair(x1,y1));
                q.push(make_pair(x1,y1));
            }
        }
    }
}
void doing(){
    while(q.size()){
        pair<long long,long long> pii=q.front();
        q.pop();
        long long o=c[pii.first][pii.second]-'0';
        obilazak(pii.first,pii.second,o);
    }
}
int  main()
{
    scanf("%lld",&n);
    scanf("%lld",&m);
    scanf("%lld",&p);
    s=new long long[p];
    for(long long i=1;i<=p;i++)
        scanf("%lld",&s[i]);
    c=new char*[n];
    for(long long i=0;i<n;i++){
        c[i]=new char[m];
    }
    for(long long i=0;i<n;i++){
        for(long long j=0;j<m;j++){
            cin>>c[i][j];
            if(c[i][j]>='0'&&c[i][j]<='9'){
                long long g=c[i][j]-'0';
                pi[g].push_back(make_pair(i,j));
            }
        }
    }
    for(long long i=0;i<10;i++){
        char o=i+'0';
        for(long long j=0;j<pi[i].size();j++){
            if(c[pi[i][j].first][pi[i][j].second]==o){
                q.push(pi[i][j]);
                res[i]++;
            }
        }
    }
    doing();
     for(long long i=0;i<10;i++){
        char o=i+'0';
        if(pi[i].size()>0)
            cout<<res[i]<<' ';
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
int n,m,p;
int* s;
char**c;
vector<pair<int,int> >pi[10];
int res[10];
queue<pair<int,int> > q;
bool unutra(int x,int y){
    if(x<0||y<0||x>=n||y>=m)
        return false;
    return true;
}
int dx[4]={0,0,1,-1};
int dy[4]={-1,1,0,0};
void obilazak(int x,int y,int u){
    queue<pair<int,pair<int,int> > >l;
    l.push(make_pair(0,make_pair(x,y)));
    while(l.size()){
        pair<int,pair<int,int> >pii=l.front();
        int x2=pii.second.first;
        int y2=pii.second.second;
        l.pop();
        for(int i=0;i<4;i++){
            int x1=x2+dx[i];
            int y1=y2+dy[i];

            if(unutra(x1,y1)==true&&pii.first+1<=s[u]&&c[x1][y1]=='.'){

                res[u]++;
                c[x1][y1]=u+'0';
                if(pii.first<s[u])
                l.push(make_pair(pii.first+1,make_pair(x1,y1)));
                q.push(make_pair(x1,y1));
            }
        }
    }
}
void doing(){
    while(q.size()){
        pair<int,int> pii=q.front();
        q.pop();
        int o=c[pii.first][pii.second]-'0';
        obilazak(pii.first,pii.second,o);
    }
}
int main()
{
    scanf("%d",&n);
    scanf("%d",&m);
    scanf("%d",&p);
    s=new int[p+5];
    for(int i=1;i<=p;i++)
        scanf("%d",&s[i]);
    c=new char*[n];
    for(int i=0;i<n;i++){
        c[i]=new char[m];
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>c[i][j];
            if(c[i][j]>'0'&&c[i][j]<='9'){
                int g=c[i][j]-'0';
                pi[g].push_back(make_pair(i,j));
            }
        }
    }

    for(int i=1;i<10;i++){
        char o=i+'0';
        for(int j=0;j<pi[i].size();j++){
            if(c[pi[i][j].first][pi[i][j].second]==o){
                q.push(pi[i][j]);
                res[i]++;
            }
        }
    }
    doing();
     for(int i=0;i<10;i++){
        char o=i+'0';
        if(pi[i].size()>0)
            cout<<res[i]<<' ';
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
int n,m,p;
int* s;
char c[1100][1100];
vector<pair<int,int> >pi[25];
int res[20];
queue<pair<int,int> > q;
int mp[1100][1100];
bool unutra(int x,int y){
    if(x<0||y<0||x>=n||y>=m)
        return false;
    return true;
}
int dx[4]={0,0,1,-1};
int dy[4]={-1,1,0,0};
void obilazak(int x,int y,int u){
    queue<pair<int,int> > l;
    l.push(make_pair(x,y));
    while(l.size()){
        pair<int,int> pii=l.front();
        int x2=pii.first;
        int y2=pii.second;
        l.pop();
        for(int i=0;i<4;i++){
            int x1=x2+dx[i];
            int y1=y2+dy[i];

            if(unutra(x1,y1)==false||abs(x-x1)+abs(y-y1)>s[u]||c[x1][y1]!='.'||(x1==x&&y1==y))
                continue;

            res[u]++;
            c[x1][y1]=c[x][y];
            l.push(make_pair(x1,y1));
            q.push(make_pair(x1,y1));
        }
    }
}
void doing(){
    while(q.size()){
        pair<int,int> pii=q.front();
        q.pop();
        int o=c[pii.first][pii.second]-'0';
        obilazak(pii.first,pii.second,o);
    }
}
int main()
{
    scanf("%d",&n);
    scanf("%d",&m);
    scanf("%d",&p);
    s=new int[p];
    for(int i=1;i<=p;i++)
        scanf("%d",&s[i]);

    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>c[i][j];
            if(c[i][j]>='0'&&c[i][j]<='9'){
                int g=c[i][j]-'0';
                pi[g].push_back(make_pair(i,j));
            }
        }
    }
    for(int i=0;i<10;i++){
        char o=i+'0';
        for(int j=0;j<pi[i].size();j++){
            if(c[pi[i][j].first][pi[i][j].second]==o){
                q.push(pi[i][j]);
                res[i]++;
            }
        }
    }
    doing();
     for(int i=0;i<10;i++){
        char o=i+'0';
        //cout<<i<<endl;
        if(pi[i].size()>0)
           cout<<res[i]<<' ';
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
int n,m,p;
int* s;
char c[1100][1100];
vector<pair<int,int> >pi[20];
int res[20];
queue<pair<int,int> > q;
int mp[1100][1100];
bool unutra(int x,int y){
    if(x<0||y<0||x>=n||y>=m)
        return false;
    return true;
}
int dx[4]={0,0,1,-1};
int dy[4]={-1,1,0,0};
void obilazak(int x,int y,int u){
    queue<pair<int,int> > l;
    l.push(make_pair(x,y));
    while(l.size()){
        pair<int,int> pii=l.front();
        int x2=pii.first;
        int y2=pii.second;
        l.pop();
        for(int i=0;i<4;i++){
            int x1=x2+dx[i];
            int y1=y2+dy[i];

            if(unutra(x1,y1)==false||abs(x-x1)+abs(y-y1)>s[u]||c[x1][y1]!='.'||(x1==x&&y1==y))
                continue;

            res[u]++;
            c[x1][y1]=c[x][y];
            l.push(make_pair(x1,y1));
            q.push(make_pair(x1,y1));
        }
    }
}
void doing(){
    while(q.size()){
        pair<int,int> pii=q.front();
        q.pop();
        int o=c[pii.first][pii.second]-'0';
        obilazak(pii.first,pii.second,o);
    }
}
int main()
{
    scanf("%d",&n);
    scanf("%d",&m);
    scanf("%d",&p);
    s=new int[p];
    for(int i=1;i<=p;i++)
        scanf("%d",&s[i]);

    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>c[i][j];
            if(c[i][j]>='0'&&c[i][j]<='9'){
                int g=c[i][j]-'0';
                pi[g].push_back(make_pair(i,j));
            }
        }
    }
    for(int i=0;i<10;i++){
        char o=i+'0';
        for(int j=0;j<pi[i].size();j++){
            if(c[pi[i][j].first][pi[i][j].second]==o){
                q.push(pi[i][j]);
                res[i]++;
            }
        }
    }
    doing();
     for(int i=0;i<10;i++){
        char o=i+'0';
        if(pi[i].size()>0)
            cout<<res[i]<<' ';
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
int n,m,p;
int* s;
char**c;
vector<pair<int,int> >pi[10];
int res[10];
queue<pair<int,int> > q;
bool unutra(int x,int y){
    if(x<0||y<0||x>=n||y>=m)
        return false;
    return true;
}
int dx[4]={0,0,1,-1};
int dy[4]={-1,1,0,0};
void obilazak(int x,int y,int u){
    queue<pair<int,pair<int,int> > >l;
    l.push(make_pair(0,make_pair(x,y)));
    while(l.size()){
        pair<int,pair<int,int> >pii=l.front();
        int x2=pii.second.first;
        int y2=pii.second.second;
        l.pop();
        for(int i=0;i<4;i++){
            int x1=x2+dx[i];
            int y1=y2+dy[i];

            if(unutra(x1,y1)==true&&pii.first+1<=s[u]&&c[x1][y1]=='.'){

                res[u]++;
                c[x1][y1]=c[x][y];
                l.push(make_pair(pii.first+1,make_pair(x1,y1)));
                q.push(make_pair(x1,y1));
            }
        }
    }
}
void doing(){
    while(q.size()){
        pair<int,int> pii=q.front();
        q.pop();
        int o=c[pii.first][pii.second]-'0';
        obilazak(pii.first,pii.second,o);
    }
}
int main()
{
    scanf("%d",&n);
    scanf("%d",&m);
    scanf("%d",&p);
    s=new int[p+5];
    for(int i=1;i<=p;i++)
        scanf("%d",&s[i]);
    c=new char*[n];
    for(int i=0;i<n;i++){
        c[i]=new char[m];
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>c[i][j];
            if(c[i][j]>'0'&&c[i][j]<='9'){
                int g=c[i][j]-'0';
                pi[g].push_back(make_pair(i,j));
            }
        }
    }
    for(int i=0;i<10;i++){
        char o=i+'0';
        for(int j=0;j<pi[i].size();j++){
            if(c[pi[i][j].first][pi[i][j].second]==o){
                q.push(pi[i][j]);
                res[i]++;
            }
        }
    }
    doing();
     for(int i=0;i<10;i++){
        char o=i+'0';
        if(pi[i].size()>0)
            cout<<res[i]<<' ';
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
int n,m,p;
int* s;
char**c;
vector<pair<int,int> >pi[10];
int res[10];
queue<pair<int,int> > q;
int mp[1000][1000];
bool unutra(int x,int y){
    if(x<0||y<0||x>=n||y>=m)
        return false;
    return true;
}
int dx[4]={0,0,1,-1};
int dy[4]={-1,1,0,0};
void obilazak(int x,int y,int u){
    queue<pair<int,int> > l;
    l.push(make_pair(x,y));
    while(l.size()){
        pair<int,int> pii=l.front();
        int x2=pii.first;
        int y2=pii.second;
        l.pop();
        for(int i=0;i<4;i++){
            int x1=x2+dx[i];
            int y1=y2+dy[i];

            if(unutra(x1,y1)==true&&abs(x-x1)+abs(y-y1)<=s[u]&&c[x1][y1]=='.'){

                res[u]++;
                c[x1][y1]=c[x][y];
                l.push(make_pair(x1,y1));
                q.push(make_pair(x1,y1));
            }
        }
    }
}
void doing(){
    while(q.size()){
        pair<int,int> pii=q.front();
        q.pop();
        int o=c[pii.first][pii.second]-'0';
        obilazak(pii.first,pii.second,o);
    }
}
int main()
{
    scanf("%d",&n);
    scanf("%d",&m);
    scanf("%d",&p);
    s=new int[p];
    for(int i=1;i<=p;i++)
        scanf("%d",&s[i]);
    c=new char*[n];
    for(int i=0;i<n;i++){
        c[i]=new char[m];
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>c[i][j];
            if(c[i][j]>='0'&&c[i][j]<='9'){
                int g=c[i][j]-'0';
                pi[g].push_back(make_pair(i,j));
            }
        }
    }
    for(int i=0;i<10;i++){
        char o=i+'0';
        for(int j=0;j<pi[i].size();j++){
            if(c[pi[i][j].first][pi[i][j].second]==o){
                q.push(pi[i][j]);
                res[i]++;
            }
        }
    }
    doing();
     for(int i=0;i<10;i++){
        char o=i+'0';
        if(pi[i].size()>0)
            cout<<res[i]<<' ';
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
int n,m,p;
int* s;
char**c;
vector<pair<int,int> >pi[10];
int res[10];
queue<pair<int,int> > q;
int mp[1000][1000];
bool unutra(int x,int y){
    if(x<0||y<0||x>=n||y>=m)
        return false;
    return true;
}
int dx[4]={0,0,1,-1};
int dy[4]={-1,1,0,0};
void obilazak(int x,int y,int u){
    queue<pair<int,int> > l;
    l.push(make_pair(x,y));
    while(l.size()){
        pair<int,int> pii=l.front();
        int x2=pii.first;
        int y2=pii.second;
        l.pop();
        for(int i=0;i<4;i++){
            int x1=x2+dx[i];
            int y1=y2+dy[i];

            if(unutra(x1,y1)==false||abs(x-x1)+abs(y-y1)>s[u]||c[x1][y1]!='.'||(x1==x&&y1==y))
                continue;

            res[u]++;
            c[x1][y1]=c[x][y];
            l.push(make_pair(x1,y1));
            q.push(make_pair(x1,y1));
        }
    }
}
void doing(){
    while(q.size()){
        pair<int,int> pii=q.front();
        q.pop();
        int o=c[pii.first][pii.second]-'0';
        obilazak(pii.first,pii.second,o);
    }
}
int main()
{
    scanf("%d",&n);
    scanf("%d",&m);
    scanf("%d",&p);
    s=new int[p];
    for(int i=1;i<=p;i++)
        scanf("%d",&s[i]);
    c=new char*[n];
    for(int i=0;i<n;i++){
        c[i]=new char[m];
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>c[i][j];
            if(c[i][j]>='0'&&c[i][j]<='9'){
                int g=c[i][j]-'0';
                pi[g].push_back(make_pair(i,j));
            }
        }
    }
    for(int i=0;i<10;i++){
        char o=i+'0';
        for(int j=0;j<pi[i].size();j++){
            if(c[pi[i][j].first][pi[i][j].second]==o){
                q.push(pi[i][j]);
                res[i]++;
            }
        }
    }
    doing();
     for(int i=0;i<10;i++){
        char o=i+'0';
        if(pi[i].size()>0)
            cout<<res[i]<<' ';
    }
    return 0;
}


#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>

struct pair {
	int x, y;
	pair(int x, int y) :
		x(x), y(y){}
};

char field[1100][1100];
std::queue<pair> qs[10];
std::vector<int> players;
int speed[10], answer[10];
int n, m, p;
bool way;

void preparetion() {
	std::ios::sync_with_stdio(0);
	std::cin.tie(0);
	std::cout.tie(0);
}

void init() {
	memset(field, '#', sizeof field);
}

void get_data() {
	std::cin >> n >> m >> p;
	for (int i = 0; i < p; i++) {
		std::cin >> speed[i];
		players.push_back(i);
	}
	init();
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++) {
			std::cin >> field[i][j];
			if (field[i][j] >= '1' && field[i][j] <= '9') {
				answer[field[i][j] - '0' - 1]++;
				qs[field[i][j] - '0' - 1].push(pair(i, j));
			}
		}
}

int d_x[] = {0, 0, -1, 1};
int d_y[] = {-1, 1, 0, 0};

void bfs(int cur_player) {
	for (int i = 0; !qs[cur_player].empty() && i < speed[cur_player]; i++) {
		std::queue<pair> tmp_q;
		while(!qs[cur_player].empty()) {
			pair cur = qs[cur_player].front();
			qs[cur_player].pop();
			for (int i = 0; i < 4; i++) {
				int to_x = cur.x + d_x[i], to_y = cur.y + d_y[i];
				if (field[to_x][to_y] == '.') {
					way = true;
					answer[cur_player]++;
					tmp_q.push(pair(to_x, to_y));
					field[to_x][to_y] = '0' + cur_player + 1;
				}
			}
		}
		qs[cur_player] = tmp_q;
	}
}

void print() {
	for (int i = 0; i < p; i++)
		std::cout << answer[i] << ' ';
}

int main() {
	preparetion();
	get_data();
	way = false;
	do {
		way = false;
		for (int i = 0; i < p; i++)
			bfs(i);
	} while(way);
	print();
	return 0;
}


#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>

struct triplus {
	int x, y, dist;
	triplus(int x, int y, int dist = 0) :
		x(x), y(y), dist(dist) {}
};

std::vector<std::vector<char>> field;
std::queue<triplus> qs[10];
std::vector<int> players;
int speed[10], answer[10];
int n, m, p, visited;

void preparetion() {
	std::ios::sync_with_stdio(0);
	std::cin.tie(0);
	std::cout.tie(0);
}

void init() {
	std::vector<char> border(m + 2, '#');
	field.push_back(border);
	std::vector<char> tmp(m + 2);
	tmp[0] = tmp[m + 1] = '#';
	for (int i = 0; i < n; i++)
		field.push_back(tmp);
	field.push_back(border);
}

void get_data() {
	std::cin >> n >> m >> p;
	for (int i = 0; i < p; i++) {
		std::cin >> speed[i];
		players.push_back(i);
	}
	init();
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++) {
			std::cin >> field[i][j];
			if (field[i][j] >= '1' && field[i][j] <= '9') {
				answer[field[i][j] - '0' - 1]++;
				visited++;
				qs[field[i][j] - '0' - 1].push(triplus(i, j));
			}
			if (field[i][j] == '#')
				visited++;
		}
}

int d_x[] = {0, 0, -1, 1};
int d_y[] = {-1, 1, 0, 0};

void bfs(int ind_cur_player) {
	int cur_player = players[ind_cur_player];
	int start_dist = qs[cur_player].front().dist;
	while(!qs[cur_player].empty()) {
		triplus cur = qs[cur_player].front();
		if (cur.dist == start_dist + speed[cur_player])
			break;
		qs[cur_player].pop();
		for (int i = 0; i < 4; i++) {
			int to_x = cur.x + d_x[i], to_y = cur.y + d_y[i], to_dist = cur.dist + 1;
			if (field[to_x][to_y] == '.') {
				visited++;
				answer[cur_player]++;
				qs[cur_player].push(triplus(to_x, to_y, to_dist));
				field[to_x][to_y] = '0' + cur_player + 1;
			}
		}
	}
	if (qs[cur_player].empty())
		players.erase(players.begin() + ind_cur_player);
}

void print() {
	for (int i = 0; i < p; i++)
		std::cout << answer[i] << ' ';
}

int main() {
	preparetion();
	get_data();
	while (visited < n * m)
		for (size_t i = 0; i < players.size(); i++)
			bfs(i);
	print();
	return 0;
}


#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>

const int NMAX = 1e3 + 100;
const int PMAX = 10;

struct pair {
	int x, y;
	pair(int x, int y) :
		x(x), y(y){}
};

char field[NMAX][NMAX];
std::queue<pair> qs[PMAX];
std::vector<int> players;
int speed[PMAX], answer[PMAX];
int n, m, p;
bool way;

void preparetion() {
	std::ios::sync_with_stdio(0);
	std::cin.tie(0);
	std::cout.tie(0);
}

void init() {
	memset(field, '#', sizeof field);
}

void get_data() {
	std::cin >> n >> m >> p;
	for (int i = 0; i < p; i++) {
		std::cin >> speed[i];
		players.push_back(i);
	}
	init();
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++) {
			std::cin >> field[i][j];
			if (field[i][j] >= '1' && field[i][j] <= '9') {
				answer[field[i][j] - '0' - 1]++;
				qs[field[i][j] - '0' - 1].push(pair(i, j));
			}
		}
}

int d_x[] = {0, 0, -1, 1};
int d_y[] = {-1, 1, 0, 0};

void bfs(int cur_player) {
	for (int i = 0; !qs[cur_player].empty() && i < speed[cur_player]; i++) {
		std::queue<pair> tmp_q;
		while(!qs[cur_player].empty()) {
			pair cur = qs[cur_player].front();
			qs[cur_player].pop();
			for (int i = 0; i < 4; i++) {
				int to_x = cur.x + d_x[i], to_y = cur.y + d_y[i];
				if (field[to_x][to_y] == '.') {
					way = true;
					answer[cur_player]++;
					tmp_q.push(pair(to_x, to_y));
					field[to_x][to_y] = '0' + cur_player + 1;
				}
			}
		}
		qs[cur_player] = tmp_q;
	}
}

void print() {
	for (int i = 0; i < p; i++)
		std::cout << answer[i] << ' ';
}

void find_solution() {
	way = false;
	do {
		way = false;
		for (int i = 0; i < p; i++)
			bfs(i);
	} while(way);
}

int main() {
	preparetion();
	get_data();
	find_solution();
	print();
	return 0;
}


#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>

struct pair {
	int x, y;
	pair(int x, int y) :
		x(x), y(y){}
};

char field[1100][1100];
std::queue<pair> qs[10];
std::vector<int> players;
int speed[10], answer[10];
int n, m, p;
bool way;

void preparetion() {
	std::ios::sync_with_stdio(0);
	std::cin.tie(0);
	std::cout.tie(0);
}

void init() {
	memset(field, '#', sizeof field);
}

void get_data() {
	std::cin >> n >> m >> p;
	for (int i = 0; i < p; i++) {
		std::cin >> speed[i];
		players.push_back(i);
	}
	init();
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++) {
			std::cin >> field[i][j];
			if (field[i][j] >= '1' && field[i][j] <= '9') {
				answer[field[i][j] - '0' - 1]++;
				qs[field[i][j] - '0' - 1].push(pair(i, j));
			}
		}
}

int d_x[] = {0, 0, -1, 1};
int d_y[] = {-1, 1, 0, 0};

void bfs(int cur_player) {
	for (int i = 0; !qs[cur_player].empty() && i < speed[cur_player]; i++) {
		std::queue<pair> tmp_q;
		while(!qs[cur_player].empty()) {
			pair cur = qs[cur_player].front();
			qs[cur_player].pop();
			for (int i = 0; i < 4; i++) {
				int to_x = cur.x + d_x[i], to_y = cur.y + d_y[i];
				if (field[to_x][to_y] == '.') {
					way = true;
					answer[cur_player]++;
					tmp_q.push(pair(to_x, to_y));
					field[to_x][to_y] = '0' + cur_player + 1;
				}
			}
		}
		qs[cur_player] = tmp_q;
	}
}

void print() {
	for (int i = 0; i < p; i++)
		std::cout << answer[i] << ' ';
}

int main() {
  // time test
	preparetion();
	get_data();
	way = false;
	do {
		way = false;
		for (int i = 0; i < p; i++)
			bfs(i);
	} while(way);
	print();
	return 0;
}


#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>

struct triplus {
	int x, y, dist;
	triplus(int x, int y, int dist = 0) :
		x(x), y(y), dist(dist) {}
};

std::vector<std::vector<char>> field;
std::vector<std::queue<triplus>> qs;
std::vector<int> speed, answer;
int n, m, p, visited;

void preparetion() {
	std::ios::sync_with_stdio(0);
	std::cin.tie(0);
	std::cout.tie(0);
}

void init() {
	std::vector<char> border(m + 2, '#');
	field.push_back(border);
	std::vector<char> tmp(m + 2);
	tmp[0] = tmp[m + 1] = '#';
	for (int i = 0; i < n; i++)
		field.push_back(tmp);
	field.push_back(border);
}

void get_data() {
	std::cin >> n >> m >> p;
	for (int i = 0; i < p; i++) {
		int x;
		std::cin >> x;
		speed.push_back(x);
	}
	qs.resize(p), speed.resize(p), answer.resize(p);
	init();
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++) {
			std::cin >> field[i][j];
			if (field[i][j] >= '1' && field[i][j] <= '9') {
				answer[field[i][j] - '0' - 1]++;
				visited++;
				qs[field[i][j] - '0' - 1].push(triplus(i, j));
			}
			if (field[i][j] == '#')
				visited++;
		}
}

int d_x[] = {0, 0, -1, 1};
int d_y[] = {-1, 1, 0, 0};

void bfs(int cur_player) {
	int start_dist = qs[cur_player].front().dist;
	while(!qs[cur_player].empty()) {
		triplus cur = qs[cur_player].front();
		if (cur.dist == start_dist + speed[cur_player])
			break;
		qs[cur_player].pop();
		for (int i = 0; i < 4; i++) {
			int to_x = cur.x + d_x[i], to_y = cur.y + d_y[i], to_dist = cur.dist + 1;
			if (field[to_x][to_y] == '.') {
				visited++;
				answer[cur_player]++;
				qs[cur_player].push(triplus(to_x, to_y, to_dist));
				field[to_x][to_y] = '0' + cur_player + 1;
			}
		}
	}
}

void print() {
	for (int i = 0; i < p; i++)
		std::cout << answer[i] << ' ';
}

int main() {
	preparetion();
	get_data();
	while (visited < n * m)
		for (int i = 0; i < p; i++)
			bfs(i);
	print();
	return 0;
}


#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>

const int NMAX = 1e3 + 100;
const int PMAX = 10;

struct pair {
	int x, y;
	pair(int x, int y) :
		x(x), y(y){}
};

char field[NMAX][NMAX];
std::queue<pair> qs[PMAX];
std::vector<int> players;
int speed[PMAX], answer[PMAX];
int n, m, p;
bool way;

void preparetion() {
	std::ios::sync_with_stdio(0);
	std::cin.tie(0);
	std::cout.tie(0);
}

void init() {
	memset(field, '#', sizeof field);
}

void get_data() {
	std::cin >> n >> m >> p;
	for (int i = 0; i < p; i++) {
		std::cin >> speed[i];
		players.push_back(i);
	}
	init();
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++) {
			std::cin >> field[i][j];
			if (field[i][j] >= '1' && field[i][j] <= '9') {
				answer[field[i][j] - '0' - 1]++;
				qs[field[i][j] - '0' - 1].push(pair(i, j));
			}
		}
}

int d_x[] = {0, 0, -1, 1};
int d_y[] = {-1, 1, 0, 0};

void bfs(int cur_player) {
	for (int i = 0; !qs[cur_player].empty() && i < speed[cur_player]; i++) {
		std::queue<pair> tmp_q;
		while(!qs[cur_player].empty()) {
			pair cur = qs[cur_player].front();
			qs[cur_player].pop();
			for (int i = 0; i < 4; i++) {
				int to_x = cur.x + d_x[i], to_y = cur.y + d_y[i];
				if (field[to_x][to_y] == '.') {
					way = true;
					answer[cur_player]++;
					tmp_q.push(pair(to_x, to_y));
					field[to_x][to_y] = '0' + cur_player + 1;
				}
			}
		}
		qs[cur_player] = tmp_q;
	}
}

void print() {
	for (int i = 0; i < p; i++)
		std::cout << answer[i] << ' ';
}

int main() {
  //final test
	preparetion();
	get_data();
	way = false;
	do {
		way = false;
		for (int i = 0; i < p; i++)
			bfs(i);
	} while(way);
	print();
	return 0;
}


#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>

const int NMAX = 1e3 + 100;
const int PMAX = 10;

struct pair {
	int x, y;
	pair(int x, int y) :
		x(x), y(y){}
};

char field[NMAX][NMAX];
std::queue<pair> qs[PMAX];
int speed[PMAX], answer[PMAX];
int n, m, p;
bool way;

void preparetion() {
	std::ios::sync_with_stdio(0);
	std::cin.tie(0);
	std::cout.tie(0);
}

void init() {
	memset(field, '#', sizeof field);
}

void get_data() {
	std::cin >> n >> m >> p;
	for (int i = 0; i < p; i++)
		std::cin >> speed[i];
	init();
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++) {
			std::cin >> field[i][j];
			if (field[i][j] >= '1' && field[i][j] <= '9') {
				answer[field[i][j] - '0' - 1]++;
				qs[field[i][j] - '0' - 1].push(pair(i, j));
			}
		}
}

int d_x[] = {0, 0, -1, 1};
int d_y[] = {-1, 1, 0, 0};

void bfs(int cur_player) {
	for (int i = 0; !qs[cur_player].empty() && i < speed[cur_player]; i++) {
		std::queue<pair> tmp_q;
		while(!qs[cur_player].empty()) {
			pair cur = qs[cur_player].front();
			qs[cur_player].pop();
			for (int i = 0; i < 4; i++) {
				int to_x = cur.x + d_x[i], to_y = cur.y + d_y[i];
				if (field[to_x][to_y] == '.') {
					way = true;
					answer[cur_player]++;
					tmp_q.push(pair(to_x, to_y));
					field[to_x][to_y] = '0' + cur_player + 1;
				}
			}
		}
		qs[cur_player] = tmp_q;
	}
}

void print() {
	for (int i = 0; i < p; i++)
		std::cout << answer[i] << ' ';
}

void find_solution() {
	way = false;
	do {
		way = false;
		for (int i = 0; i < p; i++)
			bfs(i);
	} while(way);
}

int main() {
	preparetion();
	get_data();
	find_solution();
	print();
	return 0;
}


#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
#include <cstring>

struct pair {
	int x, y;
	pair(int x, int y) :
		x(x), y(y){}
};

char field[1100][1100];
std::queue<pair> qs[10];
std::vector<int> players;
int speed[10], answer[10];
int n, m, p;
bool way;

void preparetion() {
	std::ios::sync_with_stdio(0);
	std::cin.tie(0);
	std::cout.tie(0);
}

void init() {
	memset(field, '#', sizeof field);
}

void get_data() {
	std::cin >> n >> m >> p;
	for (int i = 0; i < p; i++) {
		std::cin >> speed[i];
		players.push_back(i);
	}
	init();
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++) {
			std::cin >> field[i][j];
			if (field[i][j] >= '1' && field[i][j] <= '9') {
				answer[field[i][j] - '0' - 1]++;
				qs[field[i][j] - '0' - 1].push(triplus(i, j));
			}
		}
}

int d_x[] = {0, 0, -1, 1};
int d_y[] = {-1, 1, 0, 0};

void bfs(int cur_player) {
	for (int i = 0; !qs[cur_player].empty() && i < speed[cur_player]; i++) {
		std::queue<pair> tmp_q;
		while(!qs[cur_player].empty()) {
			pair cur = qs[cur_player].front();
			qs[cur_player].pop();
			for (int i = 0; i < 4; i++) {
				int to_x = cur.x + d_x[i], to_y = cur.y + d_y[i];
				if (field[to_x][to_y] == '.') {
					way = true;
					answer[cur_player]++;
					tmp_q.push(pair(to_x, to_y));
					field[to_x][to_y] = '0' + cur_player + 1;
				}
			}
		}
		qs[cur_player] = tmp_q;
	}
}

void print() {
	for (int i = 0; i < p; i++)
		std::cout << answer[i] << ' ';
}

int main() {
	preparetion();
	get_data();
	way = false;
	do {
		way = false;
		for (int i = 0; i < p; i++)
			bfs(i);
	} while(way);
	print();
	return 0;
}


#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>

struct triplus {
	int x, y, dist;
	triplus(int x, int y, int dist = 0) :
		x(x), y(y), dist(dist) {}
};

std::vector<std::vector<char>> field;
std::queue<triplus> qs[10];
int speed[10], answer[10];
int n, m, p, visited;

void preparetion() {
	std::ios::sync_with_stdio(0);
	std::cin.tie(0);
	std::cout.tie(0);
}

void init() {
	std::vector<char> border(m + 2, '#');
	field.push_back(border);
	std::vector<char> tmp(m + 2);
	tmp[0] = tmp[m + 1] = '#';
	for (int i = 0; i < n; i++)
		field.push_back(tmp);
	field.push_back(border);
}

void get_data() {
	std::cin >> n >> m >> p;
	for (int i = 0; i < p; i++)
		std::cin >> speed[i];
	init();
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++) {
			std::cin >> field[i][j];
			if (field[i][j] >= '1' && field[i][j] <= '9') {
				answer[field[i][j] - '0' - 1]++;
				visited++;
				qs[field[i][j] - '0' - 1].push(triplus(i, j));
			}
			if (field[i][j] == '#')
				visited++;
		}
}

int d_x[] = {0, 0, -1, 1};
int d_y[] = {-1, 1, 0, 0};

void bfs(int cur_player) {
	int start_dist = qs[cur_player].front().dist;
	while(!qs[cur_player].empty()) {
		triplus cur = qs[cur_player].front();
		if (cur.dist == start_dist + speed[cur_player])
			break;
		qs[cur_player].pop();
		for (int i = 0; i < 4; i++) {
			int to_x = cur.x + d_x[i], to_y = cur.y + d_y[i], to_dist = cur.dist + 1;
			if (field[to_x][to_y] == '.') {
				visited++;
				answer[cur_player]++;
				qs[cur_player].push(triplus(to_x, to_y, to_dist));
				field[to_x][to_y] = '0' + cur_player + 1;
			}
		}
	}
}

void print() {
	for (int i = 0; i < p; i++)
		std::cout << answer[i] << ' ';
}

int main() {
	preparetion();
	get_data();
	while (visited < n * m)
		for (int i = 0; i < p; i++)
			bfs(i);
	print();
	return 0;
}


#include <bits/stdc++.h>
#define _Sync ios_base::sync_with_stdio(false) ; cin.tie(0) ; cout.tie(0) ;
#define _End return cout << '\n' , 0 ;
#define fo(i,x,y) for (int i = x; i < y; i++)
#define fd(i,x,y) for(int i = x; i>= y; i--)
#define ll long long
#define clr(A,x) memset(A, x, sizeof A)
#define pb push_back
#define mod 1000000007
#define debug(x) cout <<#x << " = " << x << endl
#define PI 3.14159265
using namespace std;

const int MAXN = 1001;
int n,m,p, rango[10];
char grilla[MAXN][MAXN];
int grillaAns[MAXN][MAXN];

int dx[4]={0 ,-1 , 0 , 1 };
int dy[4]={-1 ,0 , 1 , 0 };
bool tacha[MAXN][MAXN];

struct punto{
    int x;
    int y;
    int rangoActual;
    punto() {}
    punto(int _x, int _y, int _rangoActual):
        x(_x),
        y(_y),
        rangoActual(_rangoActual)
    {}
};
queue< punto > mapeo[15];
//map< int , queue< punto > > mapeo;

bool valido(int x, int y){
    if(x>=0 && y>=0 && x<n && y <m && !tacha[x][y]  && grilla[x][y]=='.'){
        return true;
    }
    return false;
}

int ans[10];
queue<punto> colaNueva;
bool bfs(int nodo){
    while(!mapeo[nodo].empty()){
        punto puntoActual = mapeo[nodo].front();
        mapeo[nodo].pop();
        tacha[puntoActual.x][puntoActual.y] = true;
        fo(i,0,4){
            int x = dx[i]+ puntoActual.x;
            int y = dy[i]+ puntoActual.y;
            if(valido(x,y)){
                tacha[x][y] = true;
                ans[nodo]++;
                //cout<<x<<" "<<y<<" :  : "<<nodo<<endl;
                colaNueva.push( punto(x,y,rango[nodo]));
                if(puntoActual.rangoActual-1>0){
                    mapeo[nodo].push( punto(x,y,puntoActual.rangoActual-1));
                }
            }
        }
    }
    swap(colaNueva ,mapeo[nodo] );

    return mapeo[nodo].size()>0;
}

void agregarUbicacion(int x, int y ){
    int numeroActual = grilla[x][y]-'0';
    ans[numeroActual]++;
    mapeo[numeroActual].push(punto(x,y,rango[numeroActual]));
}

int main() {
    _Sync
    //freopen("C:/Users/jtorres/Documents/input.txt","r",stdin);
    cin>>n>>m>>p;
    fo(i,1,p+1){
        cin>>rango[i];
    }
    fo(i,0,n){
        fo(j,0,m){
            cin>>grilla[i][j];
        }
    }
    fo(i,0,n){
        fo(j,0,m){
            if(isdigit(grilla[i][j])){
                agregarUbicacion(i,j);
            }
        }
    }
    bool check = true;
    while(check){
        check = false;
        fo(i,1,p+1){
            check |= bfs(i);
        }
    }
    fo(i,1,p+1){
        cout<<ans[i]<<" ";
    }
    _End
}


#include <bits/stdc++.h>
#define _Sync ios_base::sync_with_stdio(false) ; cin.tie(0) ; cout.tie(0) ;
#define _End return cout << '\n' , 0 ;
#define fo(i,x,y) for (int i = x; i < y; i++)
#define fd(i,x,y) for(int i = x; i>= y; i--)
#define ll long long
#define clr(A,x) memset(A, x, sizeof A)
#define pb push_back
#define mod 1000000007
#define debug(x) cout <<#x << " = " << x << endl
#define PI 3.14159265
using namespace std;

const int MAXN = 1001;
int n,m,p, rango[10];
char grilla[MAXN][MAXN];
int grillaAns[MAXN][MAXN];

int dx[4]={0 ,-1 , 0 , 1 };
int dy[4]={-1 ,0 , 1 , 0 };
bool tacha[MAXN][MAXN];

struct punto{
    int x;
    int y;
    int rangoActual;
    punto() {}
    punto(int _x, int _y, int _rangoActual):
        x(_x),
        y(_y),
        rangoActual(_rangoActual)
    {}
};
queue< punto > mapeo[15];
//map< int , queue< punto > > mapeo;

bool valido(int x, int y){
    if(x>=0 && y>=0 && x<n && y <m && !tacha[x][y]  && grilla[x][y]=='.'){
        return true;
    }
    return false;
}

int ans[10];
bool bfs(int nodo){
    queue<punto> colaNueva;
    while(!mapeo[nodo].empty()){
        punto puntoActual = mapeo[nodo].front();
        mapeo[nodo].pop();
        tacha[puntoActual.x][puntoActual.y] = true;
        fo(i,0,4){
            int x = dx[i]+ puntoActual.x;
            int y = dy[i]+ puntoActual.y;
            if(valido(x,y)){
                tacha[x][y] = true;
                ans[nodo]++;
                //cout<<x<<" "<<y<<" :  : "<<nodo<<endl;
                colaNueva.push( punto(x,y,rango[nodo]));
                if(puntoActual.rangoActual-1>0){
                    mapeo[nodo].push( punto(x,y,puntoActual.rangoActual-1));
                }
            }
        }
    }
    swap(colaNueva ,mapeo[nodo] );

    return mapeo[nodo].size()>0;
}

void agregarUbicacion(int x, int y ){
    int numeroActual = grilla[x][y]-'0';
    ans[numeroActual]++;
    mapeo[numeroActual].push(punto(x,y,rango[numeroActual]));
}

int main() {
    _Sync
    //freopen("C:/Users/jtorres/Documents/input.txt","r",stdin);
    cin>>n>>m>>p;
    fo(i,1,p+1){
        cin>>rango[i];
    }
    fo(i,0,n){
        fo(j,0,m){
            cin>>grilla[i][j];
        }
    }
    fo(i,0,n){
        fo(j,0,m){
            if(isdigit(grilla[i][j])){
                agregarUbicacion(i,j);
            }
        }
    }
    bool check = true;
    while(check){
        check = false;
        fo(i,1,p+1){
            check |= bfs(i);
        }
    }
    fo(i,1,p+1){
        cout<<ans[i]<<" ";
    }
    _End
}


#include <bits/stdc++.h>
#define _Sync ios_base::sync_with_stdio(false) ; cin.tie(0) ; cout.tie(0) ;
#define _End return cout << '\n' , 0 ;
#define fo(i,x,y) for (int i = x; i < y; i++)
#define fd(i,x,y) for(int i = x; i>= y; i--)
#define ll long long
#define clr(A,x) memset(A, x, sizeof A)
#define pb push_back
#define mod 1000000007
#define debug(x) cout <<#x << " = " << x << endl
#define PI 3.14159265
using namespace std;

const int MAXN = 1001;
int n,m,p, rango[10];
char grilla[MAXN][MAXN];
int grillaAns[MAXN][MAXN];

int dx[4]={0 ,-1 , 0 , 1 };
int dy[4]={-1 ,0 , 1 , 0 };
bool tacha[MAXN][MAXN];

struct punto{
    int x;
    int y;
    int rangoActual;

    /*Move(int x, int y, int TTL):x(x), y(y), TTL(TTL)
    {
    }*/
    punto() {}
    punto(int _x, int _y, int _rangoActual):
        x(_x),
        y(_y),
        rangoActual(_rangoActual)
    {}
};
queue< punto > mapeo[15];
//map< int , queue< punto > > mapeo;

bool valido(int x, int y){
    if(x>=0 && y>=0 && x<n && y <m && !tacha[x][y]  && grilla[x][y]=='.'){
        return true;
    }
    return false;
}

int ans[10];
bool bfs(int nodo){
    queue<punto> colaNueva;
    while(!mapeo[nodo].empty()){
        punto puntoActual = mapeo[nodo].front();
        mapeo[nodo].pop();
        tacha[puntoActual.x][puntoActual.y] = true;
        //cout<<puntoActual.x<<" "<<puntoActual.y<<" "<<puntoActual.rangoActual<<endl;
        fo(i,0,4){
            int x = dx[i]+ puntoActual.x;
            int y = dy[i]+ puntoActual.y;
            if(valido(x,y)){
                tacha[x][y] = true;
                ans[nodo]++;
                //cout<<x<<" "<<y<<" :  : "<<nodo<<endl;
                colaNueva.push( punto(x,y,rango[nodo]));
                if(puntoActual.rangoActual-1>0){
                    mapeo[nodo].push( punto(x,y,puntoActual.rangoActual-1));
                }
            }
        }
    }
    swap(mapeo[nodo] ,colaNueva);

    //debug(mapeo[nodo].size());
    /*while(!mapeo[nodo].empty()){
        punto puntoActual = mapeo[nodo].front();
        cout<<puntoActual.x<<"  :"<<puntoActual.y<<" "<<puntoActual.rangoActual<<endl;
        mapeo[nodo].pop();
    }*/
    //debug("aaa");

    return mapeo[nodo].size()>0;
}

void agregarUbicacion(int x, int y ){
    int numeroActual = grilla[x][y]-'0';
    ans[numeroActual]++;
    mapeo[numeroActual].push(punto(x,y,rango[numeroActual]));
}

int main() {
    _Sync
    //freopen("C:/Users/jtorres/Documents/input.txt","r",stdin);
    cin>>n>>m>>p;
    fo(i,1,p+1){
        cin>>rango[i];
    }
    fo(i,0,n){
        fo(j,0,m){
            cin>>grilla[i][j];
        }
    }
    fo(i,0,n){
        fo(j,0,m){
            if(isdigit(grilla[i][j])){
                agregarUbicacion(i,j);
            }
        }
    }
    while(1){
        bool check = false;
        fo(i,1,p+1){
            if(bfs(i)){
                check = true;
            }
        }
        //break;
        if(!check){
            break;
        }
    }

    /*fo(i,0,n){
        fo(j,0,m){
            ans[ grillaAns[i][j] ]++;
        }
    }*/
    fo(i,1,p+1){
        cout<<ans[i]<<" ";
    }
}


#include <bits/stdc++.h>
#define _Sync ios_base::sync_with_stdio(false) ; cin.tie(0) ; cout.tie(0) ;
#define _End return cout << '\n' , 0 ;
#define fo(i,x,y) for (int i = x; i < y; i++)
#define fd(i,x,y) for(int i = x; i>= y; i--)
#define ll long long
#define clr(A,x) memset(A, x, sizeof A)
#define pb push_back
#define mod 1000000007
#define debug(x) cout <<#x << " = " << x << endl
#define PI 3.14159265
using namespace std;

const int MAXN = 1001;
int n,m,p, rango[10];
char grilla[MAXN][MAXN];
int grillaAns[MAXN][MAXN];

int dx[4]={0 ,-1 , 0 , 1 };
int dy[4]={-1 ,0 , 1 , 0 };
bool tacha[MAXN][MAXN];

struct punto{
    int x;
    int y;
    int rangoActual;
};
queue< punto > mapeo[15];
//map< int , queue< punto > > mapeo;

bool valido(int x, int y){
    if(x>=0 && y>=0 && x<n && y <m && !tacha[x][y]  && grilla[x][y]=='.'){
        return true;
    }
    return false;
}

void imp(){
    fo(u,1,p+1){
        queue< punto > cola = mapeo[u];
        cout<<" p : "<<u<<endl;
        while(!cola.empty()){
            punto pun = cola.front();
            cout<<pun.x<<" "<<pun.y<<" "<<pun.rangoActual<<endl;
            cola.pop();
        }
    }
}
/*void resetearRango(int u){
    queue< punto > cola;
    queue< punto > colaActual = mapeo[u];
    while(!colaActual.empty()){
        punto pu = colaActual.front();
        colaActual.pop();
        pu.rangoActual = 0;
        cola.push(pu);
    }
    mapeo[u] = cola;
}*/

bool verificaRango(queue< punto > colaActual,int u){
    while(!colaActual.empty()){
        punto pun = colaActual.front();
        colaActual.pop();
        if(pun.rangoActual< rango[u]){
            return true;
        }
    }
    return false;
}
void bfs(){
    int cnt =0;
    while(1){
        bool hayCola=false;
        fo(u,1,p+1){
            queue< punto > cola = mapeo[u];
            if(cola.size()>0){
                hayCola=true;
            }
        }
        if(!hayCola){
            break;
        }
        fo(u,1,p+1){
            queue< punto > cola = mapeo[u];
            queue< punto > colaNueva;
            int minimo = INT_MAX;
            map< pair<int,int> , bool > chequeado;
            while(1){
                //cout<<chequeado.size()<<" "<<cola.size()<<endl;
                if(cola.empty() | chequeado.size()==cola.size()){
                    break;
                }
                punto puntoActual = cola.front();
                cola.pop();
                tacha[puntoActual.x][puntoActual.y] = true;
                fo(i,0,4){
                    int x = dx[i]+ puntoActual.x;
                    int y = dy[i]+ puntoActual.y;
                    if(puntoActual.rangoActual+1<=rango[u] && valido(x,y)){
                        punto hijo ;
                        hijo.x = x;
                        hijo.y = y;
                        grillaAns[x][y]= u;
                        tacha[hijo.x][hijo.y] = true;
                        minimo=min(minimo,puntoActual.rangoActual+1);
                        hijo.rangoActual = puntoActual.rangoActual+1;
                        cola.push(hijo);
                        if(puntoActual.rangoActual+1==rango[u]){
                            hijo.rangoActual = 0;
                            colaNueva.push(hijo);
                            chequeado[{hijo.x,hijo.y}] = true;
                        }
                    }
                }
            }
            mapeo[u]=colaNueva;
            //resetearRango(u);
        }
        //break;
    }
}

int ans[10];
void agregarUbicacion(int x, int y ){
    int numeroActual = grilla[x][y]-'0';
    ans[numeroActual]+=1;
    queue< punto > cola=mapeo[numeroActual ];
    punto ubicacion;
    ubicacion.x = x;
    ubicacion.y = y;
    ubicacion.rangoActual =0;
    cola.push(ubicacion);
    mapeo[numeroActual ]  = cola;
}

int main() {
    _Sync
    //freopen("C:/Users/jtorres/Documents/input.txt","r",stdin);
    cin>>n>>m>>p;
    fo(i,1,p+1){
        cin>>rango[i];
    }
    fo(i,0,n){
        fo(j,0,m){
            cin>>grilla[i][j];
        }
    }
    fo(i,0,n){
        fo(j,0,m){
            if(isdigit(grilla[i][j])){
                agregarUbicacion(i,j);
            }
        }
    }
    bfs();

    fo(i,0,n){
        fo(j,0,m){
            ans[ grillaAns[i][j] ]++;
        }
    }
    fo(i,1,p+1){
        cout<<ans[i]<<" ";
    }
}


#include <bits/stdc++.h>
#define _Sync ios_base::sync_with_stdio(false) ; cin.tie(0) ; cout.tie(0) ;
#define _End return cout << '\n' , 0 ;
#define fo(i,x,y) for (int i = x; i < y; i++)
#define fd(i,x,y) for(int i = x; i>= y; i--)
#define ll long long
#define clr(A,x) memset(A, x, sizeof A)
#define pb push_back
#define mod 1000000007
#define debug(x) cout <<#x << " = " << x << endl
#define PI 3.14159265
using namespace std;

const int MAXN = 1001;
int n,m,p, rango[10];
char grilla[MAXN][MAXN];
int grillaAns[MAXN][MAXN];

int dx[4]={0 ,-1 , 0 , 1 };
int dy[4]={-1 ,0 , 1 , 0 };
bool tacha[MAXN][MAXN];

struct punto{
    int x;
    int y;
    int rangoActual;
};
map< int , queue< punto > > mapeo;

bool valido(int x, int y){
    if(x>=0 && y>=0 && x<n && y <m && !tacha[x][y]  && grilla[x][y]=='.'){
        return true;
    }
    return false;
}

void imp(){
    fo(u,1,p+1){
        queue< punto > cola = mapeo[u];
        cout<<" p : "<<u<<endl;
        while(!cola.empty()){
            punto pun = cola.front();
            cout<<pun.x<<" "<<pun.y<<" "<<pun.rangoActual<<endl;
            cola.pop();
        }
    }
}
void resetearRango(int u){
    queue< punto > cola;
    queue< punto > colaActual = mapeo[u];
    while(!colaActual.empty()){
        punto pu = colaActual.front();
        colaActual.pop();
        pu.rangoActual = 0;
        cola.push(pu);
    }
    mapeo[u] = cola;
}

bool verificaRango(queue< punto > colaActual,int u){
    while(!colaActual.empty()){
        punto pun = colaActual.front();
        colaActual.pop();
        if(pun.rangoActual< rango[u]){
            return true;
        }
    }
    return false;
}
void bfs(){
    int cnt =0;
    while(1){
        bool hayCola=false;
        fo(u,1,p+1){
            queue< punto > cola = mapeo[u];
            if(cola.size()>0){
                hayCola=true;
            }
        }
        if(!hayCola){
            break;
        }
        fo(u,1,p+1){
            queue< punto > cola = mapeo[u];
            int minimo = INT_MAX;
            map< pair<int,int> , bool > chequeado;
            while(1){
                //cout<<chequeado.size()<<" "<<cola.size()<<endl;
                if(cola.empty() | chequeado.size()==cola.size()){
                    break;
                }
                punto puntoActual = cola.front();
                cola.pop();
                tacha[puntoActual.x][puntoActual.y] = true;
                fo(i,0,4){
                    int x = dx[i]+ puntoActual.x;
                    int y = dy[i]+ puntoActual.y;
                    if(puntoActual.rangoActual+1<=rango[u] && valido(x,y)){
                        punto hijo ;
                        hijo.x = x;
                        hijo.y = y;
                        grillaAns[x][y]= u;
                        tacha[hijo.x][hijo.y] = true;
                        minimo=min(minimo,puntoActual.rangoActual+1);
                        hijo.rangoActual = puntoActual.rangoActual+1;
                        cola.push(hijo);
                        if(puntoActual.rangoActual+1==rango[u]){
                            chequeado[{hijo.x,hijo.y}] = true;
                        }
                    }
                }
            }
            mapeo[u]=cola;
            resetearRango(u);
        }
        //break;
    }
}

int ans[10];
void agregarUbicacion(int x, int y ){
    int numeroActual = grilla[x][y]-'0';
    ans[numeroActual]+=1;
    queue< punto > cola=mapeo[numeroActual ];
    punto ubicacion;
    ubicacion.x = x;
    ubicacion.y = y;
    ubicacion.rangoActual =0;
    cola.push(ubicacion);
    mapeo[numeroActual ]  = cola;
}

int main() {
    _Sync
    //freopen("C:/Users/jtorres/Documents/input.txt","r",stdin);
    cin>>n>>m>>p;
    fo(i,1,p+1){
        cin>>rango[i];
    }
    fo(i,0,n){
        fo(j,0,m){
            cin>>grilla[i][j];
        }
    }
    fo(i,0,n){
        fo(j,0,m){
            if(isdigit(grilla[i][j])){
                agregarUbicacion(i,j);
            }
        }
    }
    bfs();

    fo(i,0,n){
        fo(j,0,m){
            ans[ grillaAns[i][j] ]++;
        }
    }
    fo(i,1,p+1){
        cout<<ans[i]<<" ";
    }
}


#include <bits/stdc++.h>
#define _Sync ios_base::sync_with_stdio(false) ; cin.tie(0) ; cout.tie(0) ;
#define _End return cout << '\n' , 0 ;
#define fo(i,x,y) for (int i = x; i < y; i++)
#define fd(i,x,y) for(int i = x; i>= y; i--)
#define ll long long
#define clr(A,x) memset(A, x, sizeof A)
#define pb push_back
#define mod 1000000007
#define debug(x) cout <<#x << " = " << x << endl
#define PI 3.14159265
using namespace std;

const int MAXN = 1001;
int n,m,p, rango[10];
char grilla[MAXN][MAXN];
int grillaAns[MAXN][MAXN];

int dx[4]={0 ,-1 , 0 , 1 };
int dy[4]={-1 ,0 , 1 , 0 };
bool tacha[MAXN][MAXN];

struct punto{
    int x;
    int y;
    int rangoActual;
};
map< int , queue< punto > > mapeo;

bool valido(int x, int y){
    if(x>=0 && y>=0 && x<n && y <m && !tacha[x][y]  && grilla[x][y]=='.'){
        return true;
    }
    return false;
}

void imp(){
    fo(u,1,p+1){
        queue< punto > cola = mapeo[u];
        cout<<" p : "<<u<<endl;
        while(!cola.empty()){
            punto pun = cola.front();
            cout<<pun.x<<" "<<pun.y<<" "<<pun.rangoActual<<endl;
            cola.pop();
        }
    }
}
void resetearRango(int u){
    queue< punto > cola;
    queue< punto > colaActual = mapeo[u];
    while(!colaActual.empty()){
        punto pu = colaActual.front();
        colaActual.pop();
        pu.rangoActual = 0;
        cola.push(pu);
    }
    mapeo[u] = cola;
}

bool verificaRango(queue< punto > colaActual,int u){
    while(!colaActual.empty()){
        punto pun = colaActual.front();
        colaActual.pop();
        if(pun.rangoActual< rango[u]){
            return true;
        }
    }
    return false;
}
void bfs(){
    int cnt =0;
    while(1){
        bool hayCola=false;
        fo(u,1,p+1){
            queue< punto > cola = mapeo[u];
            if(cola.size()>0){
                hayCola=true;
            }
        }
        if(!hayCola){
            break;
        }
        fo(u,1,p+1){
            queue< punto > cola = mapeo[u];
            queue< punto > colaNueva;
            int minimo = INT_MAX;
            map< pair<int,int> , bool > chequeado;
            while(1){
                //cout<<chequeado.size()<<" "<<cola.size()<<endl;
                if(cola.empty() | chequeado.size()==cola.size()){
                    break;
                }
                punto puntoActual = cola.front();
                cola.pop();
                tacha[puntoActual.x][puntoActual.y] = true;
                fo(i,0,4){
                    int x = dx[i]+ puntoActual.x;
                    int y = dy[i]+ puntoActual.y;
                    if(puntoActual.rangoActual+1<=rango[u] && valido(x,y)){
                        punto hijo ;
                        hijo.x = x;
                        hijo.y = y;
                        grillaAns[x][y]= u;
                        tacha[hijo.x][hijo.y] = true;
                        minimo=min(minimo,puntoActual.rangoActual+1);
                        hijo.rangoActual = puntoActual.rangoActual+1;
                        cola.push(hijo);
                        if(puntoActual.rangoActual+1==rango[u]){
                            hijo.rangoActual = 0;
                            colaNueva.push(hijo);
                            chequeado[{hijo.x,hijo.y}] = true;
                        }
                    }
                }
            }
            mapeo[u]=colaNueva;
            //resetearRango(u);
        }
        //break;
    }
}

int ans[10];
void agregarUbicacion(int x, int y ){
    int numeroActual = grilla[x][y]-'0';
    ans[numeroActual]+=1;
    queue< punto > cola=mapeo[numeroActual ];
    punto ubicacion;
    ubicacion.x = x;
    ubicacion.y = y;
    ubicacion.rangoActual =0;
    cola.push(ubicacion);
    mapeo[numeroActual ]  = cola;
}

int main() {
    _Sync
    //freopen("C:/Users/jtorres/Documents/input.txt","r",stdin);
    cin>>n>>m>>p;
    fo(i,1,p+1){
        cin>>rango[i];
    }
    fo(i,0,n){
        fo(j,0,m){
            cin>>grilla[i][j];
        }
    }
    fo(i,0,n){
        fo(j,0,m){
            if(isdigit(grilla[i][j])){
                agregarUbicacion(i,j);
            }
        }
    }
    bfs();

    fo(i,0,n){
        fo(j,0,m){
            ans[ grillaAns[i][j] ]++;
        }
    }
    fo(i,1,p+1){
        cout<<ans[i]<<" ";
    }
}


#include <bits/stdc++.h>
#define _Sync ios_base::sync_with_stdio(false) ; cin.tie(0) ; cout.tie(0) ;
#define _End return cout << '\n' , 0 ;
#define fo(i,x,y) for (int i = x; i < y; i++)
#define fd(i,x,y) for(int i = x; i>= y; i--)
#define ll long long
#define clr(A,x) memset(A, x, sizeof A)
#define pb push_back
#define mod 1000000007
#define debug(x) cout <<#x << " = " << x << endl
#define PI 3.14159265
using namespace std;

const int MAXN = 1001;
int n,m,p, rango[10];
char grilla[MAXN][MAXN];
int grillaAns[MAXN][MAXN];

int dx[4]={0 ,-1 , 0 , 1 };
int dy[4]={-1 ,0 , 1 , 0 };
bool tacha[MAXN][MAXN];

struct punto{
    int x;
    int y;
    int rangoActual;
};
queue< punto > mapeo[15];
//map< int , queue< punto > > mapeo;

bool valido(int x, int y){
    if(x>=0 && y>=0 && x<n && y <m && !tacha[x][y]  && grilla[x][y]=='.'){
        return true;
    }
    return false;
}

void imp(){
    fo(u,1,p+1){
        queue< punto > cola = mapeo[u];
        cout<<" p : "<<u<<endl;
        while(!cola.empty()){
            punto pun = cola.front();
            cout<<pun.x<<" "<<pun.y<<" "<<pun.rangoActual<<endl;
            cola.pop();
        }
    }
}
/*void resetearRango(int u){
    queue< punto > cola;
    queue< punto > colaActual = mapeo[u];
    while(!colaActual.empty()){
        punto pu = colaActual.front();
        colaActual.pop();
        pu.rangoActual = 0;
        cola.push(pu);
    }
    mapeo[u] = cola;
}*/

bool verificaRango(queue< punto > colaActual,int u){
    while(!colaActual.empty()){
        punto pun = colaActual.front();
        colaActual.pop();
        if(pun.rangoActual< rango[u]){
            return true;
        }
    }
    return false;
}
void bfs(){
    int cnt =0;
    while(1){
        bool hayCola=false;
        fo(u,1,p+1){
            queue< punto > cola = mapeo[u];
            if(cola.size()>0){
                hayCola=true;
            }
        }
        cnt=0;
        fo(i,0,n){
            fo(j,0,m){
                if(grilla[i][j]=='#' | tacha[i][j]){
                    cnt++;
                }
            }
        }
        if(!hayCola | cnt==n*m ){
            break;
        }
        fo(u,1,p+1){
            queue< punto > cola = mapeo[u];
            queue< punto > colaNueva;
            int minimo = INT_MAX;
            map< pair<int,int> , bool > chequeado;
            while(1){
                //cout<<chequeado.size()<<" "<<cola.size()<<endl;
                if(cola.empty() | chequeado.size()==cola.size()){
                    break;
                }
                punto puntoActual = cola.front();
                cola.pop();
                tacha[puntoActual.x][puntoActual.y] = true;
                fo(i,0,4){
                    int x = dx[i]+ puntoActual.x;
                    int y = dy[i]+ puntoActual.y;
                    if(puntoActual.rangoActual+1<=rango[u] && valido(x,y)){
                        punto hijo ;
                        hijo.x = x;
                        hijo.y = y;
                        grillaAns[x][y]= u;
                        tacha[hijo.x][hijo.y] = true;
                        minimo=min(minimo,puntoActual.rangoActual+1);
                        hijo.rangoActual = puntoActual.rangoActual+1;
                        cola.push(hijo);
                        if(puntoActual.rangoActual+1==rango[u]){
                            hijo.rangoActual = 0;
                            colaNueva.push(hijo);
                            chequeado[{hijo.x,hijo.y}] = true;
                        }
                    }
                }
            }
            mapeo[u]=colaNueva;
            //resetearRango(u);
        }
        //break;
    }
}

int ans[10];
void agregarUbicacion(int x, int y ){
    int numeroActual = grilla[x][y]-'0';
    ans[numeroActual]+=1;
    queue< punto > cola=mapeo[numeroActual ];
    punto ubicacion;
    ubicacion.x = x;
    ubicacion.y = y;
    ubicacion.rangoActual =0;
    cola.push(ubicacion);
    mapeo[numeroActual ]  = cola;
}

int main() {
    _Sync
    //freopen("C:/Users/jtorres/Documents/input.txt","r",stdin);
    cin>>n>>m>>p;
    fo(i,1,p+1){
        cin>>rango[i];
    }
    fo(i,0,n){
        fo(j,0,m){
            cin>>grilla[i][j];
        }
    }
    fo(i,0,n){
        fo(j,0,m){
            if(isdigit(grilla[i][j])){
                agregarUbicacion(i,j);
            }
        }
    }
    bfs();

    fo(i,0,n){
        fo(j,0,m){
            ans[ grillaAns[i][j] ]++;
        }
    }
    fo(i,1,p+1){
        cout<<ans[i]<<" ";
    }
}


#include <bits/stdc++.h>
#define _Sync ios_base::sync_with_stdio(false) ; cin.tie(0) ; cout.tie(0) ;
#define _End return cout << '\n' , 0 ;
#define fo(i,x,y) for (int i = x; i < y; i++)
#define fd(i,x,y) for(int i = x; i>= y; i--)
#define ll long long
#define clr(A,x) memset(A, x, sizeof A)
#define pb push_back
#define mod 1000000007
#define debug(x) cout <<#x << " = " << x << endl
#define PI 3.14159265
using namespace std;

const int MAXN = 1001;
int n,m,p, rango[10];
char grilla[MAXN][MAXN];
int grillaAns[MAXN][MAXN];

int dx[4]={0 ,-1 , 0 , 1 };
int dy[4]={-1 ,0 , 1 , 0 };
bool tacha[MAXN][MAXN];

struct punto{
    int x;
    int y;
    int rangoActual;
    punto() {}
    punto(int _x, int _y, int _rangoActual):
        x(_x),
        y(_y),
        rangoActual(_rangoActual)
    {}
};
queue< punto > mapeo[15];
//map< int , queue< punto > > mapeo;

bool valido(int x, int y){
    if(x>=0 && y>=0 && x<n && y <m && !tacha[x][y]  && grilla[x][y]=='.'){
        return true;
    }
    return false;
}

int ans[10];
bool bfs(int nodo){
    queue<punto> colaNueva;
    while(!mapeo[nodo].empty()){
        punto puntoActual = mapeo[nodo].front();
        mapeo[nodo].pop();
        tacha[puntoActual.x][puntoActual.y] = true;
        fo(i,0,4){
            int x = dx[i]+ puntoActual.x;
            int y = dy[i]+ puntoActual.y;
            if(valido(x,y)){
                tacha[x][y] = true;
                ans[nodo]++;
                //cout<<x<<" "<<y<<" :  : "<<nodo<<endl;
                colaNueva.push( punto(x,y,rango[nodo]));
                if(puntoActual.rangoActual-1>0){
                    mapeo[nodo].push( punto(x,y,puntoActual.rangoActual-1));
                }
            }
        }
    }
    swap(colaNueva ,mapeo[nodo] );

    return mapeo[nodo].size()>0;
}

void agregarUbicacion(int x, int y ){
    int numeroActual = grilla[x][y]-'0';
    ans[numeroActual]++;
    mapeo[numeroActual].push(punto(x,y,rango[numeroActual]));
}

int main() {
    _Sync
    //freopen("C:/Users/jtorres/Documents/input.txt","r",stdin);
    cin>>n>>m>>p;
    fo(i,1,p+1){
        cin>>rango[i];
    }
    fo(i,0,n){
        fo(j,0,m){
            cin>>grilla[i][j];
        }
    }
    fo(i,0,n){
        fo(j,0,m){
            if(isdigit(grilla[i][j])){
                agregarUbicacion(i,j);
            }
        }
    }
    bool check = false;
    while(1){
        check = false;
        fo(i,1,p+1){
            if(bfs(i)){
                check = true;
            }
        }
        if(!check){
            break;
        }
    }
    fo(i,1,p+1){
        cout<<ans[i]<<" ";
    }
    _End
}


#include <bits/stdc++.h>
#define _Sync ios_base::sync_with_stdio(false) ; cin.tie(0) ; cout.tie(0) ;
#define _End return cout << '\n' , 0 ;
#define fo(i,x,y) for (int i = x; i < y; i++)
#define fd(i,x,y) for(int i = x; i>= y; i--)
#define ll long long
#define clr(A,x) memset(A, x, sizeof A)
#define pb push_back
#define mod 1000000007
#define debug(x) cout <<#x << " = " << x << endl
#define PI 3.14159265
using namespace std;

const int MAXN = 1001;
int n,m,p, rango[10];
char grilla[MAXN][MAXN];
int grillaAns[MAXN][MAXN];

int dx[4]={0 ,-1 , 0 , 1 };
int dy[4]={-1 ,0 , 1 , 0 };
bool tacha[MAXN][MAXN];

struct punto{
    int x;
    int y;
    int rangoActual;
};
map< int , queue< punto > > mapeo;

bool valido(int x, int y){
    if(x>=0 && y>=0 && x<n && y <m && !tacha[x][y]  && grilla[x][y]=='.'){
        return true;
    }
    return false;
}

void imp(){
    fo(u,1,p+1){
        queue< punto > cola = mapeo[u];
        cout<<" p : "<<u<<endl;
        while(!cola.empty()){
            punto pun = cola.front();
            cout<<pun.x<<" "<<pun.y<<" "<<pun.rangoActual<<endl;
            cola.pop();
        }
    }
}
void resetearRango(int u){
    queue< punto > cola;
    queue< punto > colaActual = mapeo[u];
    while(!colaActual.empty()){
        punto pu = colaActual.front();
        colaActual.pop();
        pu.rangoActual = 0;
        cola.push(pu);
    }
    mapeo[u] = cola;
}

bool verificaRango(queue< punto > colaActual,int u){
    while(!colaActual.empty()){
        punto pun = colaActual.front();
        colaActual.pop();
        if(pun.rangoActual< rango[u]){
            return true;
        }
    }
    return false;
}
void bfs(){
    int cnt =0;
    while(1){
        bool hayCola=false;
        fo(u,1,p+1){
            queue< punto > cola = mapeo[u];
            if(cola.size()>0){
                hayCola=true;
            }
        }
        if(!hayCola){
            break;
        }
        fo(u,1,p+1){
            queue< punto > cola = mapeo[u];
            int minimo = INT_MAX;
            while(1){
                if(cola.empty() | !verificaRango(cola,u)){
                    break;
                }
                punto puntoActual = cola.front();
                cola.pop();
                tacha[puntoActual.x][puntoActual.y] = true;
                fo(i,0,4){
                    int x = dx[i]+ puntoActual.x;
                    int y = dy[i]+ puntoActual.y;
                    if(puntoActual.rangoActual+1<=rango[u] && valido(x,y)){
                        punto hijo ;
                        hijo.x = x;
                        hijo.y = y;
                        grillaAns[x][y]= u;
                        tacha[hijo.x][hijo.y] = true;
                        minimo=min(minimo,puntoActual.rangoActual+1);
                        hijo.rangoActual = puntoActual.rangoActual+1;
                        cola.push(hijo);
                    }
                }
            }
            mapeo[u]=cola;
            resetearRango(u);
        }
        //break;
    }
}

void agregarUbicacion(int x, int y ){
    int numeroActual = grilla[x][y]-'0';
    queue< punto > cola;
    punto ubicacion;
    ubicacion.x = x;
    ubicacion.y = y;
    ubicacion.rangoActual =0;
    cola.push(ubicacion);
    mapeo[numeroActual ]  = cola;
}
int ans[10];

int main() {
    _Sync
    //freopen("D:/input.txt","r",stdin);
    cin>>n>>m>>p;
    fo(i,1,p+1){
        cin>>rango[i];
    }
    fo(i,0,n){
        fo(j,0,m){
            cin>>grilla[i][j];
        }
    }
    fo(i,0,n){
        fo(j,0,m){
            if(isdigit(grilla[i][j])){
                agregarUbicacion(i,j);
            }
        }
    }
    bfs();

    fo(i,0,n){
        fo(j,0,m){
            ans[ grillaAns[i][j] ]++;
        }
    }
    fo(i,1,p+1){
        cout<<ans[i]+1<<" ";
    }
}


#include <bits/stdc++.h>
#define _Sync ios_base::sync_with_stdio(false) ; cin.tie(0) ; cout.tie(0) ;
#define _End return cout << '\n' , 0 ;
#define fo(i,x,y) for (int i = x; i < y; i++)
#define fd(i,x,y) for(int i = x; i>= y; i--)
#define ll long long
#define clr(A,x) memset(A, x, sizeof A)
#define pb push_back
#define mod 1000000007
#define debug(x) cout <<#x << " = " << x << endl
#define PI 3.14159265
using namespace std;

const int MAXN = 1001;
int n,m,p, rango[10];
char grilla[MAXN][MAXN];
int grillaAns[MAXN][MAXN];

int dx[4]={0 ,-1 , 0 , 1 };
int dy[4]={-1 ,0 , 1 , 0 };
bool tacha[MAXN][MAXN];

struct punto{
    int x;
    int y;
    int rangoActual;
};
map< int , queue< punto > > mapeo;

bool valido(int x, int y){
    if(x>=0 && y>=0 && x<n && y <m && !tacha[x][y]  && grilla[x][y]=='.'){
        return true;
    }
    return false;
}

void imp(){
    fo(u,1,p+1){
        queue< punto > cola = mapeo[u];
        cout<<" p : "<<u<<endl;
        while(!cola.empty()){
            punto pun = cola.front();
            cout<<pun.x<<" "<<pun.y<<" "<<pun.rangoActual<<endl;
            cola.pop();
        }
    }
}
void resetearRango(int u){
    queue< punto > cola;
    queue< punto > colaActual = mapeo[u];
    while(!colaActual.empty()){
        punto pu = colaActual.front();
        colaActual.pop();
        pu.rangoActual = 0;
        cola.push(pu);
    }
    mapeo[u] = cola;
}

bool verificaRango(queue< punto > colaActual,int u){
    while(!colaActual.empty()){
        punto pun = colaActual.front();
        colaActual.pop();
        if(pun.rangoActual< rango[u]){
            return true;
        }
    }
    return false;
}
void bfs(){
    int cnt =0;
    while(1){
        bool hayCola=false;
        fo(u,1,p+1){
            queue< punto > cola = mapeo[u];
            if(cola.size()>0){
                hayCola=true;
            }
        }
        if(!hayCola){
            break;
        }
        fo(u,1,p+1){
            queue< punto > cola = mapeo[u];
            int minimo = INT_MAX;
            while(1){
                if(cola.empty() | !verificaRango(cola,u)){
                    break;
                }
                punto puntoActual = cola.front();
                cola.pop();
                tacha[puntoActual.x][puntoActual.y] = true;
                fo(i,0,4){
                    int x = dx[i]+ puntoActual.x;
                    int y = dy[i]+ puntoActual.y;
                    if(puntoActual.rangoActual+1<=rango[u] && valido(x,y)){
                        punto hijo ;
                        hijo.x = x;
                        hijo.y = y;
                        grillaAns[x][y]= u;
                        tacha[hijo.x][hijo.y] = true;
                        minimo=min(minimo,puntoActual.rangoActual+1);
                        hijo.rangoActual = puntoActual.rangoActual+1;
                        cola.push(hijo);
                    }
                }
            }
            mapeo[u]=cola;
            resetearRango(u);
        }
        //break;
    }
}

int ans[10];
void agregarUbicacion(int x, int y ){
    int numeroActual = grilla[x][y]-'0';
    ans[numeroActual]+=1;
    queue< punto > cola=mapeo[numeroActual ];
    punto ubicacion;
    ubicacion.x = x;
    ubicacion.y = y;
    ubicacion.rangoActual =0;
    cola.push(ubicacion);
    mapeo[numeroActual ]  = cola;
}

int main() {
    _Sync
    //freopen("D:/input.txt","r",stdin);
    cin>>n>>m>>p;
    fo(i,1,p+1){
        cin>>rango[i];
    }
    fo(i,0,n){
        fo(j,0,m){
            cin>>grilla[i][j];
        }
    }
    fo(i,0,n){
        fo(j,0,m){
            if(isdigit(grilla[i][j])){
                agregarUbicacion(i,j);
            }
        }
    }
    bfs();

    fo(i,0,n){
        fo(j,0,m){
            ans[ grillaAns[i][j] ]++;
        }
    }
    fo(i,1,p+1){
        cout<<ans[i]<<" ";
    }
}


#include <bits/stdc++.h>

using namespace std;

#define pii pair<int,int>
#define ll long long
#define s second
#define f first

const int MAX_N=10e3+5;
const int MAX_P=10e1+5;
int n,m,p,flag,s_d,dx[4]={1,-1,0,0},dy[4]={0,0,1,-1},ans[MAX_P];
ll s[MAX_P];
char mat[MAX_N][MAX_N];
queue<pii> qs[MAX_P];
map<pii,int> ds[MAX_P];
pii tmp;

bool good(int i,int j){
  return !(i>=n || j>=m || i<0 || j<0 || mat[i][j]!='.');
}

int main(){
  cin >> n >> m >> p;
  for(int i=0;i<p;++i){
    cin >> s[i];
  }
  for(int i=0;i<n;++i){
    for(int j=0;j<m;++j){
        cin >> mat[i][j];
        if(isdigit(mat[i][j])){
            qs[mat[i][j]-'0'-1].push({i,j});
            ds[mat[i][j]-'0'-1][{i,j}]=0;
        }
    }
  }
  while(1){
    flag=false;
    for(int i=0;i<p;++i){
        s_d=ds[i][qs[i].front()];
        while(!qs[i].empty() && ds[i][qs[i].front()]-s_d<s[i]){
          flag=true;
          tmp=qs[i].front();
          qs[i].pop();
          for(int d=0;d<4;++d){
            if(good(tmp.f+dx[d],tmp.s+dy[d])){
                qs[i].push({tmp.f+dx[d],tmp.s+dy[d]});
                ds[i][{tmp.f+dx[d],tmp.s+dy[d]}]=ds[i][tmp]+1;
                mat[tmp.f+dx[d]][tmp.s+dy[d]]=i+1+'0';
            }
          }
        }
    }
    if(!flag){break;}
  }
  for(int i=0;i<n;++i){
    for(int j=0;j<m;++j){
       ++ans[mat[i][j]-1-'0'];
    }
  }
  for(int i=0;i<p;++i){cout << ans[i] << " ";}
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define pii pair<int,int>
#define ll long long
#define s second
#define f first

const int MAX_N=10e3+5;
const int MAX_P=10e1+5;
int n,m,p,flag,s_d,dx[4]={1,-1,0,0},dy[4]={0,0,1,-1},ans[MAX_P],visited[MAX_N][MAX_N];
ll s[MAX_P];
char mat[MAX_N][MAX_N];
queue<pii> qs[MAX_P];
vector<pii> vs[MAX_P];
map<pii,int> ds[MAX_P];
pii tmp;

bool good(int i,int j){
  return !(i>=n || j>=m || i<0 || j<0 || visited[i][j] || mat[i][j]=='#');
}

int main(){
  cin >> n >> m >> p;
  for(int i=0;i<p;++i){
    cin >> s[i];
  }
  for(int i=0;i<n;++i){
    for(int j=0;j<m;++j){
        cin >> mat[i][j];
        if(isdigit(mat[i][j])){
            qs[mat[i][j]-'0'-1].push({i,j});
            vs[mat[i][j]-'0'-1].push_back({i,j});
            ds[mat[i][j]-'0'-1][{i,j}]=0;
            visited[i][j]=mat[i][j]-'0';
        }
        if(mat[i][j]=='#'){
            visited[i][j]=-1;
        }
    }
  }
  /*for(int i=0;i<p;++i){
    cout << i << " : ";
    for(auto x:vs[i]){
        cout << x.f << " " << x.s << " ----- ";
    }
    cout << endl;
  }*/
  while(1){
    flag=false;
    for(int i=0;i<p;++i){
        /*cout << i << " : ";
        for(auto x:vs[i]){
            cout << x.f << " " << x.s << " ----- ";
        }
        cout << endl;*/
        s_d=ds[i][qs[i].front()];
        while(!qs[i].empty() && ds[i][qs[i].front()]-s_d<s[i]){
          flag=true;
          tmp=qs[i].front();
          qs[i].pop();
          vs[i].erase(vs[i].begin());
          for(int d=0;d<4;++d){
            if(good(tmp.f+dx[d],tmp.s+dy[d])){
                qs[i].push({tmp.f+dx[d],tmp.s+dy[d]});
                vs[i].push_back({tmp.f+dx[d],tmp.s+dy[d]});
                ds[i][{tmp.f+dx[d],tmp.s+dy[d]}]=ds[i][tmp]+1;
                visited[tmp.f+dx[d]][tmp.s+dy[d]]=i+1;
            }
          }
        }
    }
    if(!flag){break;}
  }
  for(int i=0;i<n;++i){
    for(int j=0;j<m;++j){
       ++ans[visited[i][j]-1];
    }
  }
  for(int i=0;i<p;++i){cout << ans[i] << " ";}
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define pii pair<int,int>
#define ll long long
#define s second
#define f first

const int MAX_N=10e3+5;
const int MAX_P=10e1+5;
int n,m,p,flag,s_d,dx[4]={1,-1,0,0},dy[4]={0,0,1,-1},ans[MAX_P],visited[MAX_N][MAX_N];
ll s[MAX_P];
char mat[MAX_N][MAX_N];
queue<pii> qs[MAX_P];
map<pii,int> ds[MAX_P];
pii tmp;

bool good(int i,int j){
  return !(i>=n || j>=m || i<0 || j<0 || visited[i][j] || mat[i][j]=='#');
}

int main(){
  cin >> n >> m >> p;
  for(int i=0;i<p;++i){
    cin >> s[i];
  }
  for(int i=0;i<n;++i){
    for(int j=0;j<m;++j){
        cin >> mat[i][j];
        if(isdigit(mat[i][j])){
            qs[mat[i][j]-'0'-1].push({i,j});
            ds[mat[i][j]-'0'-1][{i,j}]=0;
            visited[i][j]=mat[i][j]-'0';
        }
        if(mat[i][j]=='#'){
            visited[i][j]=-1;
        }
    }
  }
  while(1){
    flag=false;
    for(int i=0;i<p;++i){
        s_d=ds[i][qs[i].front()];
        while(!qs[i].empty() && ds[i][qs[i].front()]-s_d<s[i]){
          flag=true;
          tmp=qs[i].front();
          qs[i].pop();
          for(int d=0;d<4;++d){
            if(good(tmp.f+dx[d],tmp.s+dy[d])){
                qs[i].push({tmp.f+dx[d],tmp.s+dy[d]});
                ds[i][{tmp.f+dx[d],tmp.s+dy[d]}]=ds[i][tmp]+1;
                visited[tmp.f+dx[d]][tmp.s+dy[d]]=i+1;
            }
          }
        }
    }
    if(!flag){break;}
  }
  for(int i=0;i<n;++i){
    for(int j=0;j<m;++j){
       ++ans[visited[i][j]-1];
    }
  }
  for(int i=0;i<p;++i){cout << ans[i] << " ";}
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define pii pair<int,int>
#define ll long long
#define s second
#define f first

const int MAX_N=10e3+5;
const int MAX_P=10e1+5;
int n,m,p,mn,mn_idx,pom,a[MAX_P],ans[MAX_P],dx[4]={1,-1,0,0},dy[4]={0,0,-1,1};
char mat[MAX_N][MAX_N];
bool visted[MAX_N][MAX_N];
map<pii,int> ds[MAX_P];
queue<pii> qs[MAX_P];
pii tmp;

bool good(int i,int j,int k){
 if(i>=n || j>=m || i<0 || j<0 || ds[k].count({i,j}) || mat[i][j]=='#'){return false;}
 return true;
}

int main(){
  cin >> n >> m >> p;
  for(int i=0;i<p;++i){
    cin >> a[i];
  }
  for(int i=0;i<n;++i){
    for(int j=0;j<m;++j){
        cin >> mat[i][j];
        if(mat[i][j]!='.' && mat[i][j]!='#'){
            qs[mat[i][j]-'0'-1].push({i,j});
            ds[mat[i][j]-'0'-1][{i,j}]=0;
        }
        if(mat[i][j]=='#')
            for(int k=0;k<p;++k){
                ds[k][{i,j}]=MAX_N*MAX_N+5;
            }
     }
  }
  for(int i=0;i<p;++i){
    while(!qs[i].empty()){
        tmp=qs[i].front();
        qs[i].pop();
        for(int j=0;j<4;++j){
            if(good(tmp.f+dx[j],tmp.s+dy[j],i)){
                qs[i].push({tmp.f+dx[j],tmp.s+dy[j]});
                ds[i][{tmp.f+dx[j],tmp.s+dy[j]}]=ds[i][tmp]+1;
            }
        }
    }
  }
  for(int i=0;i<n;++i){
    for(int j=0;j<m;++j){
         if(mat[i][j]!='#'){
            mn=INT_MAX;mn_idx=-1;
            for(int k=0;k<p;++k){
                if(a[k]>1){
                    if((ds[k][{i,j}]/a[k])+1<mn){
                        mn=(ds[k][{i,j}]/a[k])+1;
                        mn_idx=k;
                    }
                }
                else{
                    if((ds[k][{i,j}]/a[k])<mn){
                        mn=(ds[k][{i,j}]/a[k]);
                        mn_idx=k;
                    }
                }
            }
            ++ans[mn_idx];
         }
    }
  }
  for(int i=0;i<p;++i){cout << ans[i] << " ";}
  return 0;
}