Go: ///
// File:  0558.go
// Author: ymiyamoto
//
// Created on Sun Mar  4 20:58:45 2018
//
package main

import (
	"fmt"
	"strconv"
	"strings"
)

type pos struct {
	x, y int
}

var H, W, N int
var graph [][]string

func wfs(p pos, index int) (int, pos) {
	var q []pos
	dists := make([][]int, H)
	for i := range dists {
		dists[i] = make([]int, W)
	}

	q = append(q, p)
	for len(q) > 0 {
		p := q[0]
		dist := dists[p.x][p.y]
		q = q[1:]

		for _, d := range []pos{{-1, 0}, {1, 0}, {0, -1}, {0, 1}} {
			x := p.x + d.x
			y := p.y + d.y
			if 0 <= x && x < H && 0 <= y && y < W && graph[x][y] != "X" && dists[x][y] == 0 {
				dists[x][y] = dist + 1
				q = append(q, pos{x, y})
			}
		}
	}

	for i := range graph {
		for j := range graph[i] {
			if graph[i][j] == strconv.Itoa(index) {
				return dists[i][j], pos{i, j}
			}
		}
	}

	panic("not found")
}

func main() {
	fmt.Scan(&H, &W, &N)

	var start pos

	graph = make([][]string, H)
	for i := range graph {
		var s string
		fmt.Scan(&s)
		graph[i] = strings.Split(s, "")
		for j := range graph[i] {
			if graph[i][j] == "S" {
				start.x = i
				start.y = j
			}
		}
	}

	count := 0
	for i := 1; i <= N; i++ {
		c, s := wfs(start, i)
		start = s
		count += c
	}

	fmt.Println(count)
}

C++: #define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <sstream>
#include <string>
#include <cstdio>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
#include <functional>
#include <cstring>
#include <tuple>
#include <utility>
#include <list>
#include <cmath>
#include <unordered_map>

using namespace std;

typedef long long LL;
typedef vector<int> Array;
typedef pair<int, int> P;

const int INF = 1 << 29;
const LL MOD = 100000;
#define rep(i,n) for(int i=0;i<(int)n;++i)
#define all(c) (c).begin(), (c).end()

struct edge{ int to, cost; edge(int t, int c) :to(t), cost(c){} };

int main()
{
	//while (cin >> n)
	stringstream ss;
	//ss << "result" << i + 1 << ".txt";
	//FILE* fp_out = freopen(ss.str().c_str(), "w", stdout);

	int h, w, n;
	while (cin >> h >> w >> n && h)
	{
		vector<vector<char>> stage(h, vector<char>(w));
		vector<P> cheese(n + 1);
		rep(i, h) rep(j, w)
		{
			char c; cin >> c;
			stage[i][j] = c;
			if (c == 'S') cheese[0] = P(i, j);
			if (1 <= c - '0' && c - '0' <= 9) cheese[c - '0'] = P(i, j);
		}

		int ans = 0;
		vector<int> dr = { -1, 0, 1, 0 };
		vector<int> dc = { 0, 1, 0, -1 };
		rep(i, n)
		{
			P from = cheese[i], to = cheese[i + 1];
			typedef pair<P, int> PI;
			queue<PI> que;
			vector<vector<bool>> visited(h, vector<bool>(w));
			que.emplace(from, 0);
			while (!que.empty())
			{
				PI pi = que.front(); que.pop();
				P p = pi.first; int len = pi.second;

				if (p == to)
				{
					ans += len;
					break;
				}

				rep(k, 4)
				{
					int nr = dr[k] + p.first, nc = dc[k] + p.second;
					if (nr < 0 || nr >= h || nc < 0 || nc >= w ||
						stage[nr][nc] == 'X' || visited[nr][nc]) continue;

					visited[nr][nc] = true;
					que.emplace(P(nr, nc), len + 1);
				}
			}
		}

		cout << ans << endl;
	}

	return 0;
}

C++: #include <bits/stdc++.h>

#define FOR(i, j, k) for(int i = j; i < k; ++i)
#define rep(i, j) FOR(i, 0, j)
#define INF (1 << 30)
#define mp make_pair

using namespace std;

typedef pair<int, int> P;

const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
int h, w, n;
int ans = 0;
int sx, sy, gx, gy;
char field[1010][1010];
bool went[1010][1010];

/*struct state{
	int x;
	int y;
	int count;
};*/

int bfs(char tmp) {
	cout << tmp << endl;
	queue< pair<int, P> > q;
	memset(went, false, sizeof(went));
	q.push(mp(0, mp(sx, sy)));

	while(!q.empty()) {
		pair<int, P> p = q.front();
		q.pop();
		//cout << p.first << " " << p.second.first << " " << p.second.second << endl;
		if((field[p.second.second][p.second.first]) == tmp){
			sx = p.second.first; sy = p.second.second;
			return p.first;
		}
		went[p.second.second][p.second.first] = true;
		rep(i, 4) {
			int nx = p.second.first + dx[i];
			int ny = p.second.second + dy[i];
			if(nx >= 0 && ny >= 0 && nx < w && ny < h && !went[ny][nx] && field[ny][nx] != 'X') {
				q.push(mp(p.first + 1, mp(nx, ny)));
			}
		}
	}
	return 0;
}

int main() {
	memset(field, 0, sizeof(field));
	cin >> h >> w >> n;
	rep(i, h) rep(j, w) {
		cin >> field[i][j];
		if(field[i][j] == 'S') sx = j, sy = i;
		if(field[i][j] == 'G') gx = j, gy = i;
	}
	/*rep(i, h) {
		rep(j, w) cout << field[i][j];
		cout << endl;
	}*/
	for(int i = 1; i <= n; ++i) {
		ans += bfs('0' + i);
	}
	cout << ans << endl;
	return 0;
}

C++: #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0558"

#include<bits/stdc++.h>
using namespace std;

#define call_from_test
#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
struct FastIO{
  FastIO(){
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
}fastio_beet;
//END CUT HERE
#ifndef call_from_test
signed main(){
  return 0;
}
#endif

#ifndef call_from_test
#include<bits/stdc++.h>
using namespace std;
#endif
//BEGIN CUT HERE
vector< vector<int> >
bfs(vector<string> &st,int sy,int sx,char wall,int dir){
  int h=st.size(),w=st.front().size();
  vector<vector<int> > dp(h,vector<int>(w,-1));
  using P = pair<int, int>;
  queue<P> qu;

  dp[sy][sx]=0;
  qu.emplace(sy,sx);

  int dy[]={1,-1,0,0,1,1,-1,-1};
  int dx[]={0,0,1,-1,1,-1,1,-1};
  auto in=[&](int y,int x){return 0<=y&&y<h&&0<=x&&x<w;};

  while(!qu.empty()){
    int y,x;
    tie(y,x)=qu.front();qu.pop();
    for(int k=0;k<dir;k++){
      int ny=y+dy[k],nx=x+dx[k];
      if(!in(ny,nx)||st[ny][nx]==wall) continue;
      if(~dp[ny][nx]) continue;
      dp[ny][nx]=dp[y][x]+1;
      qu.emplace(ny,nx);
    }
  }

  return dp;
}
//END CUT HERE
#ifndef call_from_test
//INSERT ABOVE HERE
signed ABC088_D(){
  int h,w;
  cin>>h>>w;
  vector<string> s(h);
  for(int i=0;i<h;i++) cin>>s[i];
  auto dp=bfs(s,0,0,'#',4);

  if(dp[h-1][w-1]<0){
    cout<<-1<<endl;
    return 0;
  }

  int cnt=0;
  for(int i=0;i<h;i++)
    for(int j=0;j<w;j++)
      cnt+=s[i][j]=='.';
  cout<<cnt-(dp[h-1][w-1]+1)<<endl;
  return 0;
}
/*
  verified on 2019/12/10
  https://atcoder.jp/contests/abc088/tasks/abc088_d
*/

signed main(){
  ABC088_D();
  return 0;
}
#endif

#undef call_from_test

signed main(){
  int h,w,n;
  cin>>h>>w>>n;

  vector<string> st(h);
  for(int i=0;i<h;i++) cin>>st[i];

  for(int i=0;i<h;i++)
    for(int j=0;j<w;j++)
      if(st[i][j]=='S') st[i][j]='0';

  vector<int> ys(n+1),xs(n+1);
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if(!isdigit(st[i][j])) continue;
      int p=st[i][j]-'0';
      ys[p]=i;xs[p]=j;
    }
  }

  int ans=0;
  for(int k=0;k<n;k++)
    ans+=bfs(st,ys[k],xs[k],'X',4)[ys[k+1]][xs[k+1]];

  cout<<ans<<endl;
  return 0;
}