// Slower C++ solution:


#include <iostream>

#include <cstdio>

#include <cstring>

#include <queue>



using namespace std;

const int maxn = 1e3 + 5;

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

int mp[maxn][maxn];

//bool vis[maxn][maxn];

int d[maxn][maxn];

struct point{

    int x,y;

};

int h,w,n;

 int dis = 0;

void bfs(point &p,int cnt)

{

   // memset(vis, 0, sizeof(vis));

    memset(d, 0, sizeof(d));

    queue<point> q;

    q.push(p);

    while (!q.empty()) {

        point t = q.front();q.pop();

        //vis[t.x][t.y] = true;

        if(mp[t.x][t.y] == cnt + 1) {dis += d[t.x][t.y];p.x = t.x,p.y = t.y;return ;}

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

            int tx = t.x + dir[i][0];

            int ty = t.y + dir[i][1];

            if (tx >= 0 && tx < h && ty >= 0 && ty < w && !d[tx][ty] && mp[tx][ty] != -1) {

                q.push({tx,ty});

                d[tx][ty] = 1 + d[t.x][t.y];

            }

        }

    }

}

int main()

{

    while (scanf("%d%d%d",&h,&w,&n) != EOF) {

        getchar();

        char ch;

        memset(mp, -1, sizeof(mp));

       // int sx,sy;

        point s;

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

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

                scanf("%c",&ch);

                if(ch == 'S') {s.x = i,s.y = j;mp[i][j] = 0;}

                else if(ch == '.') {mp[i][j] = 0;}

                else if(isdigit(ch)) {mp[i][j] = ch - '0';}

            }

            getchar();

        }

       

        dis = 0;

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

            bfs(s,i);

        }

        printf("%d\n",dis);

    }

    return 0;

}

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

#include <cctype>

#include <queue>

#include <string.h>

using namespace std;

const int DIRECTSIZE = 4;

struct _direct {

    int drow;

    int dcol;

} direct[DIRECTSIZE] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}};



const int N = 1000;

const int N2 = 10;

char grid[N][N], visited[N][N];

int h, w, n;

struct _factory {

    int row, col;

} factory[N2];



struct _node {

    int row, col, level;

};



int bfs(int n, char goal)

{

    memset(visited, 0, sizeof(visited));



    _node start={factory[n-1].row, factory[n-1].col, 0}, temp;



    visited[start.row][start.col] = 1;



    queue<_node> q;

    q.push(start);



    while(!q.empty()) {

        _node front = q.front();

        q.pop();



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

            int nextrow = front.row + direct[i].drow;

            int nextcol = front.col + direct[i].dcol;

            if( 0 <= nextrow && nextrow < h && 0 <= nextcol && nextcol < w) {

                if(grid[nextrow][nextcol] == goal) {

                    return front.level + 1;

                } else if(visited[nextrow][nextcol] == 0 && grid[nextrow][nextcol] != 'X') {

                    visited[nextrow][nextcol] = 1;

                    temp.row = nextrow;

                    temp.col = nextcol;

                    temp.level = front.level + 1;

                    q.push(temp);

                }

            }

        }

    }



    return 0;

}



int main()

{

    while(cin >> h >> w >> n) {

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

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

                cin >> grid[i][j];



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

                    factory[0].row = i;

                    factory[0].col = j;

                } else if(isdigit(grid[i][j])) {

                    factory[grid[i][j] - '0'].row = i;

                    factory[grid[i][j] - '0'].col = j;

                }

            }



        int minstep = 0;

        char goal = '1';

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

            minstep += bfs(i, goal);

            goal++;

        }



        cout << minstep << endl;

    }



    return 0;

}