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

#include <algorithm>

#include <iostream>

#include <cstring>

#include <queue>



using namespace std;



const int hw_max = 1000 + 5;

char graph[hw_max][hw_max];

int sign[hw_max][hw_max];

int h, w, n, ans;

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

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

struct node

{

    int x;

    int y;

    int time;

} start;



void BFS(node op, char ed)

{

    queue <node> process;

    process.push(op);

    sign[op.x][op.y] = 1;

    while(!process.empty())

    {

        node now = process.front();

        process.pop();

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

        {

            node next = now;

            next.x += dx[i];

            next.y += dy[i];

            next.time ++;

            if(next.x >= 0 && next.x < h && next.y >= 0 && next.y < w && graph[next.x][next.y] != 'X' && !sign[next.x][next.y])

            {

                if(graph[next.x][next.y] == ed)

                {

                    ans += next.time;

                    next.time = 0;

                    start = next;

                        return;

                }

                else

                {

                    process.push(next);

                    sign[next.x][next.y] = 1;

                }

            }

        }

    }

}



int main()

{

    while(~scanf("%d %d %d", & h, & w, & n))

    {

        getchar();

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

        {

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

            {

                   scanf("%c", & graph[i][j]);

                   if(graph[i][j] == 'S')

                   {

                    start.x = i;

                    start.y = j;

                    start.time = 0;

                   }

            }

            getchar();

        }

        ans = 0;

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

        {

            memset(sign, 0, sizeof(sign));

            BFS(start, '0' + i);

        }

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

    }

    return 0;

}

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

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<string>

#include<math.h>

#include<queue>

using namespace std;



struct data_Node{

	int x,y,time;

};



char dataSet[1001][1001];

bool visited[1001][1001];

int H,W,N;



int total_time,total_storage,cnt_storage,cnt_time;

int start_row,start_cell;

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

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







void Find_Short_Path (int x,int y)

{

	memset(visited,false,sizeof(visited));

	data_Node temp_data;

	temp_data.x = x;

	temp_data.y = y;

	temp_data.time = 0;

	visited[x][y] = true;

	cnt_time = 0;

	queue<data_Node> temp_queue;

	temp_queue.push(temp_data);

	while (temp_queue.empty() != true)

	{

		data_Node u = temp_queue.front();

		temp_queue.pop();

		if ((int)(dataSet[u.x][u.y] - '0') == total_storage)

		{

			start_row = u.x;

			start_cell = u.y;

			cnt_time = u.time;

			break;

		}

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

		{

			int dx = u.x + control_x[i];

			int dy = u.y + control_y[i];

			if (dataSet[dx][dy] != 'X' && dx >= 0 && dx< H && dy >= 0 && dy < W)

			{

				data_Node v;

				v.x = dx;

				v.y = dy;	

				v.time = u.time + 1;//此?有坑

				if (visited[dx][dy] == false)

				{

					visited[dx][dy] = true;

					temp_queue.push(v);

				}

			}

		}

	}

}



int main ()

{



		cin>>H>>W>>N;

		memset(dataSet,'X',sizeof(dataSet));

		total_storage = 1;

		total_time = 0;

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

		{

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

			{

				cin>>dataSet[i][j];

				if (dataSet[i][j] == 'S')

				{

					start_row = i;

					start_cell = j;

				}

			}

		}

		int ans = 0;

		for (int i=1;i<=N;i++)

		{

			total_storage = i;

			Find_Short_Path(start_row,start_cell);

			ans += cnt_time;

		}

		cout<<ans<<endl;



	return 0;

}