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

#include<deque>

#include<memory.h>



using namespace std;



int H, W, N;

char mapT[1000][1000];

int vis[1000][1000];

int temp_x = 0, temp_y;

char temp;

int final_min_route = 0;

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



struct location {

	int x, y, route;

};



location findSmallRouteBFS(int x, int y, char factory) {

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

	deque<location> que;

	location temp = { x,y,0 };

	que.push_back(temp);

	vis[x][y] = 1;

	while (!que.empty()) {

		location st = que.front();

		que.pop_front();

		if (mapT[st.x][st.y] == factory) {

			return st;

		}

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

			int t_x = st.x + dir[i][0];

			int t_y = st.y + dir[i][1];

			if (t_x < 0 || t_x >= H || t_y < 0 || t_y >= W || mapT[t_x][t_y] == 'X') {

				continue;

			}

			location temp = { t_x,t_y,st.route + 1 };

			if (!vis[t_x][t_y]) {

				vis[t_x][t_y] = 1;

				que.push_back(temp);

			}

		}

	}



}



int main() {

	cin >> H >> W >> N;

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

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

			cin >> temp;

			mapT[i][j] = temp;

			if (temp == 'S') {

				mapT[i][j] = '0';

				temp_x = i;

				temp_y = j;

			}

		}

	}



	for (int factory = 1; factory != N + 1; ++factory) {



		location lo = findSmallRouteBFS(temp_x, temp_y, mapT[temp_x][temp_y] + 1);

		temp_x = lo.x;

		temp_y = lo.y;

		final_min_route += lo.route;

	}



	cout << final_min_route << endl;

	//system("pause");

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 1.6859884136637484x):
#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;

}