#include <cctype>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

struct State {
  int step;
  int x;
  int y;

  State() {
    step = 0;
    x = 0;
    y = 0;
  }

  State(int step, int x, int y) : step(step), x(x), y(y) {}

  ~State() {}
};

const int MAX_N = 1000;
const int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
char board[MAX_N][MAX_N];
int W, H, N;
State pos[10];

void init();
void input();
void solve();
int bfs(State from, State to);
void findPossition();

int main() {
#ifdef LOCAL
  freopen("data.in", "r", stdin);
  freopen("data.out", "w", stdout);
#endif
  init();
  input();
  solve();
  return 0;
}

void init() {}

void input() {
  scanf("%d %d %d", &H, &W, &N);

  for (int i = 0; i < H; i++) {
    scanf("%s", board[i]);
  }
}

void solve() {
  int moves = 0;
  findPossition();

  for (int i = 0; i < N; i++) {
    moves += bfs(pos[i], pos[i + 1]);
  }

  printf("%d\\n", moves);
}

int bfs(State from, State to) {
  queue<State> que;
  bool visit[H][W];
  State cur = from;

  for (int i = 0; i < H; i++) {
    memset(visit[i], false, sizeof(visit[i]));
  }

  que.push(cur);
  visit[cur.x][cur.y] = true;

  while (!que.empty()) {
    cur = que.front();
    que.pop();

    for (int i = 0; i < 4; i++) {
      int x = cur.x + dir[i][0];
      int y = cur.y + dir[i][1];

      if (x < 0 || x >= H || y < 0 || y >= W || visit[x][y] ||
          'X' == board[x][y]) {
        continue;
      }

      que.push(State(cur.step + 1, x, y));
      visit[cur.x][cur.y] = true;

      if (x == to.x && y == to.y) {
        return cur.step + 1;
      }
    }
  }

  return 0;
}

void findPossition() {
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      int c = board[i][j];

      if ('S' == c) {
        pos[0] = State(0, i, j);
      }

      if (isdigit(c)) {
        pos[c - '0'] = State(0, i, j);
      }
    }
  }
}

#include <cstring>
#include <iostream>
#include <queue>
#include <stdlib.h>
#define MAX_NUM 1010
using namespace std;
int H, W, N;
bool flag[MAX_NUM][MAX_NUM] = {false}; //??是否已遍??
int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

class Node {
public:
  Node();
  Node(int x, int y, int step);
  ~Node();
  int x;
  int y;
  int step;
};

Node::Node() {}

Node::Node(int x, int y, int step) {
  this->x = x;
  this->y = y;
  this->step = step;
}

Node::~Node() {}

int BFS(char map[][MAX_NUM], int sx, int sy, int ex, int ey) {
  queue<Node> que; // 第一次出?Memory Limit Exceeded,一定不能使用new来?行?建
  Node node(sx, sy, 0);
  que.push(node);
  flag[sx][sy] = true; // 将遍?的?点?置?true

  while (!que.empty()) {
    Node cur = que.front();
    que.pop();

    if (cur.x == ex && cur.y == ey) {
      return cur.step;

    } else {
      for (int i = 0; i < 4; i++) {
        int k = cur.x + dir[i][0];
        int v = cur.y + dir[i][1];

        if (k >= 0 && k < H && v >= 0 && v < W && map[k][v] != 'X' &&
            !flag[k][v]) { // 将可到?并且尚未遍?的?点加入?列
          Node temp(k, v, cur.step + 1);
          que.push(temp);
          flag[k][v] = true;
        }
      }
    }
  }

  return -1;
}

int main() {
  int sx, sy, arr[10][2];
  char map[MAX_NUM][MAX_NUM];

  if (cin >> H >> W >> N && H && W) {
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        cin >> map[i][j];

        if (map[i][j] == 'S') {
          map[i][j] = '.';
          sx = i;
          sy = j;
        }

        if (isdigit(map[i][j])) {
          int index = map[i][j] - '0';
          arr[index][0] = i;
          arr[index][1] = j;
        }
      }
    }

    arr[0][0] = sx;
    arr[0][1] = sy;
    int res = 0;

    for (int i = 0; i + 1 <= N; i++) {
      memset(flag, false, sizeof(flag));
      res += BFS(map, arr[i][0], arr[i][1], arr[i + 1][0], arr[i + 1][1]);
    }

    cout << res << endl;
  }

  return 0;
}


#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
int h, w, n;
char map[1005][1005];
bool vis[1005][1005];
int dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0};
int cnt;
int f[1001 * 1001];

int BFS(int x, int y, int t) {
  int m;
  memset(vis, 0, sizeof vis);
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      if (map[i][j] == 'X') {
        vis[i][j] == 1;
      }
    }
  }
  queue<int> q;
  q.push(x * 1001 + y);
  int xxx, yyy;
  while (!q.empty()) {
    int xx = q.front() / 1001, yy = q.front() % 1001;
    q.pop();
    if (map[xx][yy] == '0' + t) {
      xxx = xx, yyy = yy;
      break;
    }
    for (int i = 0; i < 4; i++) {
      if (!vis[xx + dx[i]][yy + dy[i]]) {
        q.push(xx + dx[i] * 1001 + yy + dy[i]);
        vis[xx + dx[i]][yy + dy[i]] = 1;
        f[xx + dx[i] * 1001 + yy + dy[i]] = xx * 1001 + yy;
      }
    }
  }
  m = 1;
  int s = xxx * 1001 + yyy;
  while (f[s] != x * 1001 + y) {
    m++;
    s = f[s];
  }
  return m;
}

int bfs(int f, int t) {
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      if (map[i][j] - '0' == f) {
        // cout<<i<<j;
        return (BFS(i, j, t));
      }
    }
  }
}

int main() {
  cin >> h >> w >> n;
  cnt = 0;
  memset(map, 'X', sizeof map);
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      cin >> map[i][j];
    }
  }
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      if (map[i][j] == 'S') {
        map[i][j] = '0';
      }
    }
  }
  for (int i = 0; i < n; i++)
    cnt += bfs(i, i + 1);
  cout << cnt << endl;
}

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
int h, w, n;
char map[1005][1005];
bool vis[1005][1005];
int dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0};
int cnt;
int f[1001 * 1001];

int BFS(int x, int y, int t) {
  int m;
  memset(vis, 0, sizeof vis);
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      if (map[i][j] == 'X') {
        vis[i][j] == 1;
      }
    }
  }
  queue<int> q;
  q.push(x * 1001 + y);
  int xxx, yyy;
  while (!q.empty()) {
    int xx = q.front() / 1001, yy = q.front() % 1001;
    q.pop();
    if (map[xx][yy] == '0' + t) {
      xxx = xx, yyy = yy;
      break;
    }
    for (int i = 0; i < 4; i++) {
      if (!vis[xx + dx[i]][yy + dy[i]] && map[xx + dx[i]][yy + dy[i]] != 'X') {
        q.push((xx + dx[i]) * 1001 + yy + dy[i]);
        vis[xx + dx[i]][yy + dy[i]] = 1;
        f[(xx + dx[i]) * 1001 + yy + dy[i]] = xx * 1001 + yy;
      }
    }
  }
  m = 1;
  int s = xxx * 1001 + yyy;
  while (f[s] != x * 1001 + y) {
    m++;
    s = f[s];
  }
  return m;
}

int bfs(int f, int t)

{
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      if (map[i][j] - '0' == f) {
        // cout<<i<<j;
        return (BFS(i, j, t));
      }
    }
  }
}

int main() {
  cin >> h >> w >> n;
  cnt = 0;
  memset(map, 'X', sizeof map);
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      cin >> map[i][j];
    }
  }
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      if (map[i][j] == 'S') {
        map[i][j] = '0';
      }
    }
  }
  for (int i = 0; i < n; i++)
    cnt += bfs(i, i + 1);
  cout << cnt << endl;
}


#include <queue>
#include <stdio.h>
#include <string.h>
using namespace std;
int h, w, n, flag[1005][1005];
char map[1005][1005];
struct point {
  int x;
  int y;
  int t;
} chess[15];
int bfs(struct point be, struct point end) {
  point temp, emp;
  queue<point> q;
  q.push(be);
  memset(flag, 0, sizeof(flag));
  while (!q.empty()) {
    temp = q.front();
    q.pop();
    flag[temp.x][temp.y] = 1;
    for (int i = -1; i < 2; i++)
      for (int j = -1; j < 2; j++)
        if (i != j && i != -j) {
          emp.x = temp.x + i;
          emp.y = temp.y + j;
          emp.t = temp.t + 1;
          if (emp.x < 0 || emp.x >= h || emp.y < 0 || emp.y >= w ||
              flag[emp.x][emp.y] == 1)
            continue;
          if (map[emp.x][emp.y] == 'X')
            continue;
          if (emp.x == end.x && emp.y == end.y)
            return emp.t;
          q.push(emp);
        }
  }
  return 0;
}
int main() {
  while (scanf("%d%d%d", &h, &w, &n)) {
    int sum = 0;
    for (int i = 0; i < h; i++)
      scanf("%s", map[i]);
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++) {
        int temp = map[i][j] - '0';
        if (map[i][j] == 'S') {
          chess[0].x = i;
          chess[0].y = j;
          chess[0].t = 0;
        } else if (temp > 0 && temp < 10) {
          chess[temp].x = i;
          chess[temp].y = j;
          chess[temp].t = 0;
        }
      }
    for (int i = 0; i < n; i++)
      sum = sum + bfs(chess[i], chess[i + 1]);
    printf("%d\\n", sum);
  }
  return 0;
}

#include <cctype>
#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
const int DIRECTSIZE = 4;
struct _direct {
  int drow;
  int dcol;
} direct[DIRECTSIZE] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}};

const int N = 1000;
const int N2 = 10;
char grid[N][N], visited[N][N];
int h, w, n;
struct _factory {
  int row, col;
} factory[N2];

struct _node {
  int row, col, level;
};

int bfs(int n, char goal) {
  memset(visited, 0, sizeof(visited));

  _node start = {factory[n - 1].row, factory[n - 1].col, 0}, temp;

  visited[start.row][start.col] = 1;

  queue<_node> q;
  q.push(start);

  while (!q.empty()) {
    _node front = q.front();
    q.pop();

    for (int i = 0; i < DIRECTSIZE; i++) {
      int nextrow = front.row + direct[i].drow;
      int nextcol = front.col + direct[i].dcol;
      if (0 <= nextrow && nextrow < h && 0 <= nextcol && nextcol < w) {
        if (grid[nextrow][nextcol] == goal) {
          return front.level + 1;
        } else if (visited[nextrow][nextcol] == 0 &&
                   grid[nextrow][nextcol] != 'X') {
          visited[nextrow][nextcol] = 1;
          temp.row = nextrow;
          temp.col = nextcol;
          temp.level = front.level + 1;
          q.push(temp);
        }
      }
    }
  }

  return 0;
}

int main() {
  while (cin >> h >> w >> n) {
    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++) {
        cin >> grid[i][j];

        if (grid[i][j] == 'S') {
          factory[0].row = i;
          factory[0].col = j;
        } else if (isdigit(grid[i][j])) {
          factory[grid[i][j] - '0'].row = i;
          factory[grid[i][j] - '0'].col = j;
        }
      }

    int minstep = 0;
    char goal = '1';
    for (int i = 1; i <= n; i++) {
      minstep += bfs(i, goal);
      goal++;
    }

    cout << minstep << endl;
  }

  return 0;
}


// AOJ-0558
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

char map[1010][1010];
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
int vis[1010][1010];
int m, n, N;
struct node {
  int x, y, t;
};

node bfs(int x, int y, int k) {
  memset(vis, 0, sizeof(vis));
  queue<node> q;
  vis[x][y] = 1;
  node s;
  s.x = x;
  s.y = y;
  s.t = 0;
  q.push(s);
  while (!q.empty()) {
    node p = q.front();
    q.pop();
    vis[p.x][p.y] = 1;
    node e;
    if (map[p.x][p.y] == k + '0')
      return p;
    for (int i = 0; i < 4; i++) {
      e.x = p.x + dx[i];
      e.y = p.y + dy[i];
      if (map[e.x][e.y] == 'X' || vis[e.x][e.y] == 1)
        continue;
      e.t = p.t + 1;
      q.push(e);
    }
  }
  s.x = s.y = s.t = -1;
  return s;
}
void clear() {
  for (int i = 0; i < 1010; i++)
    for (int j = 0; j < 1010; j++)
      map[i][j] = 'X';
}
int main() {
  while (scanf("%d %d %d", &n, &m, &N) != EOF) {
    clear();
    node s;
    for (int i = 1; i <= n; i++) {
      getchar();
      for (int j = 1; j <= m; j++) {
        map[i][j] = getchar();
        if (map[i][j] == 'S') {
          map[i][j] = '.';
          s.x = i;
          s.y = j;
          s.t = 0;
        }
      }
    }
    int ans = 0;
    for (int i = 1; i <= N; i++) {
      s = bfs(s.x, s.y, i);
      map[s.x][s.y] = '.';
      ans += s.t;
    }
    printf("%d\\n", ans);
  }
  return 0;
}

// AOJ-0558
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

char map[1010][1010];
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
int vis[1010][1010];
int m, n, N;
struct node {
  int x, y, t;
};

node bfs(int x, int y, char k) {
  memset(vis, 0, sizeof(vis));
  queue<node> q;
  node s, e, p;
  s = {x, y, 0};
  q.push(s);
  vis[x][y] = 1;
  while (!q.empty()) {
    p = q.front();
    q.pop();
    if (map[p.x][p.y] == k)
      return p;
    for (int i = 0; i < 4; i++) {
      int nx = p.x + dx[i];
      int ny = p.y + dy[i];
      if (nx >= n || nx < 0 || ny >= m || ny < 0 || map[nx][ny] == 'X')
        continue;
      if (!vis[nx][ny]) {
        vis[nx][ny] = 1;
        e = {nx, ny, p.t + 1};
        q.push(e);
      }
    }
  }
}

int main() {
  while (~scanf("%d %d %d", &n, &m, &N)) {
    node s;
    for (int i = 0; i < n; i++) {
      scanf("%s", map[i]);
      for (int j = 0; j < m; j++) {
        if (map[i][j] == 'S') {
          s.x = i;
          s.y = j;
          s.t = 0;
        }
      }
    }
    int ans = 0;
    char c = '0';
    for (char i = 1; i <= N; i++) {
      node t = bfs(s.x, s.y, c + i);
      ans += t.t;
      s.x = t.x;
      s.y = t.y;
    }
    printf("%d\\n", ans);
  }
  return 0;
}


#include <iostream>
#include <queue>

using namespace std;

int w, h, N;
char grid[1000][1000];
int dist[1000][1000];

bool viable(int i, int j);
void wipe();

int main() {
  int x, y;
  int tx, ty;
  int choice[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
  queue<int> qx, qy;
  char target = '1';
  int res = 0;

  cin >> w >> h >> N;
  for (int i = 0; i < w; i++) {
    for (int j = 0; j < h; j++) {
      cin >> grid[i][j];
      if (grid[i][j] == 'S') {
        x = i;
        y = j;
      }
    }
  }

  while (target - '0' <= N) {
    wipe();
    queue<int>().swap(qx);
    qx.push(x);
    queue<int>().swap(qy);
    qy.push(y);
    dist[x][y] = 0;
    while (!qx.empty()) {
      x = qx.front();
      qx.pop();
      y = qy.front();
      qy.pop();
      if (grid[x][y] == target) {
        res += dist[x][y];
        break;
      }
      for (int i = 0; i < 4; i++) {
        tx = x + choice[i][0];
        ty = y + choice[i][1];
        if (viable(tx, ty)) {
          dist[tx][ty] = dist[x][y] + 1;
          qx.push(tx);
          qy.push(ty);
        }
      }
    }
    target += 1;
  }
  cout << res << endl;
  return 0;
}

void wipe() {
  for (int i = 0; i < w; i++) {
    for (int j = 0; j < h; j++) {
      dist[i][j] = -1;
    }
  }
}
bool viable(int i, int j) {
  return 0 <= i && i <= w && 0 <= j && j <= h && grid[i][j] != 'X' &&
         dist[i][j] == -1;
}

#include <algorithm>
#include <iostream>
#include <math.h>
#include <queue>
#include <stdio.h>
#include <string.h>
using namespace std;

typedef struct {
  int x, y;
} p;
char a[1005][1005];
p acm[11];
p s, g;
int b[1005][1005];
int H, W, N;
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
int bfs(p s, p g) {
  queue<p> q;
  p n;
  memset(b, -1, sizeof(b));
  q.push(s);
  b[s.x][s.y] = 0;
  while (!q.empty()) {
    p h;
    h = q.front();
    q.pop();
    if (h.x == g.x && h.y == g.y) {
      break;
    }
    for (int i = 0; i < 4; i++) {
      n.x = h.x + dx[i];
      n.y = h.y + dy[i];
      if (n.x >= 0 && n.x < H && n.y >= 0 && n.y < W && a[n.x][n.y] != 'X' &&
          b[n.x][n.y] == -1) {
        q.push(n);
        b[n.x][n.y] = b[h.x][h.y] + 1;
      }
    }
  }
  return b[g.x][g.y];
}
int main() {
  int i, j, t, step = 0;
  scanf("%d%d%d", &H, &W, &N);
  for (i = 0; i < H; i++) {
    scanf("%s", a[i]);
  }
  for (i = 0; i < H; i++)
    for (j = 0; j < W; j++) {
      if (a[i][j] >= '1' && a[i][j] <= '9') {
        t = a[i][j] - '0';
        acm[t].x = i;
        acm[t].y = j;
      } else if (a[i][j] == 'S') {
        s.x = i;
        s.y = j;
        a[i][j] = '.';
      }
    }
  for (i = 1; i <= N; i++) {
    g.x = acm[i].x;
    g.y = acm[i].y;
    step += bfs(s, g);
    s.x = g.x;
    s.y = g.y;
    a[g.x][g.y] = '.';
  }

  printf("%d\\n", step);
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
typedef pair<int, int> P;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
int H, W, n;
int res = 0;
char chee[105][105];
int d[105][105];
void bfs(int x, int y, char ch) {
  memset(d, INF, sizeof(d));
  d[x][y] = 0;
  queue<P> que;
  que.push(P(x, y));
  while (!que.empty()) {
    P p = que.front();
    que.pop();
    if (chee[p.first][p.second] == ch) {
      res += d[p.first][p.second];
      break;
    }
    for (int i = 0; i < 4; i++) {
      int nx = p.first + dx[i];
      int ny = p.second + dy[i];
      if (nx < 0 || nx >= H || ny < 0 || ny >= W)
        continue;
      if (d[nx][ny] == INF && chee[nx][ny] != 'X') {
        que.push(P(nx, ny));
        d[nx][ny] = d[p.first][p.second] + 1;
      }
    }
  }
}
void rec(char ch) {
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (chee[i][j] == ch) {
        bfs(i, j, ch + 1);
        return;
      }
    }
  }
}
int main() {
  cin >> H >> W >> n;
  for (int i = 0; i < H; i++)
    scanf("%s", chee[i]);
  res = 0;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (chee[i][j] == 'S') {

        bfs(i, j, '1');
        break;
      }
    }
  }
  for (int k = 1; k < n; k++) {
    rec(k + '0');
  }

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

  return 0;
}

#include <algorithm>
#include <cstdio>
#include <deque>
#include <iostream>

using namespace std;

typedef pair<int, int> P;

const int maxn = 1e3 + 5;
int inf = 500;

int h, w, n, sx, sy;
char s[maxn][maxn];
int book[maxn][maxn], goal[10];
int Next[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};

int judge(int row, int col) {
  if (row >= 0 && row < h && col >= 0 && col < w) {
    return 1;
  }
  return 0;
}

int bfs() {
  int res = 0;
  deque<P> q;
  for (int ci = 0; ci < n; ci++) {
    fill(book[0], book[0] + maxn * maxn, inf);
    q.push_back(P(sx, sy));
    book[sx][sy] = 0;
    while (!q.empty()) {
      int x = q.front().first;
      int y = q.front().second;
      q.pop_front();
      if ((int)s[x][y] == 49 + ci) {
        goal[ci] = book[x][y];
        sx = x;
        sy = y;
        break;
      }
      for (int i = 0; i < 4; i++) {
        int nx = x + Next[i][0];
        int ny = y + Next[i][1];
        if (judge(nx, ny) && s[nx][ny] != 'X' && book[nx][ny] == inf) {
          q.push_back(P(nx, ny));
          book[nx][ny] = book[x][y] + 1;
        }
      }
    }
    q.clear();
    res += goal[ci];
  }
  return res;
}

int main() {
  cin >> h >> w >> n;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cin >> s[i][j];
      if (s[i][j] == 'S') {
        sx = i;
        sy = j;
      }
    }
  }
  int goalnum = bfs();
  cout << goalnum << endl;
  return 0;
}


/*Lucky_Glass*/
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 1000;
const int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
int vis[MAXN + 5][MAXN + 5][10];
char maz[MAXN + 5][MAXN + 5];
int r, c, n, ans;
void DFS(int x, int y, int k, int dep) {
  if (vis[x][y][k] <= dep)
    return;
  vis[x][y][k] = dep;
  if (maz[x][y] == '0' + k) {
    if (k == n) {
      ans = min(ans, dep);
      return;
    }
    k++;
  }
  for (int i = 0; i < 4; i++) {
    int X = x + dir[i][0], Y = y + dir[i][1];
    if (X < 1 || X > r || Y < 1 || Y > c || maz[X][Y] == 'X')
      continue;
    DFS(X, Y, k, dep + 1);
  }
}
int main() {
  scanf("%d%d%d", &r, &c, &n);
  int begx, begy;
  for (int i = 1; i <= r; i++) {
    scanf("%s", maz[i] + 1);
    for (int j = 1; j <= c; j++)
      if (maz[i][j] == 'S')
        begx = i, begy = j;
  }
  ans = (1 << 29);
  memset(vis, 0x3f, sizeof vis);
  DFS(begx, begy, 1, 0);
  printf("%d\\n", ans);
  return 0;
}

/*Lucky_Glass*/
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 1000;
const int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
struct QUEUE {
  int x, y, dep;
  QUEUE() {}
  QUEUE(int _x, int _y, int _dep) {
    x = _x;
    y = _y;
    dep = _dep;
  }
};
int r, c, n;
int goal[10][2];
bool vis[MAXN + 5][MAXN + 5];
char maz[MAXN + 5][MAXN + 5];
int BFS(int *beg, int cnt) {
  memset(vis, false, sizeof vis);
  queue<QUEUE> que;
  que.push(QUEUE(beg[0], beg[1], 0));
  while (!que.empty()) {
    QUEUE pre = que.front();
    que.pop();
    for (int i = 0; i < 4; i++) {
      int X = pre.x + dir[i][0], Y = pre.y + dir[i][1], depth = pre.dep + 1;
      if (X < 1 || X > r || Y < 1 || Y > c || maz[X][Y] == 'X' || vis[X][Y])
        continue;
      vis[X][Y] = true;
      if (X == goal[cnt][0] && Y == goal[cnt][1])
        return depth;
      que.push(QUEUE(X, Y, depth));
    }
  }
  return -1;
}
int main() {
  scanf("%d%d%d", &r, &c, &n);
  for (int i = 1; i <= r; i++) {
    scanf("%s", maz[i] + 1);
    for (int j = 1; j <= c; j++) {
      if ('1' <= maz[i][j] && maz[i][j] <= '9')
        goal[maz[i][j] - '0'][0] = i, goal[maz[i][j] - '0'][1] = j,
                         maz[i][j] = '.';
      if (maz[i][j] == 'S')
        goal[0][0] = i, goal[0][1] = j, maz[i][j] = '.';
    }
  }
  int ans = 0;
  for (int i = 1; i <= n; i++)
    ans += BFS(goal[i - 1], i);
  printf("%d\\n", ans);
  return 0;
} //


#include <algorithm>
#include <bitset>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define pi acos(-1)
#define close                                                                  \\
  ios::sync_with_stdio(false);                                                 \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
#define open                                                                   \\
#ifndef ONLINE_JUDGEfreopen("in.txt", "r", stdin);                           \\
  freopen("out.txt", "w", stdout);                                             \\
#endif
using namespace std;
typedef long long ll;
const int MAX_N = 1000000 + 50;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-10;
const ll INF_ll = 0x7fffffffffffffff;
ll mod = 1e9 + 7;

/*
不要放弃

        Don't give up
*/

inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = 10 * x + ch - '0';
    ch = getchar();
  }
  return x * f;
}
inline void Out(int a) {
  if (a > 9)
    Out(a / 10);
  putchar(a % 10 + '0');
}

struct Node {
  int x, y, sum, pace;
  int v;
  // friend bool operator < (Node a,Node b){
  //	return a.pace > b.pace;
  // }
} now, nex;

int H, W, N;
char mapp[1001][1010];
int vis[1001][1010];
int sx, sy;
int dirx[4] = {-1, 1, 0, 0};
int diry[4] = {0, 0, -1, 1};

// priority_queue<Node> q;
queue<Node> q;

void bfs() {
  memset(vis, 0, sizeof(vis));
  now.x = sx;
  now.y = sy;
  now.pace = 0;
  now.sum = N;
  now.v = 1;
  vis[sx][sy] = 1;
  q.push(now);
  while (!q.empty()) {
    // now = q.top();
    now = q.front();
    q.pop();
    // cout<<now.x<<"@@@"<<now.y<<"@@@"<<now.sum<<"####"<<now.v<<endl;
    if (now.sum == 0) {
      printf("%d\\n", now.pace);
      break;
    }
    int x1, y1;
    for (int i = 0; i < 4; i++) {
      x1 = now.x + dirx[i];
      y1 = now.y + diry[i];
      if (x1 >= 1 && x1 <= H && y1 >= 1 && y1 <= W && mapp[x1][y1] != 'X') {
        if (mapp[x1][y1] == '.') {
          nex.x = x1;
          nex.y = y1;
          nex.pace = now.pace + 1;
          nex.sum = now.sum;
          nex.v = now.v;
          q.push(nex);
        } else {
          int num = mapp[x1][y1] - '0';
          nex.x = x1;
          nex.y = y1;
          nex.pace = now.pace + 1;
          if (now.v >= num && !vis[x1][y1]) {
            nex.sum = now.sum - 1;
            nex.v = now.v + 1;
            vis[x1][y1] = 1;
            q.push(nex);
          }
        }
      }
    }
  }
}

int main() {
  scanf("%d%d%d", &H, &W, &N);
  for (int i = 1; i <= H; i++) {
    getchar();
    for (int j = 1; j <= W; j++) {
      scanf("%c", &mapp[i][j]);
      if (mapp[i][j] == 'S') {
        sx = i;
        sy = j;
      }
    }
  }
  bfs();
  return 0;
}

/*
                ********
               ************
               ####....#.
             #..###.....##....
             ###.......######              ###            ###
                ...........               #...#          #...#
               ##*#######                 #.#.#          #.#.#
            ####*******######             #.#.#          #.#.#
           ...#***.****.*###....          #...#          #...#
           ....**********##.....           ###            ###
           ....****    *****....
             ####        ####
           ######        ######
##############################################################
#...#......#.##...#......#.##...#......#.##------------------#
###########################################------------------#
#..#....#....##..#....#....##..#....#....#####################
##########################################    #----------#
#.....#......##.....#......##.....#......#    #----------#
##########################################    #----------#
#.#..#....#..##.#..#....#..##.#..#....#..#    #----------#
##########################################    ############
*/

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
#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;
}


// TEMPLATE BEGIN
// #define ONLINE_JUDGE
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
// #include <ctime>
#include <algorithm>
#include <bitset>
#include <complex>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <vector>
using namespace std;

#define FOR(i, a, b) for (int(i) = (a); (i) <= (b); ++(i))
#define ROF(i, a, b) for (int(i) = (a); (i) >= (b); --(i))
#define FOREDGE(i, u, head, next)                                              \\
  for (int(i) = (head[(u)]); (i); (i) = (next[(i)]))
#define FORSTL(it, A)                                                          \\
  for (__typeof((A).begin()) it = (A).begin(); it != (A).end(); ++it)
#define CLR(a, b) memset((a), (b), sizeof(a))
#define CPY(a, b) memcpy((a), (b), sizeof(a))
#define DEBUG cerr << "debug" << endl
#define STAR cerr << "**********" << endl

#define RT return
#define BK break
#define CT continue
#define ALL(x) (x).begin(), (x).end()
#define HEAP priority_queue
#define st first
#define nd second
#define pf push_front
#define pb push_back
#define ppf pop_front
#define ppb pop_back
#define mp make_pair
#define re real()
#define im imag()

#define LIST0(A, n)                                                            \\
  {                                                                            \\
    FOR(i, 0, n - 1) printf("%d ", A[i]);                                      \\
    printf("\\n");                                                              \\
  }

#define LIST1(A, n)                                                            \\
  {                                                                            \\
    FOR(i, 1, n) printf("%d ", A[i]);                                          \\
    printf("\\n");                                                              \\
  }

#define SHOW0(A, n, m)                                                         \\
  {                                                                            \\
    FOR(i, 0, n - 1) {                                                         \\
      FOR(j, 0, m - 1)                                                         \\
      printf("%d ", A[i][j]);                                                  \\
      printf("\\n");                                                            \\
    }                                                                          \\
  }

#define SHOW1(A, n, m)                                                         \\
  {                                                                            \\
    FOR(i, 1, n) {                                                             \\
      FOR(j, 1, m)                                                             \\
      printf("%d ", A[i][j]);                                                  \\
      printf("\\n");                                                            \\
    }                                                                          \\
  }

typedef long long LL;
typedef double DB;
typedef long double LDB;
typedef unsigned int UINT;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef vector<DB> VB;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef map<int, int> MII;
typedef map<LL, LL> MLL;
typedef map<int, string> MIS;
typedef map<string, int> MSI;

const int INF(0x3f3f3f3f);
const LL LINF(0x3f3f3f3f3f3f3f3fLL);
const DB DINF(1e20);
const DB EPS(1e-12); // adjustable
const DB PI(acos(-1.0));

inline DB cot(DB x) { RT 1.0 / tan(x); }
inline DB sec(DB x) { RT 1.0 / cos(x); }
inline DB csc(DB x) { RT 1.0 / sin(x); }

template <class T> inline T max(T a, T b, T c) { RT max(max(a, b), c); }
template <class T> inline T max(T a, T b, T c, T d) {
  RT max(max(a, b), max(c, d));
}
template <class T> inline T min(T a, T b, T c) { RT min(min(a, b), c); }
template <class T> inline T min(T a, T b, T c, T d) {
  RT min(min(a, b), min(c, d));
}

template <class T> inline void Scan(T &x) { // int, LL
  char c;
  for (c = getchar(); c <= ' '; c = getchar())
    ;
  bool ngt(c == '-');
  if (ngt)
    c = getchar();
  for (x = 0; c > ' '; c = getchar())
    x = (x << 3) + (x << 1) + c - '0';
  if (ngt)
    x = -x;
}
template <class T> inline void Scan(T &x, T &y) { Scan(x), Scan(y); }
template <class T> inline void Scan(T &x, T &y, T &z) {
  Scan(x), Scan(y), Scan(z);
}
// TEMPLATE END

const int N = 1010;
const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, 1, 0, -1};

int h, w, n, d[N][N];
char G[N][N];
PII pos[10];
queue<PII> Q;

int BFS(PII s, PII t) {
  CLR(d, -1);
  Q.push(s);
  d[s.st][s.nd] = 0;
  while (!Q.empty()) {
    PII tmp = Q.front();
    Q.pop();
    FOR(i, 0, 3) {
      int nx = tmp.st + dx[i], ny = tmp.nd + dy[i];
      if (1 <= nx && nx <= h && 1 <= ny && ny <= w && G[nx][ny] != 'X' &&
          d[nx][ny] == -1) {
        Q.push(mp(nx, ny));
        d[nx][ny] = d[tmp.st][tmp.nd] + 1;
        if (mp(nx, ny) == t)
          BK;
      }
    }
  }
  RT d[t.st][t.nd];
}

void Main() {
  Scan(h, w, n);
  FOR(i, 1, h) {
    scanf("%s", G[i] + 1);
    FOR(j, 1, w) {
      if (isdigit(G[i][j]))
        pos[G[i][j] - '0'] = mp(i, j);
      else if (G[i][j] == 'S')
        pos[0] = mp(i, j);
    }
  }

  int ans = 0;
  FOR(i, 1, n) ans += BFS(pos[i - 1], pos[i]);
  printf("%d\\n", ans);
}

int main() {
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  Main();
  RT 0;
}
// imagasaikou!

#include <algorithm>
#include <iostream>
#include <queue>
const int INF = 100000000;
using namespace std;
typedef pair<int, int> P;
char a[1005][1005];
int N, M;
int sx, sy;
int gx, gy;
int d[1005][1005];
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
int bfs() {
  queue<P> que;
  for (int i = 0; i < N; i++)
    for (int j = 0; j < M; j++)
      d[i][j] = INF;
  que.push(P(sx, sy));
  d[sx][sy] = 0;
  while (que.size()) {
    P p = que.front();
    que.pop();
    if (p.first == gx && p.second == gy)
      break;
    for (int i = 0; i < 4; i++) {
      int nx = p.first + dx[i];
      int ny = p.second + dy[i];
      if (nx >= 0 && nx < N && ny >= 0 && ny < M && a[nx][ny] != 'X' &&
          d[nx][ny] == INF) {
        que.push(P(nx, ny));
        d[nx][ny] = d[p.first][p.second] + 1;
      }
    }
  }
  return d[gx][gy];
}
int main(void) {
  while (cin >> N >> M) {
    int n, sum = 0;
    cin >> n;
    for (int i = 0; i < N; i++)
      for (int j = 0; j < M; j++)
        cin >> a[i][j];
    for (int j = 0; j < N; j++)
      for (int k = 0; k < M; k++)
        if (a[j][k] == 'S') {
          sx = j;
          sy = k;
        }
    for (int j = 0; j < N; j++)
      for (int k = 0; k < M; k++)
        if (a[j][k] == '1') {
          gx = j;
          gy = k;
        }
    sum += bfs();
    for (int i = 0; i < n - 1; i++) {
      for (int j = 0; j < N; j++)
        for (int k = 0; k < M; k++) {
          if (a[j][k] == (char)(i + 49)) {
            sx = j;
            sy = k;
          }
          if (a[j][k] == (char)(i + 50)) {
            gx = j;
            gy = k;
          }
        }
      sum += bfs();
    }
    cout << sum << endl;
  }
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>

#define INF 0x7f7f7f7f
#define PI acos(-1.0)

#define L(x) (x) << 1
#define R(x) (x) << 1 | 1
#define lowbit(x) (x) & (-x)
#define Mid(l, r) (l + r) >> 1
#define Min(x, y) (x) < (y) ? (x) : (y)
#define Max(x, y) (x) < (y) ? (y) : (x)
#define iabs(x) (x) < 0 ? -(x) : (x)
#define CLR(arr, val) memset(arr, val, sizeof(arr))

using namespace std;

char map[1024][1024];
bool vis[1024][1024];
int cur, h, w;
int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};

struct node {
  int x, y, step;
} sta, now;

bool check(int x, int y) {
  if (x >= 0 && x < h && y >= 0 && y < w && !vis[x][y] && map[x][y] != 'X')
    return true;
  return false;
}

void bfs(node s) {
  memset(vis, 0, sizeof(vis));

  queue<node> que;
  que.push(s);
  while (!que.empty()) {
    now = que.front();
    que.pop();
    vis[now.x][now.y] = true;

    node next;
    next.step = now.step + 1;
    for (int i = 0; i < 4; i++) {
      next.x = now.x + dir[i][0];
      next.y = now.y + dir[i][1];

      if (check(next.x, next.y)) {
        if (map[next.x][next.y] == cur + '0') {
          map[next.x][next.y] = '.';
          sta = next;
          return;
        }
        que.push(next);
      }
    }
  }
}

int main() {
  int n;
  while (cin >> h >> w >> n) {
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> map[i][j];
        if (map[i][j] == 'S')
          sta.x = i, sta.y = j, map[i][j] = '.';
      }
    }
    sta.step = 0;
    for (cur = 1; cur <= n; cur++) {
      bfs(sta);
    }
    cout << sta.step << endl;
  }
  return 0;
}

/*
 *
 */
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <string>
#define CLR(ARR, NUM) memset(ARR, NUM, sizeof(ARR))
#define GETNUM(NUM) scanf("%d", &NUM)
#define faster_io() ios_base::sync_with_stdio(false)
using namespace std;
const int MAXN = 1010;
char map[MAXN][MAXN];
bool vis[10][MAXN][MAXN];
struct node {
  int x;
  int y;
  int deep;
  int n;
};
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};

int main() {
  CLR(vis, false);
  CLR(map, 'X');
  int h, w, n;
  cin >> h >> w >> n;
  getchar();
  int sx, sy;
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      map[i][j] = getchar();
      if (map[i][j] == 'S') {
        sx = i;
        sy = j;
      }
    }
    getchar();
  }
  node t;
  t.x = sx;
  t.y = sy;
  t.deep = 0;
  t.n = 0;
  queue<node> q;
  vis[0][sx][sy] = true;
  q.push(t);
  int ans = -1;
  while (!q.empty()) {
    node cur = q.front();
    if (cur.n == n) {
      ans = cur.deep;
      break;
    }
    q.pop();
    for (int i = 0; i < 4; i++) {
      int tx = cur.x + dx[i];
      int ty = cur.y + dy[i];
      if (map[tx][ty] != 'X' && !vis[cur.n][tx][ty]) {
        node t = cur;
        t.x = tx;
        t.y = ty;
        t.deep++;
        if (map[tx][ty] == '1' + t.n) {
          t.n++;
        }
        vis[t.n][tx][ty] = true;
        q.push(t);
      }
    }
  }
  cout << ans << endl;
  return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>

#define INF 0x7f7f7f7f
#define PI acos(-1.0)

#define L(x) (x) << 1
#define R(x) (x) << 1 | 1
#define lowbit(x) (x) & (-x)
#define Mid(l, r) (l + r) >> 1
#define Min(x, y) (x) < (y) ? (x) : (y)
#define Max(x, y) (x) < (y) ? (y) : (x)
#define iabs(x) (x) < 0 ? -(x) : (x)
#define CLR(arr, val) memset(arr, val, sizeof(arr))

using namespace std;

char map[1024][1024];
int cur, h, w;
bool vis[1024][1024];

struct node {
  int x, y, step;
} sta, now, nex;

bool check(int x, int y) {
  if (x >= 0 && x < h && y >= 0 && y < w && !vis[x][y] && map[x][y] != 'X')
    return true;
  return false;
}
int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};

node bfs(node s) {
  queue<node> q;
  q.push(s);
  while (!q.empty()) {
    now = q.front();
    q.pop();
    vis[now.x][now.y] = true;
    node next;
    next.step = now.step + 1;
    for (int i = 0; i < 4; i++) {
      next.x = now.x + dir[i][0];
      next.y = now.y + dir[i][1];

      if (check(next.x, next.y)) {
        if (map[next.x][next.y] == cur + '0') {
          map[next.x][next.y] = '.';
          return next;
        }
        q.push(next);
      }
    }
  }
}

int main() {
  int n, sx, sy;
  while (~scanf("%d%d%d", &h, &w, &n)) {
    //		memset(map, 0, sizeof(map));
    int num = 1;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> map[i][j];
        if (map[i][j] == 'S')
          sta.x = i, sta.y = j, map[i][j] = '.';
        else if (map[i][j] >= '0' && map[i][j] <= '9')
          num = max(num, map[i][j] - '0');
      }
    }
    //		cout << num << endl;
    sta.step = 0;
    for (cur = 1; cur <= num; cur++) {
      memset(vis, 0, sizeof(vis));
      nex = bfs(sta);
      sta = nex;
      //			cout << cur << ' ' << sta.step << endl;
    }
    cout << sta.step << endl;
  }
  return 0;
}

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>

#define INF 0x7f7f7f7f
#define PI acos(-1.0)

#define L(x) (x) << 1
#define R(x) (x) << 1 | 1
#define lowbit(x) (x) & (-x)
#define Mid(l, r) (l + r) >> 1
#define Min(x, y) (x) < (y) ? (x) : (y)
#define Max(x, y) (x) < (y) ? (y) : (x)
#define iabs(x) (x) < 0 ? -(x) : (x)
#define CLR(arr, val) memset(arr, val, sizeof(arr))

using namespace std;

char map[1024][1024];
bool vis[1024][1024];
int cur, h, w;
int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};

struct node {
  int x, y, step;
} sta, now;

bool check(int x, int y) {
  if (x >= 0 && x < h && y >= 0 && y < w && !vis[x][y] && map[x][y] != 'X')
    return true;
  return false;
}

void bfs(node s) {
  memset(vis, 0, sizeof(vis));

  queue<node> que;
  s.step = 0;
  que.push(s);
  node next;
  while (!que.empty()) {
    //		cout << "h\\n";
    s = que.front();
    //		cout << s.x << ' ' << s.y << ' ' << cur << endl;
    que.pop();
    if (map[s.x][s.y] == cur + '0') {
      sta = s;
      return;
      //			s.step;
    }

    //		cout << "a\\n";
    for (int i = 0; i < 4; i++) {
      //			cout << i << endl;
      next.x = s.x + dir[i][0];
      next.y = s.y + dir[i][1];
      next.step = s.step + 1;
      if (check(next.x, next.y)) {
        vis[next.x][next.y] = true;
        que.push(next);
      }
    }
  }
}

int main() {
  int n;
  while (cin >> h >> w >> n) {
    //		memset(map, 0, sizeof(map));
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> map[i][j];
        if (map[i][j] == 'S')
          sta.x = i, sta.y = j, map[i][j] = '.';
      }
    }
    sta.step = 0;
    int ans = 0;
    for (cur = 1; cur <= n; cur++) {
      bfs(sta);
      ans += sta.step;
      // cout << ans << endl;
    }
    cout << ans << endl;
  }
  return 0;
}


#include <queue>
#include <stdio.h>
using namespace std;
char sz[1001][1001];
int a, b, c;
struct node {
  int x, y;
};
typedef struct node Node;
queue<Node> Q;
int bfs(struct node T, int k) {
  int cnt = 0, flag = 1, Flag = 1;
  Node vb;
  while (!Q.empty()) {
    flag = Flag;
    Flag = 0;
    for (int i = 0; i < flag; i++) {
      for (int dr = -1; dr <= 1; dr++) {
        for (int dc = -1; dc <= 1; dc++) {
          if ((dc != 0 || dr != 0) && dr * dc == 0) {
            int xx = Q.front().x + dr;
            int yy = Q.front().y + dc;
            if (xx >= 0 && xx < a && yy >= 0 && yy < b) {
              if (sz[xx][yy] == '.' ||
                  sz[xx][yy] != k + '0' && sz[xx][yy] != 'X') {
                vb.x = xx;
                vb.y = yy;
                Q.push(vb);
                Flag++;
                sz[xx][yy] = k + '0';
              }
              if (xx == T.x && yy == T.y) {
                while (!Q.empty())
                  Q.pop();
                return cnt + 1;
              }
            }
          }
        }
      }
      Q.pop();
    }
    cnt++;
  }
  return cnt;
}
int main() {

  struct node st[10];
  while (scanf("%d%d%d", &a, &b, &c)) {
    getchar();
    for (int i = 0; i < a; i++) {
      for (int j = 0; j < b; j++) {
        scanf("%c", &sz[i][j]);
        if (sz[i][j] == 'S') {
          st[0].x = i;
          st[0].y = j;
          sz[i][j] = '0';
        }
        if (sz[i][j] > '0' && sz[i][j] <= '9') {
          st[sz[i][j] - '0'].x = i;
          st[sz[i][j] - '0'].y = j;
        }
      }
      getchar();
    }
    int count = 0;
    for (int i = 1; i <= c; i++) {
      Q.push(st[i - 1]);
      count += bfs(st[i], i - 1);
    }
    printf("%d\\n", count);
  }
}

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>

using namespace std;
struct as {
  int x, y;
} pos[10]; // 用来存??次的起点和?点
struct node {
  int x, y;
  int step;
};
bool vis[1010][1010];
char maze[1050][1050];
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
int H, W, N;

bool check(int x, int y) {
  if (x <= 0 || x > H)
    return 1;
  if (y <= 0 || y > W)
    return 1;
  if (vis[x][y])
    return 1;
  if (maze[x][y] == 'X')
    return 1;
  return 0;
}
int bfs(int m, int n) {
  memset(vis, 0, sizeof vis);
  int sx = pos[m].x, sy = pos[m].y;
  int gx = pos[n].x, gy = pos[n].y;
  // printf("%d %d\\n",sx,sy);
  // printf("%d %d\\n",gx,gy);
  queue<node> Q;
  node a, next;
  a.step = 0;
  a.x = sx, a.y = sy;
  Q.push(a);
  while (!Q.empty()) {
    a = Q.front();
    Q.pop();
    if (a.x == gx && a.y == gy)
      return a.step;
    for (int i = 0; i < 4; i++) {
      int nx = a.x + dx[i];
      int ny = a.y + dy[i];
      if (check(nx, ny))
        continue;
      else {
        vis[nx][ny] = 1;
        next.x = nx, next.y = ny, next.step = a.step + 1;
        Q.push(next);
      }
    }
  }
  return 999999;
}

int main() {
  // freopen("in.txt","r",stdin);
  while (cin >> H >> W >> N) {
    int sx, sy;
    for (int i = 1; i <= H; i++) {
      for (int j = 1; j <= W; j++) {
        cin >> maze[i][j];
        if (maze[i][j] >= '1' && maze[i][j] <= '9') {
          pos[maze[i][j] - '0'].x = i;
          pos[maze[i][j] - '0'].y = j;
        }
        if (maze[i][j] == 'S')
          sx = i, sy = j;
      }
    }

    pos[0].x = sx, pos[0].y = sy;
    int ans = 0;
    for (int i = 0; i < N; i++)
      ans += bfs(i, i + 1);
    cout << ans << endl;
  }
  return 0;
}

/*
入力例 2
4 5 2
.X..1
....X
.XX.S
.2.X.

出力例 2
12
*/


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <queue>
#include <string.h>

using namespace std;

int H, W;
int N;
char a[1005][1005];
bool b[1005][1005];
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};

struct Node {
  int x;
  int y;
  int deep;
};

struct Node Temp;

void bfs(int n) {
  queue<struct Node> t;
  t.push(Temp);
  while (t.size()) {
    Temp = t.front();
    t.pop();
    int x = Temp.x;
    int y = Temp.y;
    int d = Temp.deep;
    if (a[x][y] == n + 48) {
      break;
    }
    if (b[x][y])
      b[x][y] = false;

    for (int i = 0; i < 4; i++) {
      int x1 = x + dx[i];
      int y1 = y + dy[i];
      if (x1 >= 0 && x1 < W && y1 >= 0 && y1 < H && a[x1][y1] != 'X' &&
          b[x1][y1]) {
        Temp.x = x1;
        Temp.y = y1;
        Temp.deep = d + 1;
        t.push(Temp);
      }
    }
  }
}

int main() {
  while (cin >> H >> W >> N) {
    int i, j;
    int sx = 0, sy = 0;
    for (j = 0; j < H; j++)
      for (i = 0; i < W; i++) {
        cin >> a[i][j];
        if (a[i][j] == 'S') {
          sx = i;
          sy = j;
        }
      }
    Temp.x = sx;
    Temp.y = sy;
    Temp.deep = 0;

    for (int k = 1; k <= N; k++) {
      memset(b, true, sizeof(b));
      bfs(k);
    }
    cout << Temp.deep << endl;
  }
  return 0;
}


#include <algorithm>
#include <queue>
#include <stdio.h>
#include <string.h>
using namespace std;
char a[1001][1001];
int v[1001][1001], n, h, w, sx, sy, ans;
int dir[4][2] = {-1, 0, 1, 0, 0, 1, 0, -1};
char b[1001];
int s[1001][1001];
struct st {
  int x, y;
} st1, st2, fl, pp;
int check(st kk) {
  if (kk.x >= 0 && kk.x < h && kk.y >= 0 && kk.y < w)
    return 1;
  else
    return 0;
}
int bfs(char c) {
  queue<st> qq;
  qq.push(pp);
  memset(v, 0, sizeof(v));
  memset(s, 0, sizeof(s));
  while (!qq.empty()) {
    st1 = qq.front();
    qq.pop();
    if (a[st1.x][st1.y] == c) {
      pp = st1;
      // printf("+%d %d+ %d\\n",st1.x,st1.y,s[pp.x][pp.y]);
      break;
    }
    for (int i = 0; i < 4; i++) {
      st2.x = st1.x + dir[i][0];
      st2.y = st1.y + dir[i][1];
      if (check(st2) && v[st2.x][st2.y] == 0 && a[st2.x][st2.y] != 'X') {
        v[st2.x][st2.y] = 1;
        s[st2.x][st2.y] = s[st1.x][st1.y] + 1;
        // printf("-%d %d %d-\\n",st2.x,st2.y,s[st2.x][st2.y]);
        qq.push(st2);
      }
    }
  }
  return s[pp.x][pp.y];
  // printf("(%d %d %d %c)\\n",st1.x,st1.y,s[st1.x][st1.y],c);
}
int main() {
  int i, j, k, m, l;
  while (~scanf("%d %d %d", &h, &w, &n)) {
    getchar();
    memset(v, 0, sizeof(v));
    memset(s, 0, sizeof(s));
    for (i = 0; i < h; i++) {
      scanf("%s", &a[i]);
    }
    for (i = 0; i < n; i++) {
      b[i] = i + 1 + '0';
      // printf("%c\\n",b[i]);
    }
    for (i = 0; i < h; i++) {
      for (j = 0; j < w; j++) {
        if (a[i][j] == 'S') {
          pp.x = i;
          pp.y = j;
        }
      }
    }
    // printf("%d %d\\n",sx,sy);
    int sum = 0;
    for (i = 0; i < n; i++) {
      sum += bfs(b[i]);
      // printf("[%d]\\n",sum);
    }
    printf("%d\\n", sum);
  }
  return 0;
}


#include <iostream>
#include <queue>
#define min(x, y) ((x) < (y) ? (x) : (y))
#define INFI 65535

using namespace std;
typedef pair<int, int> P;

int Strength = 1;
char Maps[1010][1010];
int dist[1010][1010];
int H, W, N;
int hor[] = {1, 0, -1, 0};
int ver[] = {0, -1, 0, 1};
int ans;

void clear();
void show();
P bfs(int cheese, P n);

int main(void) {
  cin >> H >> W >> N;
  P s, e;
  for (int i = 0; i < H; i++)
    cin >> Maps[i];
  for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++)
      if (Maps[i][j] == 'S')
        s.first = i, s.second = j;

  for (int i = 1; i <= N; i++) {
    clear();
    s = bfs(i, s);
  }

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

P bfs(int cheese, P n) {
  queue<P> que;
  que.push(n);
  dist[n.first][n.second] = 0;

  P top;
  while (que.size()) {
    top = que.front();
    if (Maps[top.first][top.second] - '0' == cheese) {
      ans += dist[top.first][top.second];
      break;
    }

    que.pop();
    for (int i = 0; i < 4; i++) {
      int nv = top.first + ver[i], nh = top.second + hor[i];
      if (nv >= 0 && nv < H && nh >= 0 && nh < W && dist[nv][nh] == INFI &&
          Maps[nv][nh] != 'X') {
        que.push(P(nv, nh));
        dist[nv][nh] = min(dist[nv][nh], dist[top.first][top.second] + 1);
      }
    }
  }
  return top;
}

void clear() {
  for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++)
      dist[i][j] = INFI;
}

#include <iostream>
#include <queue>
#define min(x, y) ((x) < (y) ? (x) : (y))
#define INFI 100000000

using namespace std;
typedef pair<int, int> P;

int Strength = 1;
char Maps[1010][1010];
int dist[1010][1010];
int H, W, N;
int hor[] = {1, 0, -1, 0};
int ver[] = {0, -1, 0, 1};
int ans;

void clear();
void show();
P bfs(int cheese, P n);

int main(void) {
  cin >> H >> W >> N;
  P s, e;
  for (int i = 0; i < H; i++)
    cin >> Maps[i];
  for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++)
      if (Maps[i][j] == 'S')
        s.first = i, s.second = j;

  for (int i = 1; i <= N; i++) {
    clear();
    s = bfs(i, s);
  }

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

P bfs(int cheese, P n) {
  queue<P> que;
  que.push(n);
  dist[n.first][n.second] = 0;

  P top;
  while (que.size()) {
    top = que.front();
    if (Maps[top.first][top.second] - '0' == cheese) {
      ans += dist[top.first][top.second];
      break;
    }

    que.pop();
    for (int i = 0; i < 4; i++) {
      int nv = top.first + ver[i], nh = top.second + hor[i];
      if (nv >= 0 && nv < H && nh >= 0 && nh < W && dist[nv][nh] == INFI &&
          Maps[nv][nh] != 'X') {
        que.push(P(nv, nh));
        dist[nv][nh] = min(dist[nv][nh], dist[top.first][top.second] + 1);
      }
    }
  }
  return top;
}

void clear() {
  for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++)
      dist[i][j] = INFI;
}


#include <climits>
#include <iostream>
#include <queue>
#define REP(i, n) for (int i = 0; i < (n); i++)
using namespace std;

typedef pair<int, int> pii;

int main() {
  int H, W, N;
  const int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
  cin >> H >> W >> N;
  char map[H][W];
  int d[N][H][W], hp = 1, ans = 0;
  fill(d[0][0], d[N][0], INT_MAX);
  queue<pii> q;
  REP(i, H) {
    REP(j, W) {
      cin >> map[i][j];
      if (map[i][j] == 'S') {
        q.push({i, j});
        d[hp - 1][i][j] = 0;
      }
    }
  }
  while (1) {
    pii p = q.front();
    q.pop();
    if (hp == map[p.first][p.second] - '0') {
      ans += d[hp - 1][p.first][p.second];
      hp++;
      d[hp - 1][p.first][p.second] = 0;
      while (!q.empty())
        q.pop();
    }
    if (hp == N + 1) {
      cout << ans << endl;
      return 0;
    }
    REP(i, 4) {
      pii next_p = {p.first + dx[i], p.second + dy[i]};
      if (next_p.first < 0 || next_p.first >= H || next_p.second < 0 ||
          next_p.second >= W || map[next_p.first][next_p.second] == 'X')
        continue;
      if (d[hp - 1][next_p.first][next_p.second] >
          d[hp - 1][p.first][p.second] + 1) {
        d[hp - 1][next_p.first][next_p.second] =
            d[hp - 1][p.first][p.second] + 1;
        q.push(next_p);
      }
    }
  }
}

#include <climits>
#include <iostream>
#include <queue>
#define REP(i, n) for (int i = 0; i < (n); i++)
using namespace std;

typedef pair<int, int> pii;

int main() {
  int H, W, N;
  const int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
  cin >> H >> W >> N;
  char map[H][W];
  int d[H][W], hp = 1, ans = 0;
  fill(d[0], d[H], INT_MAX);
  queue<pii> q;
  REP(i, H) {
    REP(j, W) {
      cin >> map[i][j];
      if (map[i][j] == 'S') {
        q.push({i, j});
        d[i][j] = 0;
      }
    }
  }
  while (1) {
    pii p = q.front();
    q.pop();
    if (hp == map[p.first][p.second] - '0') {
      ans += d[p.first][p.second];
      hp++;
      fill(d[0], d[H], INT_MAX);
      d[p.first][p.second] = 0;
      while (!q.empty())
        q.pop();
    }
    if (hp == N + 1) {
      cout << ans << endl;
      return 0;
    }
    REP(i, 4) {
      pii next_p = {p.first + dx[i], p.second + dy[i]};
      if (next_p.first < 0 || next_p.first >= H || next_p.second < 0 ||
          next_p.second >= W || map[next_p.first][next_p.second] == 'X')
        continue;
      if (d[next_p.first][next_p.second] > d[p.first][p.second] + 1) {
        d[next_p.first][next_p.second] = d[p.first][p.second] + 1;
        q.push(next_p);
      }
    }
  }
}


#include <bits/stdc++.h>

using namespace std;

typedef struct xyt {
  int xx;
  int yy;
  int tt;
} xyt;

int H, W, N, minute = 0;
char area[1001][1001] = {};
bool areab[1001][1001] = {};
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};

void dfs(int x, int y) {
  int X, Y, time;
  int HP = 1;
  xyt now = {x, y, 0};
  queue<xyt> Q;
  Q.push(now);

  while (HP <= N) {
    X = Q.front().xx;
    Y = Q.front().yy;
    time = Q.front().tt;
    Q.pop();

    for (int i = 0; i <= 4; i++) {
      if (X + dx[i] <= 0 || Y + dy[i] <= 0 || X + dx[i] > W || Y + dy[i] > H)
        continue;

      if (areab[X + dx[i]][Y + dy[i]] == 0) {
        if (area[X + dx[i]][Y + dy[i]] == HP) {
          minute += time;
          while (!Q.empty()) {
            Q.pop();
          }
          now.xx = X + dx[i];
          now.yy = Y + dy[i];
          now.tt = 0;
          Q.push(now);
          HP++;
          break;
        } else {
          now.xx = X + dx[i];
          now.yy = Y + dy[i];
          now.tt = time + 1;
          Q.push(now);
        }
      }
    }
  }
  return;
}

int main() {
  cin >> H >> W >> N;
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      cin >> area[j][i];
      if (area[j][i] == 'X') {
        areab[j][i] = 1;
      }
    }
  }
  for (int i = 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      if (area[j][i] == 'S') {
        dfs(j, i);
      }
    }
  }
  cout << minute << endl;
  return 0;
}

#include <bits/stdc++.h>

using namespace std;

struct Node {
  int x, y, t;
  Node(int x_, int y_, int t_) {
    x = x_;
    y = y_;
    t = t_;
  }
};

int H, W, N;
int area[1001][1001];
bool memo[1001][1001];
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};

int bfs(int sx, int sy, int HP) {
  fill_n(*memo, 1001 * 1001, 0);
  queue<Node> Q;
  Q.push(Node(sx, sy, 0));
  int ret;

  while (!Q.empty()) {
    int X, Y, T;
    Node node = Q.front();
    X = node.x;
    Y = node.y;
    T = node.t;
    Q.pop();
    if (area[X][Y] == HP) {
      ret = T;
      break;
    }
    if (memo[X][Y] == 1)
      continue;
    memo[X][Y] = 1;
    for (int i = 0; i < 4; i++) {
      int nx = X + dx[i];
      int ny = Y + dy[i];
      if (nx < 0 || ny < 0 || nx >= W || ny >= H)
        continue;
      if (area[nx][ny] == -1)
        continue;
      Q.push(Node(nx, ny, T + 1));
    }
  }
  return ret;
}

int main() {
  fill_n(*area, 1001 * 1001, 0);
  int sx[10];
  int sy[10];
  char c;
  int ans = 0;
  cin >> H >> W >> N;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> c;
      if (c == 'X') {
        area[j][i] = -1;
      } else if (c == '.') {
        area[j][i] = 0;
      } else if (c == 'S') {
        area[j][i] = 0;
        sx[0] = j;
        sy[0] = i;
      } else {
        area[j][i] = c - '0';
        sx[c - '0'] = j;
        sy[c - '0'] = i;
      }
    }
  }
  for (int i = 0; i < N; i++) {
    ans += bfs(sx[i], sy[i], i + 1);
  }
  cout << ans << endl;
}

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc


#include <bits/stdc++.h>
#include <ctype.h>
#define int long long int
#define rep(a, b) for (int a = 0; a < b; a++)
#define INF 1000006
using namespace std;

int tx[] = {1, 0, -1, 0};
int ty[] = {0, 1, 0, -1};
int w, h, che, sx, sy;
char bases;
int base[1003][1003], base2[1003][1003], memo[1003][1003];

int chee(int x, int y, int n) {
  int ans = INF;
  if (memo[x][y] > 0 && (memo[x][y] != INF || base[x][y] < 0))
    return memo[x][y];
  else if (base[x][y] == n)
    return 0;
  else if (base[x][y] >= 0) {
    base[x][y] = -1;
    for (int i = 0; i < 4; i++) {
      if (x + tx[i] >= 0 && x + tx[i] < w && y + ty[i] >= 0 && y + ty[i] < h) {
        ans = min(ans, chee(x + tx[i], y + ty[i], n) + 1);
      }
    }
    base[x][y] = 0;
  }
  memo[x][y] = ans;
  return ans;
}
void sho(int b[1003][1003], int a[1003][1003]) {
  rep(i, 1003) {
    rep(j, 1003) { b[i][j] = a[i][j]; }
  }
}

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int zx[20], zy[20];
  cin >> h >> w >> che;
  rep(f, h) {
    rep(s, w) {
      cin >> bases;
      switch (bases) {
      case 'S':
        sx = s;
        sy = f;
      case '.':
        base[s][f] = 0;
        break;
      case 'X':
        base[s][f] = -1;
        break;
      default: {
        base[s][f] = bases - '0';
        zx[base[s][f]] = s;
        zy[base[s][f]] = f;
      }
      }
    }
  }
  sho(base2, base);
  int ans = 0;
  ans += chee(sx, sy, 1);
  for (int i = 2; i <= che; i++) {
    sho(base, base2);
    fill((int *)memo, (int *)(memo + 1003), 0);
    ans += chee(zx[i - 1], zy[i - 1], i);
  }
  cout << ans << endl;
  return 0;
}

#include <bits/stdc++.h>
#define int long long int

using namespace std;

const int INF = 100000000;

typedef pair<int, int> P;
char masu[1003][1003];
int W, H, K, ans = 0;
int sx[10], sy[10];
int gx[10], gy[10];

int d[1003][1003];

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

queue<P> que;

void sho() {
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      d[j][i] = INF;
    }
  }
  while (que.size()) {
    que.pop();
  }
}

int bfs() {
  for (int i = 0; i < K; i++) {
    sho();
    que.push(P(sx[i], sy[i]));
    d[sx[i]][sy[i]] = 0;
    while (que.size()) {
      P p = que.front();
      que.pop();
      if (p.first == gx[i + 1] && p.second == gy[i + 1])
        break;
      for (int j = 0; j < 4; j++) {
        int nx = p.first + dx[j], ny = p.second + dy[j];
        if (0 <= nx & nx < W && 0 <= ny && ny < H && masu[nx][ny] != 'X' &&
            d[nx][ny] == INF) {
          que.push(P(nx, ny));
          d[nx][ny] = d[p.first][p.second] + 1;
        }
      }
    }
    ans += d[gx[i + 1]][gy[i + 1]];
  }
  return ans;
}

signed main() {
  cin >> H >> W >> K;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> masu[j][i];
      int a = masu[j][i] - '0';
      if (isdigit(masu[j][i])) {
        gx[a] = j, gy[a] = i, sx[a] = j, sy[a] = i;
      } else if (masu[j][i] == 'S') {
        sx[0] = j, sy[0] = i;
      }
    }
  }
  int answer = bfs();
  cout << answer << endl;
  return 0;
}


#include <iostream>
#include <queue>
using namespace std;
int H, W, N, a, b, c, d, nh, nw;
int cost[1000][1000];
char t[1000][1000];
queue<int> qh;
queue<int> qw;
int th[4] = {0, -1, 0, 1};
int tw[4] = {1, 0, -1, 0};
int map[10][2];
int bfs(int tah, int taw) {
  int h, w, ans;
  while (!qw.empty()) {
    h = qh.front(), qh.pop();
    w = qw.front(), qw.pop();
    for (int i = 0; i < 4; i++) {
      nh = h + th[i];
      nw = w + tw[i];
      if (nh == tah && nw == taw) {
        ans = cost[h][w] + 1;
        return ans;
      } else if (cost[nh][nw] == -1) {
        qh.push(nh);
        qw.push(nw);
        cost[nh][nw] = cost[h][w] + 1;
      }
    }
  }
}
void syokika() {
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (cost[i][j] != -2)
        cost[i][j] = -1;
    }
  }
  while (!qh.empty()) {
    b = qh.front(), qh.pop();
    b = qw.front(), qw.pop();
  }
}
int main() {
  cin >> H >> W >> N;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> t[i][j];
      if (t[i][j] == 'S') {
        map[0][0] = i;
        map[0][1] = j;
      } else if (t[i][j] == 'X') {
        cost[i][j] = -2;
      } else if (t[i][j] != '.') {
        map[t[i][j] - '0'][0] = i;
        map[t[i][j] - '0'][1] = j;
      } else {
      }
    }
  }
  int sum = 0, a;
  for (int i = 0; i < N; i++) {
    syokika();

    qh.push(map[i][0]);
    qw.push(map[i][1]);
    cost[map[i][0]][map[i][1]] = 0;
    a = bfs(map[i + 1][0], map[i + 1][1]);
    sum += a;
  }
  cout << sum << endl;
  return 0;
}

#include <iostream>
#include <queue>
using namespace std;
int H, W, N, a, b, c, d, nh, nw;
int cost[1000][1000];
char t[1000][1000];
queue<int> qh;
queue<int> qw;
int th[4] = {0, -1, 0, 1};
int tw[4] = {1, 0, -1, 0};
int map[10][2];
int bfs(int tah, int taw) {
  int h, w, ans;
  while (!qw.empty()) {
    h = qh.front(), qh.pop();
    w = qw.front(), qw.pop();
    for (int i = 0; i < 4; i++) {
      nh = h + th[i];
      nw = w + tw[i];
      if (0 <= nh && nh < H && 0 <= nw && nw < W) {
        if (nh == tah && nw == taw) {
          ans = cost[h][w] + 1;
          return ans;
        } else if (cost[nh][nw] == -1) {
          qh.push(nh);
          qw.push(nw);
          cost[nh][nw] = cost[h][w] + 1;
        }
      }
    }
  }
}
void syokika() {
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (cost[i][j] != -2)
        cost[i][j] = -1;
    }
  }
  while (!qh.empty()) {
    qh.pop();
    qw.pop();
  }
}
int main() {
  cin >> H >> W >> N;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> t[i][j];
      if (t[i][j] == 'S') {
        map[0][0] = i;
        map[0][1] = j;
      } else if (t[i][j] == 'X') {
        cost[i][j] = -2;
      } else if (t[i][j] != '.') {
        map[t[i][j] - '0'][0] = i;
        map[t[i][j] - '0'][1] = j;
      } else {
      }
    }
  }
  int sum = 0, a;
  for (int i = 0; i < N; i++) {
    syokika();

    qh.push(map[i][0]);
    qw.push(map[i][1]);
    cost[map[i][0]][map[i][1]] = 0;
    a = bfs(map[i + 1][0], map[i + 1][1]);
    sum += a;
  }
  cout << sum << endl;
  return 0;
}


#include <iostream>
#include <queue>
using namespace std;

#define MAX_DATA 100000
struct status {
  int health;
  int x;
  int y;
  int minutes;
  int bx;
  int by;
};

queue<status> bfs;
// status checked[11][MAX_DATA];//
// int lastnum[11] = {0,0,0,0,0,0,0,0,0,0};
int maxhp = 0;
/// queue???push??????
///??¢??????????????\\??????????????¨?????????status?????´?????????????????????
bool PushToQueue(status a) {
  /*for (int i = 0;i < lastnum[a.health];i++) {
          if (checked[i].health == a.health && checked[a.health][i].x == a.x &&
  checked[a.health][i].y == a.y && checked[a.health][i].minutes == a.minutes){
                  cout << "health:" << a.health << "/" << i << "/" <<
  lastnum[a.health] << endl; return true;
          }
  }
  checked[a.health][lastnum[a.health]++] = a;*/
  if (a.health < maxhp)
    return false;
  bfs.push(a);
  if (a.health > maxhp)
    maxhp = a.health;

  return true;
}

int main() {
  int H, W, N;

  cin >> H >> W >> N;
  char data[H][W];

  for (int i = 0; i < H; i++) {
    cin >> data[i];
  }
  // Find 'S'
  for (int y = 0; y < H; y++) {
    for (int x = 0; x < W; x++) {
      if (data[y][x] == 'S') {
        bfs.push((struct status){1, x, y, 0, -100, -100});
        goto getout;
      }
    }
  }
getout:
  int result;
  for (;;) {
    if (bfs.empty())
      break;
    struct status popped = bfs.front();
    bfs.pop();
    // cout << popped.health << "/" << popped.x << "/" << popped.y << "/" <<
    // popped.minutes << "/" << popped.bx << "/" << popped.by << endl;
    if (popped.health == N + 1) {
      result = popped.minutes;
      break;
    } else {
      for (int x = -1; x < 2; x++) {
        for (int y = -1; y < 2; y++) {
          if (x != 0 && y != 0)
            continue;
          if (popped.x + x < 0 || popped.x + x >= W || popped.y + y < 0 ||
              popped.y + y >= H)
            continue;
          if (popped.x + x == popped.bx && popped.y + y == popped.by)
            continue;
          if (data[popped.y + y][popped.x + x] == 'S' ||
              data[popped.y + y][popped.x + x] == 'X')
            continue;
          else if (data[popped.y + y][popped.x + x] == '.') {
            PushToQueue((struct status){popped.health, popped.x + x,
                                        popped.y + y, popped.minutes + 1,
                                        popped.x, popped.y});
          } else {
            // cout << "*****************************factory" << endl;
            int factory = data[popped.y + y][popped.x + x] - 48;
            // cout << data[popped.y + y][popped.x + x]<< endl;
            if (factory == popped.health) {
              // eat
              PushToQueue((struct status){popped.health + 1, popped.x + x,
                                          popped.y + y, popped.minutes + 1,
                                          popped.x, popped.y});
            } else {
              // the mouse doesn't eat.
              PushToQueue((struct status){popped.health, popped.x + x,
                                          popped.y + y, popped.minutes + 1,
                                          popped.x, popped.y});
            }
          }
        }
      }
    }
  }
  cout << result << endl;
  return 0;
}

#include <iostream>
#include <queue>
using namespace std;

#define INF 999999999
#define MAX_X 1000
#define MAX_Y 1000
#define MAX_HEALTH 10
struct status {
  int health;
  int x;
  int y;
  int minutes;
};

queue<status> bfs;
bool checked[12][1010][1010]; // health,x,y
// int lastnum[11] = {0,0,0,0,0,0,0,0,0,0};
int maxhp = 0;
/// queue???push??????
///??¢??????????????\\??????????????¨?????????status?????´?????????????????????
bool PushToQueue(status a) {
  /*for (int i = 0;i < lastnum[a.health];i++) {
          if (checked[i].health == a.health && checked[a.health][i].x == a.x &&
  checked[a.health][i].y == a.y && checked[a.health][i].minutes == a.minutes){
                  cout << "health:" << a.health << "/" << i << "/" <<
  lastnum[a.health] << endl; return true;
          }
  }
  checked[a.health][lastnum[a.health]++] = a;*/
  if (checked[a.health][a.x][a.y] == true)
    return false;
  if (a.health < maxhp)
    return false;
  bfs.push(a);
  if (a.health > maxhp) {
    maxhp = a.health;
    // cout << "maxhp has changed to " << maxhp << endl;
  }
  checked[a.health][a.x][a.y] = true;
  return true;
}

int main() {
  for (int a = 0; a < 11; a++) {
    for (int b = 0; b < 1000; b++) {
      for (int c = 0; c < 1000; c++) {
        checked[a][b][c] = false;
      }
    }
  }

  int H, W, N;

  cin >> H >> W >> N;
  char data[H][W];

  for (int i = 0; i < H; i++) {
    cin >> data[i];
  }
  // cout << "A" << endl;
  // Find 'S'
  for (int y = 0; y < H; y++) {
    for (int x = 0; x < W; x++) {
      if (data[y][x] == 'S') {
        bfs.push((struct status){1, x, y, 0});
        goto getout;
      }
    }
  }

getout:
  int result = INF;
  for (;;) {
    if (bfs.empty())
      break;
    struct status popped = bfs.front();
    bfs.pop();
    // cout << popped.health << "/" << popped.x << "/" << popped.y << "/" <<
    // popped.minutes << "/" << endl;
    if (popped.health == N + 1) {
      if (popped.minutes < result) {
        result = popped.minutes;
      }
    } else {
      for (int x = -1; x < 2; x++) {
        for (int y = -1; y < 2; y++) {
          if (x != 0 && y != 0)
            continue;
          if (popped.x + x < 0 || popped.x + x >= W || popped.y + y < 0 ||
              popped.y + y >= H)
            continue;
          if (data[popped.y + y][popped.x + x] == 'X')
            continue;
          else if (data[popped.y + y][popped.x + x] == '.') {
            PushToQueue((struct status){popped.health, popped.x + x,
                                        popped.y + y, popped.minutes + 1});
          } else {
            // cout << "*****************************factory" << endl;
            int factory = data[popped.y + y][popped.x + x] - 48;
            // cout << data[popped.y + y][popped.x + x]<< endl;
            if (factory == popped.health) {
              // eat
              PushToQueue((struct status){popped.health + 1, popped.x + x,
                                          popped.y + y, popped.minutes + 1});
            } else {
              // the mouse doesn't eat.
              PushToQueue((struct status){popped.health, popped.x + x,
                                          popped.y + y, popped.minutes + 1});
            }
          }
        }
      }
    }
  }
  cout << result << endl;
  return 0;
}


#include <iostream>
#include <queue>
#include <vector>
using namespace std;

int dr[] = {1, -1, 0, 0};
int dc[] = {0, 0, 1, -1};

struct Info {
  int r;
  int c;
  int cost;
  Info(int r, int c, int cost) : r(r), c(c), cost(cost) {}
};

int bfs(vector<string> map, pair<int, int> start, char target) {
  int res = 0;
  queue<Info> que;
  que.push(Info(start.first, start.second, 0));
  while (!que.empty()) {
    Info info = que.front();
    que.pop();
    if (map[info.r][info.c] == target) {
      res = info.cost;
      break;
    }
    map[info.r][info.c] = 'o';
    for (int i = 0; i < 4; i++) {
      int nr = info.r + dr[i];
      int nc = info.c + dc[i];
      if (nr >= 0 && nr < map.size() && nc >= 0 && nc < map[nr].size() &&
          map[nr][nc] != 'X' && map[nr][nc] != 'o') {
        Info nextInfo = Info(nr, nc, info.cost + 1);
        que.push(nextInfo);
      }
    }
  }

  return res;
}

int getCost(vector<string> &map, int next, int N) {
  char from = 'S';
  if (next > 1)
    from = char(next - 1 + '0');
  char to = char(next + '0');
  pair<int, int> start;
  for (int i = 0; i < map.size(); i++) {
    for (int j = 0; j < map[i].size(); j++) {
      if (map[i][j] == from) {
        start = pair<int, int>(i, j);
        int c = bfs(map, start, to);

        return c;
      }
    }
  }
  return 0;
}

int solve(vector<string> &map, int N) {
  int cost = 0;
  for (int k = 1; k <= N; k++) {
    cost += getCost(map, k, N);
  }
  return cost;
}

int main() {
  int H, W, N;
  cin >> H >> W >> N;
  vector<string> map;
  for (int i = 0; i < H; i++) {
    string s;
    cin >> s;
    map.push_back(s);
  }
  int answer = solve(map, N);
  cout << answer << endl;
}

#include <iostream>
#include <queue>
#include <vector>
using namespace std;

// typedef
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;

// container util
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())
#define EACH(i, c)                                                             \\
  for (typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort((c).begin(), (c).end())
// repetition
//------------------------------------------
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)

int dr[] = {1, -1, 0, 0};
int dc[] = {0, 0, 1, -1};

int bfs(vector<string> &map, PII start, PII goal) {
  int res = 0;
  VVI costs(map.size(), VI(map[0].size(), -1));
  costs[start.first][start.second] = 0;
  queue<PII> q;
  q.push(start);
  int cost = 0;
  while (!q.empty()) {
    PII p = q.front();
    q.pop();
    if (p == goal) {
      cost = costs[p.first][p.second];
      break;
    }
    for (int i = 0; i < 4; i++) {
      int nr = p.first + dr[i];
      int nc = p.second + dc[i];
      if (nr >= 0 && nr < map.size() && nc >= 0 && nc < map[nr].size() &&
          map[nr][nc] != 'X' && costs[nr][nc] == -1) {
        costs[nr][nc] = costs[p.first][p.second] + 1;
        q.push(PII(nr, nc));
      }
    }
  }
  /*
  REP(i, costs.size()) {
      REP(j, costs[i].size()) {
          if (
          cerr << (costs[i][j] == -1 ? '?' : costs[i][j]) << " ";
      }
      cerr << endl;
  }
  */
  return cost;
}

int getCost(vector<string> &map, int next) {
  char from = 'S';
  if (next > 1)
    from = char(next - 1 + '0');
  char to = char(next + '0');

  PII start, goal;
  for (int i = 0; i < map.size(); i++) {
    for (int j = 0; j < map[i].size(); j++) {
      if (map[i][j] == from)
        start = PII(i, j);
      if (map[i][j] == to)
        goal = PII(i, j);
    }
  }
  return bfs(map, start, goal);
}

int solve(vector<string> &map, int N) {
  int cost = 0;
  for (int i = 1; i <= N; i++) {
    cost += getCost(map, i);
  }
  return cost;
}

int main() {
  int H, W, N;
  cin >> H >> W >> N;
  vector<string> map;
  for (int i = 0; i < H; i++) {
    string s;
    cin >> s;
    map.push_back(s);
  }
  int answer = solve(map, N);
  cout << answer << endl;
}


#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;

int main() {
  int h, w, n;
  int x[10], y[10];
  string map[1000];
  int dmap[1000][1000];
  queue<int> qx, qy;
  int dis;

  cin >> h >> w >> n;

  for (int i = 0; i < h; i++)
    cin >> map[i];

  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (map[i][j] == 'S') {
        x[0] = j;
        y[0] = i;
        break;
      }
      if (map[i][j] != 'X' && map[i][j] != '.') {
        x[map[i][j] - '0'] = j;
        y[map[i][j] - '0'] = i;
      }
    }
  }

  dis = 0;
  for (int i = 0; i < n; i++) {
    while (!qx.empty())
      qx.pop();
    while (!qy.empty())
      qy.pop();
    for (int k = 0; k < h; k++) {
      for (int j = 0; j < w; j++) {
        dmap[k][j] = 10000000;
      }
    }
    dmap[y[i]][x[i]] = 0;
    qx.push(x[i]);
    qy.push(y[i]);

    while (!qx.empty()) {
      if (qx.front() > 0 && map[qy.front()][qx.front() - 1] != 'X' &&
          dmap[qy.front()][qx.front() - 1] > dmap[qy.front()][qx.front()] + 1) {
        dmap[qy.front()][qx.front() - 1] = dmap[qy.front()][qx.front()] + 1;
        qx.push(qx.front() - 1);
        qy.push(qy.front());
      }
      if (qy.front() > 0 && map[qy.front() - 1][qx.front()] != 'X' &&
          dmap[qy.front() - 1][qx.front()] > dmap[qy.front()][qx.front()] + 1) {
        dmap[qy.front() - 1][qx.front()] = dmap[qy.front()][qx.front()] + 1;
        qx.push(qx.front());
        qy.push(qy.front() - 1);
      }
      if (qx.front() < w - 1 && map[qy.front()][qx.front() + 1] != 'X' &&
          dmap[qy.front()][qx.front() + 1] > dmap[qy.front()][qx.front()] + 1) {
        dmap[qy.front()][qx.front() + 1] = dmap[qy.front()][qx.front()] + 1;
        qx.push(qx.front() + 1);
        qy.push(qy.front());
      }
      if (qy.front() < h - 1 && map[qy.front() + 1][qx.front()] != 'X' &&
          dmap[qy.front() + 1][qx.front()] > dmap[qy.front()][qx.front()] + 1) {
        dmap[qy.front() + 1][qx.front()] = dmap[qy.front()][qx.front()] + 1;
        qx.push(qx.front());
        qy.push(qy.front() + 1);
      }
      qx.pop();
      qy.pop();
    }

    dis += dmap[y[i + 1]][x[i + 1]];
  }

  cout << dis << endl;
}

#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;

int main() {
  int h, w, n;
  int x[10], y[10];
  string map[1000];
  int dmap[1000][1000];
  queue<int> qx, qy;
  int dis;

  cin >> h >> w >> n;

  for (int i = 0; i < h; i++)
    cin >> map[i];

  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (map[i][j] == 'S') {
        x[0] = j;
        y[0] = i;
      }
      if (map[i][j] != 'X' && map[i][j] != '.') {
        x[map[i][j] - '0'] = j;
        y[map[i][j] - '0'] = i;
      }
    }
  }

  dis = 0;
  for (int i = 0; i < n; i++) {
    while (!qx.empty())
      qx.pop();
    while (!qy.empty())
      qy.pop();
    for (int k = 0; k < h; k++) {
      for (int j = 0; j < w; j++) {
        dmap[k][j] = 10000000;
      }
    }
    dmap[y[i]][x[i]] = 0;
    qx.push(x[i]);
    qy.push(y[i]);

    while (!qx.empty()) {
      if (qx.front() > 0 && map[qy.front()][qx.front() - 1] != 'X' &&
          dmap[qy.front()][qx.front() - 1] > dmap[qy.front()][qx.front()] + 1) {
        dmap[qy.front()][qx.front() - 1] = dmap[qy.front()][qx.front()] + 1;
        qx.push(qx.front() - 1);
        qy.push(qy.front());
      }
      if (qy.front() > 0 && map[qy.front() - 1][qx.front()] != 'X' &&
          dmap[qy.front() - 1][qx.front()] > dmap[qy.front()][qx.front()] + 1) {
        dmap[qy.front() - 1][qx.front()] = dmap[qy.front()][qx.front()] + 1;
        qx.push(qx.front());
        qy.push(qy.front() - 1);
      }
      if (qx.front() < w - 1 && map[qy.front()][qx.front() + 1] != 'X' &&
          dmap[qy.front()][qx.front() + 1] > dmap[qy.front()][qx.front()] + 1) {
        dmap[qy.front()][qx.front() + 1] = dmap[qy.front()][qx.front()] + 1;
        qx.push(qx.front() + 1);
        qy.push(qy.front());
      }
      if (qy.front() < h - 1 && map[qy.front() + 1][qx.front()] != 'X' &&
          dmap[qy.front() + 1][qx.front()] > dmap[qy.front()][qx.front()] + 1) {
        dmap[qy.front() + 1][qx.front()] = dmap[qy.front()][qx.front()] + 1;
        qx.push(qx.front());
        qy.push(qy.front() + 1);
      }
      qx.pop();
      qy.pop();
    }

    dis += dmap[y[i + 1]][x[i + 1]];
  }

  cout << dis << endl;
}


#include <cstdio>
#include <queue>
#include <utility>

using namespace std;

typedef pair<int, int> P;
typedef pair<P, P> RAT;

char map[1005][1005];
int H, W, N;
int sx, sy;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

int main() {
  queue<RAT> que;
  int tx, ty;
  scanf("%d %d %d", &H, &W, &N);
  for (int i = 0; i < H; i++) {
    scanf("%s", map[i]);
    for (int j = 0; j < W; j++)
      if (map[i][j] == 'S') {
        sx = i;
        sy = j;
      }
  }

  que.push(RAT(P(sx, sy), P(1, 0)));
  for (;;) {
    RAT rat = que.front();
    que.pop();
    if (rat.second.first == N + 1) {
      printf("%d\\n", rat.second.second);
      break;
    }
    for (int i = 0; i < 4; i++) {
      tx = rat.first.first + dx[i];
      ty = rat.first.second + dy[i];
      if (tx >= 0 && tx < H && ty >= 0 && ty < W && map[tx][ty] != 'X') {
        if (rat.second.first == map[tx][ty] - 48)
          que.push(
              RAT(P(tx, ty), P(rat.second.first + 1, rat.second.second + 1)));
        else
          que.push(RAT(P(tx, ty), P(rat.second.first, rat.second.second + 1)));
      }
    }
  }
  return 0;
}

#include <cstdio>
#include <queue>
#include <utility>

using namespace std;

typedef pair<int, int> P;
typedef pair<P, P> RAT;

const int INF = 100000000;

char map[1005][1005];
int flag[1005][1005];
int H, W, N;
int cheese;
int sx, sy;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

int main() {
  queue<RAT> que;
  int tx, ty;
  scanf("%d %d %d", &H, &W, &N);
  for (int i = 0; i < H; i++) {
    scanf("%s", map[i]);
    for (int j = 0; j < W; j++)
      if (map[i][j] == 'S') {
        sx = i;
        sy = j;
      }
  }

  que.push(RAT(P(sx, sy), P(1, 0)));
  cheese = 1;
  for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++)
      flag[i][j] = INF;
  for (;;) {
    RAT rat = que.front();
    que.pop();
    if (rat.second.first == N + 1) {
      printf("%d\\n", rat.second.second);
      break;
    }
    if (cheese > rat.second.first)
      continue;
    if (cheese < rat.second.first) {
      cheese = rat.second.first;
      for (int i = 0; i < H; i++)
        for (int j = 0; j < W; j++)
          flag[i][j] = INF;
    }
    for (int i = 0; i < 4; i++) {
      tx = rat.first.first + dx[i];
      ty = rat.first.second + dy[i];
      if (tx >= 0 && tx < H && ty >= 0 && ty < W && map[tx][ty] != 'X' &&
          flag[tx][ty] != 0) {
        if (rat.second.first == map[tx][ty] - 48) {
          que.push(
              RAT(P(tx, ty), P(rat.second.first + 1, rat.second.second + 1)));
          flag[tx][ty] = 0;
        } else {
          que.push(RAT(P(tx, ty), P(rat.second.first, rat.second.second + 1)));
          flag[tx][ty] = 0;
        }
      }
    }
  }
  return 0;
}


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

typedef pair<int, int> P;
#define FOR(i, a, b) for (int i = (a); i < (int)(b); i++)
#define rep(i, n) FOR(i, 0, n)
#define F first
#define S second

const int M = 1024;
const int INF = 114514;
int h, w, n;
char f[M][M];
int d[M][M];
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
vector<P> cheese(12);

void init() {
  rep(y, M) rep(x, M) f[y][x] = '$';
  cheese.clear();
}

bool ng(int x, int y) { return (x < 0 or w <= x or y < 0 or h <= y); }

int bfs(P s, P g) {
  int gx = g.F, gy = g.S;
  queue<P> Q;
  rep(y, M) rep(x, M) d[y][x] = INF;
  Q.push(s);
  d[s.S][s.F] = 0;

  while (Q.size()) {
    P p = Q.front();
    Q.pop();
    if (p.F == gx and p.S == gy)
      break;

    rep(i, 4) {
      int nx = p.F + dx[i], ny = p.S + dy[i];
      if (ng(nx, ny) or f[ny][nx] == 'X' or d[ny][nx] < INF)
        continue;
      d[ny][nx] = d[p.S][p.F] + 1;
      Q.push(P(nx, ny));
    }
  }

  return d[gy][gx];
}

int main() {
  while (cin >> h >> w >> n) {
    init();
    rep(y, h) rep(x, w) {
      cin >> f[y][x];
      char c = f[y][x];
      if (c != '.' and c != 'S' and c != 'X')
        cheese[c - '0'] = make_pair(x, y);
      if (c == 'S')
        cheese[0] = make_pair(x, y);
    }

    int ans = 0;
    rep(i, n) ans += bfs(cheese[i], cheese[i + 1]);
    cout << ans << endl;
  }

  return 0;
}

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

typedef pair<int, int> P;
#define FOR(i, a, b) for (int i = (a); i < (int)(b); i++)
#define rep(i, n) FOR(i, 0, n)
#define F first
#define S second

const int M = 1024;
const int INF = 114514810;
int h, w, n;
char f[M][M];
int d[M][M];
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
vector<P> cheese(12);

void init() {
  rep(y, M) rep(x, M) f[y][x] = '$';
  cheese.clear();
}

bool ng(int x, int y) { return (x < 0 or w <= x or y < 0 or h <= y); }

int bfs(P s, P g) {
  int gx = g.F, gy = g.S;
  queue<P> Q;
  rep(y, M) rep(x, M) d[y][x] = INF;
  Q.push(s);
  d[s.S][s.F] = 0;

  while (Q.size()) {
    P p = Q.front();
    Q.pop();
    if (p.F == gx and p.S == gy)
      break;

    rep(i, 4) {
      int nx = p.F + dx[i], ny = p.S + dy[i];
      if (ng(nx, ny) or f[ny][nx] == 'X' or d[ny][nx] < INF)
        continue;
      d[ny][nx] = d[p.S][p.F] + 1;
      Q.push(P(nx, ny));
    }
  }

  return d[gy][gx];
}

int main() {
  while (cin >> h >> w >> n) {
    init();
    rep(y, h) rep(x, w) {
      cin >> f[y][x];
      char c = f[y][x];
      if (c != '.' and c != 'S' and c != 'X')
        cheese[c - '0'] = make_pair(x, y);
      if (c == 'S')
        cheese[0] = make_pair(x, y);
    }

    int ans = 0;
    rep(i, n) ans += bfs(cheese[i], cheese[i + 1]);
    cout << ans << endl;
  }

  return 0;
}


#include <iostream>
#include <queue>
#include <vector>
using namespace std;

int h, w, n;
vector<vector<bool>> mp;
vector<pair<int, int>> f;

int bfs(pair<int, int> start, pair<int, int> end) {
  queue<pair<int, pair<int, int>>> q;
  q.push(make_pair(0, start));
  while (q.size()) {
    int c = q.front().first;
    pair<int, int> p = q.front().second;
    q.pop();
    if (p == end)
      return c;
    int x = p.first;
    int y = p.second;
    for (int dx = -1; dx <= 1; dx++) {
      for (int dy = -1; dy <= 1; dy++) {
        if ((!!dx ^ !!dy) && 0 <= x + dx && x + dx < w && 0 <= y + dy &&
            y + dy < h && !mp[x + dx][y + dy]) {
          q.push(make_pair(c + 1, make_pair(x + dx, y + dy)));
        }
      }
    }
  }
  return -1;
}

int main() {
  cin >> h >> w >> n;
  mp.assign(w, vector<bool>(h, false));
  f.assign(n + 1, make_pair(0, 0));
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      char a;
      cin >> a;
      if (a == 'X')
        mp[x][y] = true;
      if (a == 'S')
        f[0] = make_pair(x, y);
      if ('1' <= a && a <= '9')
        f[a - '0'] = make_pair(x, y);
    }
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    ans += bfs(f[i - 1], f[i]);
  }
  cout << ans << endl;
  return 0;
}

#include <iostream>
#include <queue>
#include <vector>
using namespace std;

int h, w, n;
vector<vector<bool>> mp;
vector<pair<int, int>> f;

int calc(pair<int, int> start, pair<int, int> end) {
  vector<vector<int>> hi(w, vector<int>(h, 1145141919));
  priority_queue<pair<int, pair<int, int>>, vector<pair<int, pair<int, int>>>,
                 greater<pair<int, pair<int, int>>>>
      q;
  q.push(make_pair(0, start));
  while (q.size()) {
    int c = q.top().first;
    pair<int, int> p = q.top().second;
    q.pop();
    if (p == end)
      return c;
    int x = p.first;
    int y = p.second;
    for (int dx = -1; dx <= 1; dx++) {
      for (int dy = -1; dy <= 1; dy++) {
        if ((!!dx ^ !!dy) && 0 <= x + dx && x + dx < w && 0 <= y + dy &&
            y + dy < h && !mp[x + dx][y + dy] && hi[x + dx][y + dy] > c + 1) {
          hi[x + dx][y + dy] = c + 1;
          q.push(make_pair(c + 1, make_pair(x + dx, y + dy)));
        }
      }
    }
  }
  return -1;
}

int main() {
  cin >> h >> w >> n;
  mp.assign(w, vector<bool>(h, false));
  f.assign(n + 1, make_pair(0, 0));
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      char a;
      cin >> a;
      if (a == 'X')
        mp[x][y] = true;
      if (a == 'S')
        f[0] = make_pair(x, y);
      if ('1' <= a && a <= '9')
        f[a - '0'] = make_pair(x, y);
    }
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    ans += calc(f[i - 1], f[i]);
  }
  cout << ans << endl;
  return 0;
}


#include <iostream>
#include <queue>
using namespace std;

string s[1000];
int h, w, n;
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};

int bfs(int x, int y, int now) {
  queue<pair<int, int>> Q;
  Q.push(make_pair(8, x * 1000 + y));
  while (!Q.empty()) {
    pair<int, int> a = Q.front();
    Q.pop();
    int tx = a.second / 1000, ty = a.second % 1000;
    if (s[tx][ty] - '0' == now) {
      return a.first / 10;
    }
    for (int r = 0; r < 4; r++) {
      if (abs(a.first % 10 - r) == 2)
        continue;
      int sx = tx + dx[r];
      int sy = ty + dy[r];
      if (sx < 0 || sy < 0 || sx >= h || sy >= w || s[sx][sy] == 'X')
        continue;
      Q.push(make_pair((a.first / 10 + 1) * 10 + r, sx * 1000 + sy));
    }
  }
  return 1 << 26;
}

int main() {
  cin >> h >> w >> n;
  for (int i = 0; i < h; i++)
    cin >> s[i];
  int c = 0;
  pair<int, int> pr[9];
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (s[i][j] == 'S') {
        pr[0] = make_pair(i, j);
      } else if (s[i][j] >= '0' && s[i][j] <= '8') {
        pr[s[i][j] - '0'] = make_pair(i, j);
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    c += bfs(pr[i - 1].first, pr[i - 1].second, i);
  }
  cout << c << endl;
  return 0;
}

#include <iostream>
#include <queue>
using namespace std;

string s[1000];
int h, w, n;
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};

int bfs(int x, int y, int now) {
  int d[h][w] = {};
  queue<pair<int, int>> Q;
  Q.push(make_pair(8, x * 1000 + y));
  while (!Q.empty()) {
    pair<int, int> a = Q.front();
    Q.pop();
    int tx = a.second / 1000, ty = a.second % 1000;
    if (s[tx][ty] - '0' == now) {
      return a.first / 10;
    }
    for (int r = 0; r < 4; r++) {
      if (abs(a.first % 10 - r) == 2)
        continue;
      int sx = tx + dx[r];
      int sy = ty + dy[r];
      if (sx < 0 || sy < 0 || sx >= h || sy >= w || s[sx][sy] == 'X' ||
          d[sx][sy] != 0)
        continue;
      Q.push(make_pair((a.first / 10 + 1) * 10 + r, sx * 1000 + sy));
      d[sx][sy] = 1;
    }
  }
  return 1 << 26;
}

int main() {
  cin >> h >> w >> n;
  for (int i = 0; i < h; i++)
    cin >> s[i];
  int c = 0;
  pair<int, int> pr[9];
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (s[i][j] == 'S') {
        pr[0] = make_pair(i, j);
      } else if (s[i][j] >= '0' && s[i][j] <= '8') {
        pr[s[i][j] - '0'] = make_pair(i, j);
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    c += bfs(pr[i - 1].first, pr[i - 1].second, i);
  }
  cout << c << endl;
  return 0;
}


#include <cstring>
#include <iostream>
#include <queue>
#include <utility>

using namespace std;

int H, W, N;
char map[1024][1024];
bool visited[1024][1024];
int factories[10];
int dx[4] = {0, 1, 0, -1};
int dy[4] = {-1, 0, 1, 0};

void solve() {
  int result = 0;
  for (int i = 0; i < N; ++i) {
    queue<pair<int, int>> loc_time;
    memset(visited, false, sizeof visited);
    int fx = factories[i + 1] % W;
    int fy = factories[i + 1] / W;
    loc_time.push(make_pair(factories[i], 0));

    while (!loc_time.empty()) {
      int loc = loc_time.front().first;
      int time = loc_time.front().second;
      loc_time.pop();
      int x = loc % W;
      int y = loc / W;
      visited[y][x] = true;
      if (y == fy && x == fx) {
        result += time;
        break;
      }
      for (int i = 0; i < 4; ++i) {
        int nx = x + dx[i];
        int ny = y + dy[i];
        if (0 <= nx && nx < W && 0 <= ny && ny < H && map[ny][nx] != 'X' &&
            !visited[ny][nx]) {
          loc_time.push(make_pair(ny * W + nx, time + 1));
        }
      }
    }
  }
  cout << result << endl;
}

int main() {
  cin >> H >> W >> N;
  for (int h = 0; h < H; ++h) {
    for (int w = 0; w < W; ++w) {
      cin >> map[h][w];
      if (isdigit(map[h][w])) {
        factories[map[h][w] - '0'] = h * W + w;
      }
      if (map[h][w] == 'S') {
        factories[0] = h * W + w;
      }
    }
  }
  solve();
  return 0;
}

#include <cstring>
#include <iostream>
#include <queue>

using namespace std;

int H, W, N;
char map[1024][1024];
int dist[1024][1024];
int factories[10];
int dx[4] = {0, 1, 0, -1};
int dy[4] = {-1, 0, 1, 0};

int bfs(int from, int to) {
  queue<int> q;
  q.push(from);
  dist[from / W][from % W] = 0;
  int fx = to % W;
  int fy = to / W;

  while (!q.empty()) {
    int x = q.front() % W;
    int y = q.front() / W;
    q.pop();
    if (x == fx && y == fy) {
      return dist[fy][fx];
    }
    for (int d = 0; d < 4; ++d) {
      int nx = x + dx[d];
      int ny = y + dy[d];
      if (0 <= nx && nx < W && 0 <= ny && ny < H && map[ny][nx] != 'X' &&
          dist[ny][nx] == -1) {
        q.push(ny * W + nx);
        dist[ny][nx] = dist[y][x] + 1;
      }
    }
  }
}

void solve() {
  int result = 0;
  for (int i = 0; i < N; ++i) {
    memset(dist, -1, sizeof dist);
    result += bfs(factories[i], factories[i + 1]);
  }
  cout << result << endl;
}

int main() {
  cin >> H >> W >> N;
  for (int h = 0; h < H; ++h) {
    for (int w = 0; w < W; ++w) {
      cin >> map[h][w];
      if (isdigit(map[h][w])) {
        factories[map[h][w] - '0'] = h * W + w;
      }
      if (map[h][w] == 'S') {
        factories[0] = h * W + w;
      }
    }
  }
  solve();
  return 0;
}


#include <iostream>
#include <map>
#include <queue>
using namespace std;

typedef pair<int, int> P;
struct State {
  int x, y, cnt;
};
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

int main() {
  int w, h, n;
  string m[1001];
  cin >> h >> w >> n;
  for (int y = 0; y < h; y++) {
    cin >> m[y];
  }

  struct State cheese[11];
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      char c = m[y][x];
      if (c == 'S') {
        cheese[0].x = x;
        cheese[0].y = y;
        cheese[0].cnt = 0;
      }
      if (c >= '1' && c <= '9') {
        cheese[c - '0'].x = x;
        cheese[c - '0'].y = y;
        cheese[c - '0'].cnt = 0;
      }
    }
  }
  int ans = 0;
  for (int i = 1; i <= n; i++) {
    struct State sp = cheese[i - 1];
    struct State gp = cheese[i];
    map<P, bool> memo;
    P p_(sp.x, sp.y);
    memo[p_] = true;

    queue<struct State> q;
    q.push(sp);
    while (!q.empty()) {
      struct State p = q.front();
      q.pop();
      if (p.x == gp.x && p.y == gp.y) {
        ans += p.cnt;
        break;
      }
      P p_(p.x, p.y);
      memo[p_] = true;

      for (int i = 0; i < 4; i++) {
        int mx = p.x + dx[i];
        int my = p.y + dy[i];
        if (mx < 0 || my < 0 || mx >= w || my >> h)
          continue;
        if (m[my][mx] != 'X') {
          struct State next;
          next.x = mx;
          next.y = my;
          next.cnt = p.cnt + 1;
          P p_(mx, my);
          if (memo[p_] != true) {
            q.push(next);
          }
        }
      }
    }
  }
  cout << ans << endl;
}

#include <iostream>
#include <map>
#include <queue>
using namespace std;

struct p {
  int x, y;
};
typedef struct p P;
const int INF = 1e+7;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};

int w, h, n;
string m[1001];
P cheese[11];
int ans = 0;
int d[1001][1001];

void bfs() {
  for (int i = 1; i <= n; i++) {
    P sp = cheese[i - 1];
    int sx = cheese[i - 1].x;
    int sy = cheese[i - 1].y;
    int gx = cheese[i].x;
    int gy = cheese[i].y;
    for (int y = 0; y < h; y++) {
      for (int x = 0; x < w; x++) {
        d[y][x] = INF;
      }
    }

    queue<P> q;
    q.push(sp);
    d[sy][sx] = 0;
    while (!q.empty()) {
      P now = q.front();
      q.pop();
      int x = now.x;
      int y = now.y;
      if (x == gx && y == gy) {
        ans += d[gy][gx];
        break;
      }
      for (int i = 0; i < 4; i++) {
        int mx = x + dx[i];
        int my = y + dy[i];
        if (mx < 0 || my < 0 || mx >= w || my >= h)
          continue;
        if (m[my][mx] != 'X') {
          P next;

          next.x = mx;
          next.y = my;
          if (d[my][mx] == INF) {
            d[my][mx] = d[y][x] + 1;
            q.push(next);
          }
        }
      }
    }
  }
}

int main() {
  cin >> h >> w >> n;
  for (int y = 0; y < h; y++) {
    cin >> m[y];
  }

  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      char c = m[y][x];
      if (c == 'S') {
        cheese[0].x = x;
        cheese[0].y = y;
      }
      if (c >= '1' && c <= '9') {
        cheese[c - '0'].x = x;
        cheese[c - '0'].y = y;
      }
    }
  }
  bfs();
  cout << ans << endl;
}


#include <iostream>
#include <queue>
#include <stdlib.h>
#include <utility>

using namespace std;

typedef struct pair {
  int x;
  int y;
} pair_t;

const int INF = 10000000;

int bfs();

int H, W, N;
char **field;
int **d;

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

int sx, sy;

int main() {
  cin >> H >> W >> N;
  field = (char **)malloc(sizeof(char *) * H);
  d = (int **)malloc(sizeof(int *) * H);

  for (int i = 0; i < H; i++) {
    char *row = (char *)malloc(sizeof(char) * W);
    int *dr = (int *)malloc(sizeof(int) * W);
    cin >> row;
    field[i] = row;
    d[i] = dr;
  }

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

      if (field[i][j] == 'S') {
        sx = j;
        sy = i;
        field[i][j] = '.';
      }
    }
  }

  int result = bfs();

  cout << result << endl;

  for (int i = 0; i < H; i++) {
    free(field[i]);
  }

  free(field);

  return 0;
}

void init_d(int x, int y, int n) {

  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      d[i][j] = INF;
    }
  }

  d[y][x] = n;
}

void clear(queue<pair_t> &q) {
  queue<pair_t> empty;
  swap(q, empty);
}

int bfs() {
  int cheeze = 1;

  queue<pair_t> que;

  pair_t first = {sx, sy};
  que.push(first);
  d[sy][sx] = 0;

  init_d(sx, sy, 0);

  while (que.size()) {
  NEXT:
    pair_t p = que.front();
    que.pop();

    for (int i = 0; i < 4; i++) {
      int nx = p.x + dx[i];
      int ny = p.y + dy[i];

      if (0 <= nx && nx < W && 0 <= ny && ny < H && field[ny][nx] != 'X' &&
          d[ny][nx] == INF) {
        if (field[ny][nx] != '.') {
          if ((int)(field[ny][nx] - '0') == cheeze) {

            if (cheeze == N) {
              return d[p.y][p.x] + 1;
            }

            init_d(nx, ny, d[p.y][p.x] + 1);
            clear(que);

            pair_t n = {nx, ny};
            que.push(n);

            cheeze++;
            goto NEXT;
          }
        }

        pair_t n = {nx, ny};
        d[ny][nx] = d[p.y][p.x] + 1;
        que.push(n);
      }
    }
  }
  return -1;
}

#include <iostream>
#include <queue>
#include <stdlib.h>
#include <utility>

using namespace std;

typedef struct pair {
  int x;
  int y;
} pair_t;

const int INF = 10000000;

int bfs();

int H, W, N;
char **field;
int **d;

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

int sx, sy;

int main() {
  cin >> H >> W >> N;
  field = (char **)malloc(sizeof(char *) * H);
  d = (int **)malloc(sizeof(int *) * H);

  for (int i = 0; i < H; i++) {
    char *row = (char *)malloc(sizeof(char) * W);
    int *dr = (int *)malloc(sizeof(int) * W);
    cin >> row;
    field[i] = row;
    d[i] = dr;
  }

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

      if (field[i][j] == 'S') {
        sx = j;
        sy = i;
        field[i][j] = '.';
      }
    }
  }

  int result = bfs();

  cout << result << endl;

  // for(int i=0; i<H; i++){
  //     free(field[i]);
  // }

  // free(field);

  return 0;
}

void init_d(int x, int y, int n) {

  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      d[i][j] = INF;
    }
  }

  d[y][x] = n;
}

void clear(queue<pair_t> &q) {
  queue<pair_t> empty;
  swap(q, empty);
}

int bfs() {
  int cheeze = 1;

  queue<pair_t> que;

  pair_t first = {sx, sy};
  que.push(first);
  d[sy][sx] = 0;

  init_d(sx, sy, 0);

  while (que.size()) {
  NEXT:
    pair_t p = que.front();
    que.pop();

    for (int i = 0; i < 4; i++) {
      int nx = p.x + dx[i];
      int ny = p.y + dy[i];

      if (0 <= nx && nx < W && 0 <= ny && ny < H && field[ny][nx] != 'X' &&
          d[ny][nx] == INF) {
        if (field[ny][nx] != '.') {
          if ((int)(field[ny][nx] - '0') == cheeze) {

            if (cheeze == N) {
              return d[p.y][p.x] + 1;
            }

            init_d(nx, ny, d[p.y][p.x] + 1);
            clear(que);

            pair_t n = {nx, ny};
            que.push(n);

            cheeze++;
            goto NEXT;
          }
        }

        pair_t n = {nx, ny};
        d[ny][nx] = d[p.y][p.x] + 1;
        que.push(n);
      }
    }
  }
  return -1;
}