// Original C++ solution (slower):
#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;

}


// Optimized solution to the same problem (faster):
#include <iostream>

#include <queue>

using namespace std;

const int INF = 100000000;

typedef pair<int,int> Point;

Point AllPoint[1000];

int W,H;

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

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

char map[1000][1000];

int deep[1000][1000];

int N;

void BFS(Point Start,Point Over){

    queue<Point> que;

    int FirstDeep = deep[Start.first][Start.second];

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

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

            deep[i][j] = INF;

        }

    }

    que.push(Start);

    deep[Start.first][Start.second] = FirstDeep;

    while (que.size()){

        Point p = que.front();

        que.pop();

        if (p.first== Over.first&&p.second == Over.second)

            break;

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

            int ix = p.first+x[i];

            int iy = p.second+y[i];

            if (ix>=0&&ix<=H

                &&iy>=0&&iy<=W

                &&deep[ix][iy] == INF

                &&map[ix][iy]!='X'){

                que.push(Point(ix,iy));

                deep[ix][iy] = deep[p.first][p.second]+1;

            }

        }

    }

}







int main(){

    cin >> H >> W;

    cin >> N;

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

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

            cin >> map[i][j];

            if ((int)map[i][j]-48>=1&&(int)map[i][j]-48<=N){

                AllPoint[(int)map[i][j]-48].first = i;

                AllPoint[(int)map[i][j]-48].second = j;



            }

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

                AllPoint[0].first = i;

                AllPoint[0].second = j;

            }

        }

    }

    deep[AllPoint[0].first][AllPoint[0].second] = 0;

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

        BFS(AllPoint[i],AllPoint[i+1]);

    }

    cout << deep[AllPoint[N].first][AllPoint[N].second]<<endl;



    return 0;

}

//#....

//S.##.

//###G.

//#####

//#####



//#S######.#

//......#..#

//.#.##.##.#

//.#........

//##.##.####

//....#....#

//.#######.#

//....#.....

//.####.###.

//....#...G#






// Fastest known solution for this problem: