// Slower C++ solution:
#include <cstdio>

#include <cmath>

#include <algorithm>

#include <queue>

#include <iostream>

#include <vector>

#include <cstdlib>

#include <cstring>

#define eps 1e-6

#define ll long long

#define INF 0x3f3f3f3f

using namespace std;



char map[1005][1005];

int dis[1005][1005];

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

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

int row,col,n;

int current = 1;

int firstX,firstY;

int ans = 0;

typedef pair<int,int> pos;

queue <pos> q;



void bfs(){

    while(q.size()){

        pos t = q.front();

        q.pop();

        if(map[t.first][t.second] - '0'== current){

            ans += dis[t.first][t.second];

            current++;

            //清空队列保证下次起点正常

            while(q.size()){

                q.pop();

            }

            //重置距离数组

            memset(dis,INF,sizeof dis);

            dis[t.first][t.second] = 0;

            //设置下一次广搜的起点

            q.push(pos(t.first,t.second));

        }

        //四个方向进行bfs

        for(int i = 0;i<4;i++){

            int x = t.first + dx[i];

            int y = t.second + dy[i];

            if(x<0 || x>= row || y < 0|| y>=col || map[x][y] == 'X' || dis[x][y] != INF)//INF判断是否走过

                continue;

            else{

                q.push(pos(x,y));

                dis[x][y] = dis[t.first][t.second] + 1;

            }

        }

    }

}



int main(){

    cin>>row>>col>>n;

    //初始化

    ans = 0;

    memset(dis,INF,sizeof dis);

    for(int i = 0;i<row;i++){

        for(int j = 0;j<col;j++){

            cin>>map[i][j];

            if(map[i][j] == 'S'){

                //设置起点

                q.push(pos(i,j));

                dis[i][j] = 0;

            }

        }

    }

    //开始广搜

    bfs();

    cout<<ans<<endl;

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 9.259095979911278x):
#include <iostream>

#include <queue>



using namespace std;



char mp[1005][1005];

int vis[1005][1005];

int w, h, n;



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

int ans = 0, sx, sy;

int blood = 1;



struct Node{

	int x,y;

	Node(int _x, int _y){

		x = _x, y = _y;

	}

}; 

typedef struct Node Node; 



queue<Node> que;



void bfs(char t){

//	cout<<"sx = "<<sx<<", sy = "<<sy<<endl;

	que.push(Node(sx, sy));

	ans = 0;

	bool flag = true;

	while(!que.empty()){

//		cout<<"ans = "<<ans<<"n = "<<n<<endl;

		int size = que.size();

		for(int i = 0; i < size; i++){

			Node node = que.front();

			que.pop();

			int x = node.x, y = node.y;

//			cout<<"x = "<<x<<", y = "<<y<<endl;

			for(int i = 0; i < 4; i++){

				int tx = x + dirs[i][0], ty = y + dirs[i][1];

				if(tx >= 0 && tx < h && ty >= 0 && ty < w && vis[tx][ty] == 0 && mp[tx][ty] == t){

					sx = tx, sy = ty;

					ans++;

					flag = false;

					return;

				}else if(tx >= 0 && tx < h && ty >= 0 && ty < w && vis[tx][ty] == 0 &&  mp[tx][ty] != 'X'){

//					cout<<"tx = "<<tx<<", ty = "<<ty<<endl;

					que.push(Node(tx, ty));

					vis[tx][ty] = 1;

				}

			} 

		}

		ans++;

	}

	if(flag) ans = 0;

}



int main(){

	cin>>h>>w>>n;

	for(int i = 0; i < h; i++){

		scanf(" %s", mp[i]);

	}

	for(int i = 0; i < h; i++){

		for(int j = 0; j < w; j++){

			if(mp[i][j] == 'S'){

				sx = i, sy = j;

			}

		}

	}

	int res = 0;

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

		bfs(i + '0');

		for(int m = 0; m < h; m++)

			for(int k = 0; k < w; k++)

				vis[m][k] = 0;

		while(!que.empty())que.pop();

		res += ans;

	}

	cout<<res<<endl;

	return 0;

}



/**

331

S..

...

..1

*/