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

#include <cstdio>

#include <cstring>

#include <cmath>

#include <climits>

#include <queue>

#include <iostream>





#define MAX_H 1100

#define MAX_W 1100





struct status

{

  int x;

  int y;

  int step;

  int n;

};





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

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



  

int H,W,N;

char maze[MAX_H][MAX_W];

int flag[MAX_H][MAX_W];

int xs,ys;

std::queue<status> Q;





int BFS();



int main(int argc, char* argv[])

{

  //freopen("in.txt","r",stdin);

  while(std::cin>>H>>W>>N)

    {



      std::cin.get();

      //std::cout << H << W << N << std::endl;



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

	std::cin.getline(maze[i],MAX_W);



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

      //	std::cout << maze[i] << std::endl;



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

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

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

	    {

	      xs = i;

	      ys = j;

	      break;

	    }

      memset(flag,0,sizeof(flag));

      std::cout<<BFS()<<std::endl;

      

    }

}





int BFS()

{



  while(Q.empty()==false)

    Q.pop();

  status start;

  start.x = xs;

  start.y = ys;

  start.step = 0;

  start.n = 1;



  Q.push(start);



  while(Q.empty() == false )

    {

      status tmp = Q.front();

      Q.pop();





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

	{

	  int cx = tmp.x + dx[i];

	  int cy = tmp.y + dy[i];

	  int cstep = tmp.step + 1;

	  int cn = tmp.n;



	  if(cx < 0 || cx >= W ) continue;

	  if(cy < 0 || cy >= H ) continue;

	  if(maze[cy][cx] == 'X' ) continue;



	  if( (maze[cy][cx] - '0') == tmp.n )

	    cn = tmp.n + 1;

	  else

	    cn = tmp.n;



	  if(cn == N+1)

	    return cstep;



	  

	  

	  if(flag[cy][cx] >= cn  ) continue;



	  flag[cy][cx] = cn;



	  status nstatus;

	  nstatus.x = cx;

	  nstatus.y = cy;

	  nstatus.n = cn;

	  nstatus.step = cstep;

	  Q.push(nstatus);

	  

	}

    }



  return -1;

  

}

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

}