#include <stdio.h>

bool syo[1000][1000];
int zi[1000][1000];
int kox[1000000];
int koy[1000000];
int kon;
int koxs[1000000];
int koys[1000000];
int kons;
int cx[10];
int cy[10];
int sx, sy;

int main() {
  int h, w, n;
  scanf("%d %d %d", &h, &w, &n);
  for (int i = 0; i < h; i++) {
    char ww[1111];
    scanf("%s", ww);
    for (int ii = 0; ii < w; ii++) {
      if ('1' <= ww[ii] && ww[ii] <= '9') {
        int d = ww[ii] - '1';
        cy[d] = i;
        cx[d] = ii;
      }
      if (ww[ii] == 'S') {
        sy = i;
        sx = ii;
      }
      if (ww[ii] == 'X') {
        syo[i][ii] = true;
      } else {
        syo[i][ii] = false;
      }
    }
  }
  int time = 0;
  int nx = sx;
  int ny = sy;
  for (int k = 0; k < n; k++) {
    for (int i = 0; i < h; i++) {
      for (int ii = 0; ii < w; ii++) {
        zi[i][ii] = 100000000;
      }
    }
    zi[ny][nx] = 0;
    kox[0] = nx;
    koy[0] = ny;
    kon = 1;
    while (1) {
      kons = 0;
      for (int i = 0; i < kon; i++) {
        if (syo[koy[i]][kox[i]]) {
          continue;
        }
        if (kox[i] == cx[k] && koy[i] == cy[k]) {
          goto aa;
        }
        if (kox[i] > 0) {
          if (zi[koy[i]][kox[i] - 1] > zi[koy[i]][kox[i]]) {
            zi[koy[i]][kox[i] - 1] = zi[koy[i]][kox[i]] + 1;
            koxs[kons] = kox[i] - 1;
            koys[kons] = koy[i];
            kons++;
          }
        }
        if (kox[i] < w - 1) {
          if (zi[koy[i]][kox[i] + 1] > zi[koy[i]][kox[i]]) {
            zi[koy[i]][kox[i] + 1] = zi[koy[i]][kox[i]] + 1;
            koxs[kons] = kox[i] + 1;
            koys[kons] = koy[i];
            kons++;
          }
        }
        if (koy[i] > 0) {
          if (zi[koy[i] - 1][kox[i]] > zi[koy[i]][kox[i]]) {
            zi[koy[i] - 1][kox[i]] = zi[koy[i]][kox[i]] + 1;
            koxs[kons] = kox[i];
            koys[kons] = koy[i] - 1;
            kons++;
          }
        }
        if (koy[i] < h - 1) {
          if (zi[koy[i] + 1][kox[i]] > zi[koy[i]][kox[i]]) {
            zi[koy[i] + 1][kox[i]] = zi[koy[i]][kox[i]] + 1;
            koxs[kons] = kox[i];
            koys[kons] = koy[i] + 1;
            kons++;
          }
        }
      }
      for (int i = 0; i < kons; i++) {
        kox[i] = koxs[i];
        koy[i] = koys[i];
      }
      kon = kons;
    }
  aa:
    time += zi[cy[k]][cx[k]];
    nx = cx[k];
    ny = cy[k];
  }
  printf("%d\\n", time);
  return 0;
}

#include <stdio.h>

bool syo[1000][1000];
bool sude[1000][1000];
int zi[1000][1000];
int kox[1000000];
int koy[1000000];
int kon;
int koxs[1000000];
int koys[1000000];
int kons;
int cx[10];
int cy[10];
int sx, sy;

int main() {
  int h, w, n;
  scanf("%d %d %d", &h, &w, &n);
  for (int i = 0; i < h; i++) {
    char ww[1111];
    scanf("%s", ww);
    for (int ii = 0; ii < w; ii++) {
      if ('1' <= ww[ii] && ww[ii] <= '9') {
        int d = ww[ii] - '1';
        cy[d] = i;
        cx[d] = ii;
      }
      if (ww[ii] == 'S') {
        sy = i;
        sx = ii;
      }
      if (ww[ii] == 'X') {
        syo[i][ii] = true;
      } else {
        syo[i][ii] = false;
      }
    }
  }
  int time = 0;
  int nx = sx;
  int ny = sy;
  for (int k = 0; k < n; k++) {
    for (int i = 0; i < h; i++) {
      for (int ii = 0; ii < w; ii++) {
        zi[i][ii] = 1000000;
        sude[i][ii] = false;
      }
    }
    zi[ny][nx] = 0;
    kox[0] = nx;
    koy[0] = ny;
    kon = 1;
    while (1) {
      kons = 0;
      for (int i = 0; i < kon; i++) {
        if (syo[koy[i]][kox[i]] || sude[koy[i]][kox[i]]) {
          continue;
        }
        sude[koy[i]][kox[i]] = true;
        if (kox[i] == cx[k] && koy[i] == cy[k]) {
          goto aa;
        }
        if (kox[i] > 0) {
          if (zi[koy[i]][kox[i] - 1] > zi[koy[i]][kox[i]]) {
            zi[koy[i]][kox[i] - 1] = zi[koy[i]][kox[i]] + 1;
            koxs[kons] = kox[i] - 1;
            koys[kons] = koy[i];
            kons++;
          }
        }
        if (kox[i] < w - 1) {
          if (zi[koy[i]][kox[i] + 1] > zi[koy[i]][kox[i]]) {
            zi[koy[i]][kox[i] + 1] = zi[koy[i]][kox[i]] + 1;
            koxs[kons] = kox[i] + 1;
            koys[kons] = koy[i];
            kons++;
          }
        }
        if (koy[i] > 0) {
          if (zi[koy[i] - 1][kox[i]] > zi[koy[i]][kox[i]]) {
            zi[koy[i] - 1][kox[i]] = zi[koy[i]][kox[i]] + 1;
            koxs[kons] = kox[i];
            koys[kons] = koy[i] - 1;
            kons++;
          }
        }
        if (koy[i] < h - 1) {
          if (zi[koy[i] + 1][kox[i]] > zi[koy[i]][kox[i]]) {
            zi[koy[i] + 1][kox[i]] = zi[koy[i]][kox[i]] + 1;
            koxs[kons] = kox[i];
            koys[kons] = koy[i] + 1;
            kons++;
          }
        }
      }
      for (int i = 0; i < kons; i++) {
        kox[i] = koxs[i];
        koy[i] = koys[i];
      }
      kon = kons;
    }
  aa:
    time += zi[cy[k]][cx[k]];
    nx = cx[k];
    ny = cy[k];
  }
  printf("%d\\n", time);
  return 0;
}


#include <cstring>
#include <iostream>
#include <queue>
#include <stdio.h>
using namespace std;

char ma[1005][1005];
int vis[1005][1005];
int w, h, n;

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

struct node {
  int x, y, time;
};
node start;

void bfs(char ed) {
  queue<node> que;
  que.push(start);
  vis[start.x][start.y] = 1;
  while (!que.empty()) {
    node no = que.front();
    que.pop();
    for (int i = 0; i < 4; i++) {
      int x = no.x + dx[i];
      int y = no.y + dy[i];
      if (vis[x][y] || x >= h || x < 0 || y >= w || y < 0 || ma[x][y] == 'X')
        continue;
      if (ma[x][y] == ed) {
        start.x = x;
        start.y = y;
        start.time = no.time + 1;
        return;
      }
      vis[x][y] = 1;
      node no1;
      no1.x = x;
      no1.y = y;
      no1.time = no.time + 1;
      que.push(no1);
    }
  }
}

int main() {
  while (~scanf("%d %d %d", &h, &w, &n)) {
    for (int i = 0; i < h; i++) {
      scanf("%s", &ma[i]);
      for (int j = 0; j < w; j++)
        if (ma[i][j] == 'S') {
          start.x = i;
          start.y = j;
          start.time = 0;
        }
    }
    for (int i = 0; i < n; i++) {
      memset(vis, 0, sizeof(vis));
      bfs(i + '1');
    }

    printf("%d\\n", start.time);
  }
  return 0;
}

#include <bits/stdc++.h>

using namespace std;
struct node {
  int x, y, f;
};
char a[1010][1010];
int book[1010][1010];
int m, n, h, ans, head, tail;
int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
void bfs(int x, int y, int step) {
  int k = 0;
  node s, e;
  s.x = x;
  s.y = y;
  s.f = 0;
  memset(book, 0, sizeof(book));
  book[x][y] = 1;
  queue<node> q;
  q.push(s);
  while (!q.empty()) {
    s = q.front();
    q.pop();
    for (int i = 0; i < 4; i++) {
      e.x = s.x + dir[i][0];
      e.y = s.y + dir[i][1];
      e.f = s.f + 1;
      if (a[e.x][e.y] == 'X' || e.x < 0 || e.y < 0 || e.x >= m || e.y >= n ||
          book[e.x][e.y])
        continue;
      if (a[e.x][e.y] == step + '0') {
        ans += e.f;
        k = 1;
        break;
      }
      book[e.x][e.y] = 1;
      q.push(e);
    }
    if (k)
      break;
  }
  if (k && step == h)
    return;
  bfs(e.x, e.y, step + 1);
}
int main() {
  while (~scanf("%d %d %d", &m, &n, &h)) {
    int i, j;
    ans = 0;
    for (i = 0; i < m; i++)
      scanf("%s", a[i]);
    for (i = 0; i < m; i++)
      for (j = 0; j < n; j++)
        if (a[i][j] == 'S') {
          bfs(i, j, 1);
          break;
        }
    printf("%d\\n", ans);
  }
  return 0;
}


#include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <cstdint>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#define MOD 1000000007
#define INF 11234567890
#define in std::cin
#define out std::cout
#define rep(i, N) for (LL i = 0; i < N; ++i)
typedef long long int LL;
typedef std::pair<LL, LL> P;
struct edge {
  LL to, cost;
};

LL H, W, N;
std::string field[1123];
LL Sx, Sy, xy[11];
LL ans;

LL d[1123456];
std::vector<edge> G[1123456];
void dijkstra(LL s) {
  std::priority_queue<P, std::vector<P>, std::greater<P>> que;
  std::fill(d, d + H * W + 1, INF);
  d[s] = 0;
  que.push(P(0, s));
  while (!que.empty()) {
    P p = que.top();
    que.pop();
    LL v = p.second;
    if (d[v] < p.first) {
      continue;
    }
    rep(i, G[v].size()) {
      edge e = G[v][i];
      if (d[e.to] > d[v] + e.cost) {
        d[e.to] = d[v] + e.cost;
        que.push(P(d[e.to], e.to));
      }
    }
  }
}

int main() {
  try {
    in >> H >> W >> N;
    rep(i, H) { in >> field[i]; }

    rep(h, H) {
      rep(w, W) {
        if (field[h][w] == 'X') {
          continue;
        }
        if (field[h][w] == 'S') {
          Sx = h;
          Sy = w;
        }
        if (field[h][w] != '.') {
          xy[field[h][w] - '0'] = h * W + w;
        }
        if (false)
          if (h < H - 1) {
            if (field[h + 1][w] != 'X') {
              G[h * W + w].push_back({(h + 1) * W + w, 1});
              G[(h + 1) * W + w].push_back({h * W + w, 1});
            }
          }
        if (false)
          if (w < W - 1) {
            if (field[h][w + 1] != 'X') {
              G[h * W + w].push_back({h * W + (w + 1), 1});
              G[h * W + (w + 1)].push_back({h * W + w, 1});
            }
          }
      }
    }
    // dijkstra(Sx*W + Sy);
    // rep(i, N)
    //{
    //   ans += d[xy[i + 1]];
    //   dijkstra(xy[i + 1]);
    // }

    out << ans << std::endl;
    return 0;
  } catch (std::bad_alloc) {
    return 0;
  } catch (...) {
    return 0;
  }
}

#include <algorithm>
#include <array>
#include <assert.h>
#include <bitset>
#include <cstdint>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#define MOD 1000000007
#define INF 11234567890
#define in std::cin
#define out std::cout
#define rep(i, N) for (LL i = 0; i < N; ++i)
typedef long long int LL;
typedef std::pair<LL, LL> P;
struct edge {
  LL to, cost;
};

LL H, W, N;
std::string field[1123];
LL Sx, Sy, xy[11];
LL ans;

LL d[1123456];
std::vector<edge> G[1123456];
void dijkstra(LL s) {
  std::priority_queue<P, std::vector<P>, std::greater<P>> que;
  std::fill(d, d + H * W + 1, INF);
  d[s] = 0;
  que.push(P(0, s));
  while (!que.empty()) {
    P p = que.top();
    que.pop();
    LL v = p.second;
    if (d[v] < p.first) {
      continue;
    }
    rep(i, G[v].size()) {
      edge e = G[v][i];
      if (d[e.to] > d[v] + e.cost) {
        d[e.to] = d[v] + e.cost;
        que.push(P(d[e.to], e.to));
      }
    }
  }
}

int main() {
  try {
    in >> H >> W >> N;
    rep(i, H) { in >> field[i]; }

    rep(h, H) {
      rep(w, W) {
        if (field[h][w] == 'X') {
          continue;
        } else if (field[h][w] == 'S') {
          Sx = h;
          Sy = w;
        } else if (field[h][w] != '.') {
          xy[field[h][w] - '0'] = h * W + w;
        }
        if (h < H - 1) {
          if (field[h + 1][w] != 'X') {
            G[h * W + w].push_back({(h + 1) * W + w, 1});
            G[(h + 1) * W + w].push_back({h * W + w, 1});
          }
        }
        if (w < W - 1) {
          if (field[h][w + 1] != 'X') {
            G[h * W + w].push_back({h * W + (w + 1), 1});
            G[h * W + (w + 1)].push_back({h * W + w, 1});
          }
        }
      }
    }
    dijkstra(Sx * W + Sy);
    rep(i, N) {
      ans += d[xy[i + 1]];
      dijkstra(xy[i + 1]);
    }

    out << ans << std::endl;
    return 0;
  } catch (std::bad_alloc) {
    return 0;
  } catch (...) {
    return 0;
  }
}


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

#define rep(i, a, b) for (int i = (a), i##_len = (b); i < i##_len; i++)
#define rrep(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define all(c) begin(c), end(c)

// #define int long long
#define SZ(x) ((int)(x).size())
#define pb push_back
#define mp make_pair

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<double, double> pdd;

template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}

const int INF =
    sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)1e9 + 7;
const double EPS = 1e-9;

struct P {
  int x, y, t;
  P(int x, int y, int t) : x(x), y(y), t(t) {}
  P() : P(-1, -1, -1) {}
};

string A[1000];
int cnt[1000][1000];
int H, W, N;

int solve(P sp) {
  static const int dx[] = {1, 0, -1, 0};
  static const int dy[] = {0, 1, 0, -1};

  int ans = 0;
  rep(k, 1, N + 1) {
    queue<P> q;
    q.push(sp);
    while (true) {
      P tp = q.front();
      q.pop();
      cnt[tp.y][tp.x] = k;
      if ((int)A[tp.y][tp.x] == ((int)'0' + k)) {
        sp = P(tp.x, tp.y, 0);
        ans += tp.t;
        break;
      }

      rep(i, 0, 4) {
        P np(tp.x + dx[i], tp.y + dy[i], tp.t + 1);
        if (0 <= np.x && np.x < W && 0 <= np.y && np.y < H) {
          if (A[np.y][np.x] != 'X' && cnt[np.y][np.x] < k) {
            q.push(np);
          }
        }
      }
    }
  }

  return ans;
}

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  P sp;
  cin >> H >> W >> N;
  rep(i, 0, H) {
    cin >> A[i];
    if (sp.x == -1) {
      rep(j, 0, SZ(A[i])) {
        if (A[i][j] == 'S') {
          sp = P(j, i, 0);
          break;
        }
      }
    }
  }
  cout << solve(sp) << endl;

  return 0;
}

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

#define rep(i, a, b) for (int i = (a), i##_len = (b); i < i##_len; i++)
#define rrep(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define all(c) begin(c), end(c)

// #define int long long
#define SZ(x) ((int)(x).size())
#define pb push_back
#define mp make_pair

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<double, double> pdd;

template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}

const int INF =
    sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)1e9 + 7;
const double EPS = 1e-9;

struct P {
  int x, y, t;
  P(int x, int y, int t) : x(x), y(y), t(t) {}
  P() : P(-1, -1, -1) {}
};

string A[1000];
int cnt[1000][1000];
int H, W, N;

int solve(P sp) {
  static const int dx[] = {1, 0, -1, 0};
  static const int dy[] = {0, 1, 0, -1};

  int ans = 0;
  rep(k, 1, N + 1) {
    queue<P> q;
    q.push(sp);
    cnt[sp.y][sp.x] = k;
    while (true) {
      P tp = q.front();
      q.pop();
      if ((int)A[tp.y][tp.x] == ((int)'0' + k)) {
        sp = P(tp.x, tp.y, 0);
        ans += tp.t;
        break;
      }

      rep(i, 0, 4) {
        P np(tp.x + dx[i], tp.y + dy[i], tp.t + 1);
        if (0 <= np.x && np.x < W && 0 <= np.y && np.y < H) {
          if (A[np.y][np.x] != 'X' && cnt[np.y][np.x] < k) {
            cnt[np.y][np.x] = k;
            q.push(np);
          }
        }
      }
    }
  }

  return ans;
}

signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  P sp;
  cin >> H >> W >> N;
  rep(i, 0, H) {
    cin >> A[i];
    if (sp.x == -1) {
      rep(j, 0, SZ(A[i])) {
        if (A[i][j] == 'S') {
          sp = P(j, i, 0);
          break;
        }
      }
    }
  }
  cout << solve(sp) << endl;

  return 0;
}


#include <algorithm>
#include <bitset>
#include <cmath>
#include <fstream>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;

class CPoint {
public:
  int x, y;

  CPoint() : x(0), y(0){};
  CPoint(int ax, int ay) : x(ax), y(ay){};

  bool operator==(const CPoint &obj);
  bool operator!=(const CPoint &obj);
};

class CPoint;

const int MAX_H = 1000;
const int MAX_W = 1000;
const ll INF = 1000000000;

char field[MAX_H][MAX_W];
bool used[MAX_H][MAX_W];
ll d[MAX_H][MAX_W];
int H, W, N;

ll getroad(CPoint start, CPoint goal);

int main() {
  cin >> H >> W >> N;
  vector<CPoint> factorys(N + 1);

  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> field[i][j];
      if (field[i][j] != 'X' && field[i][j] != '.') {
        if (field[i][j] == 'S')
          factorys[0] = CPoint(i, j);
        else
          factorys[field[i][j] - '0'] = CPoint(i, j);
      }
    }
  }

  ll res = 0;
  for (int i = 0; i < N; i++)
    res += getroad(factorys[i], factorys[i + 1]);

  cout << res << endl;

  cin.sync();
  cin.get();
}

ll getroad(CPoint start, CPoint goal) {
  for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++)
      used[i][j] = false;
  for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++)
      d[i][j] = INF;

  d[start.x][start.y] = 0;

  while (true) {

    CPoint v(-1, -1);
    for (int i = 0; i < H; i++)
      for (int j = 0; j < W; j++)
        if (!used[i][j] && field[i][j] != 'X' &&
            (v == CPoint(-1, -1) || d[i][j] < d[v.x][v.y]))
          v = CPoint(i, j);

    if (v == CPoint(-1, -1))
      break;

    used[v.x][v.y] = true;

    if (v.y + 1 < W && field[v.x][v.y + 1] != 'X')
      d[v.x][v.y + 1] = min(d[v.x][v.y + 1], d[v.x][v.y] + 1);
    if (v.y - 1 >= 0 && field[v.x][v.y - 1] != 'X')
      d[v.x][v.y - 1] = min(d[v.x][v.y - 1], d[v.x][v.y] + 1);
    if (v.x + 1 < H && field[v.x + 1][v.y] != 'X')
      d[v.x + 1][v.y] = min(d[v.x + 1][v.y], d[v.x][v.y] + 1);
    if (v.x - 1 >= 0 && field[v.x - 1][v.y] != 'X')
      d[v.x - 1][v.y] = min(d[v.x - 1][v.y], d[v.x][v.y] + 1);
  }

  return d[goal.x][goal.y];
}

bool CPoint::operator==(const CPoint &obj) {
  return (x == obj.x && y == obj.y);
}

bool CPoint::operator!=(const CPoint &obj) { return !(*this == obj); }

#include <algorithm>
#include <bitset>
#include <cmath>
#include <ctime>
#include <fstream>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;

class CPoint {
public:
  int x, y;

  CPoint() : x(0), y(0){};
  CPoint(int ax, int ay) : x(ax), y(ay){};

  bool operator==(const CPoint &obj);
  bool operator!=(const CPoint &obj);

  CPoint operator+(const CPoint &obj);
};

class CPoint;

const int MAX_H = 1000;
const int MAX_W = 1000;
const ll INF = 1000000000;

char field[MAX_H][MAX_W];
bool used[MAX_H][MAX_W];
ll d[MAX_H][MAX_W];
int H, W, N;

ll getroad(CPoint start, CPoint goal);

int main() {
  cin >> H >> W >> N;
  vector<CPoint> factorys(N + 1);

  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> field[i][j];
      if (field[i][j] != 'X' && field[i][j] != '.') {
        if (field[i][j] == 'S')
          factorys[0] = CPoint(i, j);
        else
          factorys[field[i][j] - '0'] = CPoint(i, j);
      }
    }
  }

  ll res = 0;
  for (int i = 0; i < N; i++)
    res += getroad(factorys[i], factorys[i + 1]);

  cout << res << endl;
}

ll getroad(CPoint start, CPoint goal) {
  for (int i = 0; i < H; i++)
    for (int j = 0; j < W; j++)
      d[i][j] = INF;

  queue<CPoint> que;
  que.push(start);
  d[start.x][start.y] = 0;

  while (!que.empty()) {
    CPoint v = que.front();
    que.pop();
    if (v.y + 1 < W && field[v.x][v.y + 1] != 'X' &&
        d[v.x][v.y] + 1 < d[v.x][v.y + 1]) {
      d[v.x][v.y + 1] = d[v.x][v.y] + 1;
      que.push(v + CPoint(0, 1));
    }
    if (v.y - 1 >= 0 && field[v.x][v.y - 1] != 'X' &&
        d[v.x][v.y] + 1 < d[v.x][v.y - 1]) {
      d[v.x][v.y - 1] = d[v.x][v.y] + 1;
      que.push(v + CPoint(0, -1));
    }
    if (v.x + 1 < H && field[v.x + 1][v.y] != 'X' &&
        d[v.x][v.y] + 1 < d[v.x + 1][v.y]) {
      d[v.x + 1][v.y] = d[v.x][v.y] + 1;
      que.push(v + CPoint(1, 0));
    }
    if (v.x - 1 >= 0 && field[v.x - 1][v.y] != 'X' &&
        d[v.x][v.y] + 1 < d[v.x - 1][v.y]) {
      d[v.x - 1][v.y] = d[v.x][v.y] + 1;
      que.push((v + CPoint(-1, 0)));
    }
  }
  return d[goal.x][goal.y];
}

bool CPoint::operator==(const CPoint &obj) {
  return (x == obj.x && y == obj.y);
}

bool CPoint::operator!=(const CPoint &obj) { return !(*this == obj); }

CPoint CPoint::operator+(const CPoint &obj) {
  CPoint tmp;
  tmp.x = x + obj.x;
  tmp.y = y + obj.y;
  return tmp;
}


#include <iostream>
#include <queue>
using namespace std;
typedef pair<int, int> P;
const int MAX_HW = 1000;
int n, h, w, rat, s[2], g[2], flag[MAX_HW][MAX_HW][2];
int town[MAX_HW][MAX_HW];
char town2[MAX_HW][MAX_HW];
queue<P> que;
P p;
void bfs(int sy, int sx) {
  que.push(P(sy, sx));
  flag[sy][sx][0] = rat;
  while (que.size()) {
  RE:
    p = que.front();
    que.pop();
    for (int i = -1; i <= 1; i++) {
      for (int j = -1; j <= 1; j++) {
        if (i == 0 || j == 0) {
          if (town2[p.first + i][p.second + j] != 'X' &&
              flag[p.first + i][p.second + j][0] != rat && p.first + i < h &&
              p.first + i >= 0 && p.second + j < w && p.second + j >= 0) {
            flag[p.first + i][p.second + j][0] = rat;
            flag[p.first + i][p.second + j][1] = flag[p.first][p.second][1] + 1;
            if (town[p.first + i][p.second + j] == rat) {
              if (rat == n)
                return;
              rat++;
              flag[p.first + i][p.second + j][0] = rat;
              while (que.size()) {
                que.pop();
              }
              que.push(P(p.first + i, p.second + j));
              goto RE;
            } else {
              que.push(P(p.first + i, p.second + j));
            }
          }
        }
      }
    }
  }
}
int main() {
  cin >> h >> w >> n;
  rat = 1;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cin >> town2[i][j];
      town[i][j] = town2[i][j] - 48;
      if (town2[i][j] == 'S') {
        s[0] = i;
        s[1] = j;
      }
      if (town[i][j] == n) {
        g[0] = i;
        g[1] = j;
      }
    }
  }
  bfs(s[0], s[1]);
  cout << flag[g[0]][g[1]][1] << endl;
  return 0;
}

#include <iostream>
#include <queue>
using namespace std;
typedef pair<int, int> P;
const int MAX_HW = 1000;
int n, h, w, rat, s[2], g[2], flag[MAX_HW + 1][MAX_HW + 1][2];
int town[MAX_HW + 1][MAX_HW + 1];
char town2[MAX_HW + 1][MAX_HW + 1];
queue<P> que;
P p;
void bfs(int sy, int sx) {
  que.push(P(sy, sx));
  flag[sy][sx][0] = rat;
  while (que.size()) {
  RE:
    p = que.front();
    que.pop();
    for (int i = -1; i <= 1; i++) {
      for (int j = -1; j <= 1; j++) {
        if (i == 0 || j == 0) {
          if (town2[p.first + i][p.second + j] != 'X' &&
              flag[p.first + i][p.second + j][0] != rat && p.first + i < h &&
              p.first + i >= 0 && p.second + j < w && p.second + j >= 0) {
            flag[p.first + i][p.second + j][0] = rat;
            flag[p.first + i][p.second + j][1] = flag[p.first][p.second][1] + 1;
            if (town[p.first + i][p.second + j] == rat) {
              if (rat == n)
                return;
              rat++;
              flag[p.first + i][p.second + j][0] = rat;
              while (que.size()) {
                que.pop();
              }
              que.push(P(p.first + i, p.second + j));
              goto RE;
            } else {
              que.push(P(p.first + i, p.second + j));
            }
          }
        }
      }
    }
  }
}
int main() {
  cin >> h >> w >> n;
  rat = 1;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cin >> town2[i][j];
      town[i][j] = town2[i][j] - 48;
      if (town2[i][j] == 'S') {
        s[0] = i;
        s[1] = j;
      }
      if (town[i][j] == n) {
        g[0] = i;
        g[1] = j;
      }
    }
  }
  bfs(s[0], s[1]);
  cout << flag[g[0]][g[1]][1] << endl;
  return 0;
}


#include <iostream>
#include <queue>
using namespace std;
typedef pair<int, int> P;
const int MAX_HW = 1000;
int n, h, w, rat, s[2], g[2], flag[MAX_HW + 1][MAX_HW + 1][2];
int town[MAX_HW][MAX_HW];
char town2[MAX_HW][MAX_HW];
queue<P> que;
P p;
void bfs(int sy, int sx) {
  que.push(P(sy, sx));
  flag[sy][sx][0] = rat;
  while (que.size()) {
  RE:
    p = que.front();
    que.pop();
    for (int i = -1; i <= 1; i++) {
      for (int j = -1; j <= 1; j++) {
        if (i == 0 || j == 0) {
          if (town2[p.first + i][p.second + j] != 'X' &&
              flag[p.first + i][p.second + j][0] != rat && p.first + i < h &&
              p.first + i >= 0 && p.second + j < w && p.second + j >= 0) {
            flag[p.first + i][p.second + j][0] = rat;
            flag[p.first + i][p.second + j][1] = flag[p.first][p.second][1] + 1;
            if (town[p.first + i][p.second + j] == rat) {
              if (rat == n)
                return;
              rat++;
              flag[p.first + i][p.second + j][0] = rat;
              while (que.size()) {
                que.pop();
              }
              que.push(P(p.first + i, p.second + j));
              goto RE;
            } else {
              que.push(P(p.first + i, p.second + j));
            }
          }
        }
      }
    }
  }
}
int main() {
  cin >> h >> w >> n;
  rat = 1;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cin >> town2[i][j];
      town[i][j] = town2[i][j] - 48;
      if (town2[i][j] == 'S') {
        s[0] = i;
        s[1] = j;
      }
      if (town[i][j] == n) {
        g[0] = i;
        g[1] = j;
      }
    }
  }
  bfs(s[0], s[1]);
  cout << flag[g[0]][g[1]][1] << endl;
  return 0;
}


#include <iostream>
#include <queue>
using namespace std;
typedef pair<int, int> P;
const int MAX_HW = 1000;
int n, h, w, rat, s[2], g[2], flag[MAX_HW][MAX_HW + 1][2];
int town[MAX_HW][MAX_HW];
char town2[MAX_HW][MAX_HW];
queue<P> que;
P p;
void bfs(int sy, int sx) {
  que.push(P(sy, sx));
  flag[sy][sx][0] = rat;
  while (que.size()) {
  RE:
    p = que.front();
    que.pop();
    for (int i = -1; i <= 1; i++) {
      for (int j = -1; j <= 1; j++) {
        if (i == 0 || j == 0) {
          if (town2[p.first + i][p.second + j] != 'X' &&
              flag[p.first + i][p.second + j][0] != rat && p.first + i < h &&
              p.first + i >= 0 && p.second + j < w && p.second + j >= 0) {
            flag[p.first + i][p.second + j][0] = rat;
            flag[p.first + i][p.second + j][1] = flag[p.first][p.second][1] + 1;
            if (town[p.first + i][p.second + j] == rat) {
              if (rat == n)
                return;
              rat++;
              flag[p.first + i][p.second + j][0] = rat;
              while (que.size()) {
                que.pop();
              }
              que.push(P(p.first + i, p.second + j));
              goto RE;
            } else {
              que.push(P(p.first + i, p.second + j));
            }
          }
        }
      }
    }
  }
}
int main() {
  cin >> h >> w >> n;
  rat = 1;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cin >> town2[i][j];
      town[i][j] = town2[i][j] - 48;
      if (town2[i][j] == 'S') {
        s[0] = i;
        s[1] = j;
      }
      if (town[i][j] == n) {
        g[0] = i;
        g[1] = j;
      }
    }
  }
  bfs(s[0], s[1]);
  cout << flag[g[0]][g[1]][1] << endl;
  return 0;
}

// AOJ 0558: Cheese
#include <iostream>
#include <queue>
using namespace std;
typedef pair<int, int> P;
const int MAX_HW = 1000;
int n, h, w, rat, s[2], g[2], flag[MAX_HW + 1][MAX_HW][2];
int town[MAX_HW][MAX_HW];
char town2[MAX_HW][MAX_HW];
queue<P> que;
P p;
void bfs(int sy, int sx) {
  que.push(P(sy, sx));
  flag[sy][sx][0] = rat;
  while (que.size()) {
  RE:
    p = que.front();
    que.pop();
    for (int i = -1; i <= 1; i++) {
      for (int j = -1; j <= 1; j++) {
        if (i == 0 || j == 0) {
          if (town2[p.first + i][p.second + j] != 'X' &&
              flag[p.first + i][p.second + j][0] != rat && p.first + i < h &&
              p.first + i >= 0 && p.second + j < w && p.second + j >= 0) {
            flag[p.first + i][p.second + j][0] = rat;
            flag[p.first + i][p.second + j][1] = flag[p.first][p.second][1] + 1;
            if (town[p.first + i][p.second + j] == rat) {
              if (rat == n)
                return;
              rat++;
              flag[p.first + i][p.second + j][0] = rat;
              while (que.size()) {
                que.pop();
              }
              que.push(P(p.first + i, p.second + j));
              goto RE;
            } else {
              que.push(P(p.first + i, p.second + j));
            }
          }
        }
      }
    }
  }
}
int main() {
  cin >> h >> w >> n;
  rat = 1;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cin >> town2[i][j];
      town[i][j] = town2[i][j] - 48;
      if (town2[i][j] == 'S') {
        s[0] = i;
        s[1] = j;
      }
      if (town[i][j] == n) {
        g[0] = i;
        g[1] = j;
      }
    }
  }
  bfs(s[0], s[1]);
  cout << flag[g[0]][g[1]][1] << endl;
  return 0;
}


#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
char field[1000][1000];
struct date {
  int x, y, cnt;
};
int main() {
  int h, w, n;
  cin >> h >> w >> n;
  date start;
  int ans = 0;
  for (int i = 0; i < h; i++) {
    cin >> field[i];
    for (int j = 0; j < w; j++) {
      if (field[i][j] == 'S') {
        start.x = j, start.y = i, start.cnt = 0;
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    queue<date> Q;
    Q.push(start);
    while (!Q.empty()) {
      date d = Q.front();
      Q.pop();
      if (field[d.y][d.x] == i + '0') {
        start.x = d.x, start.y = d.y, start.cnt = d.cnt;
        break;
      }
      int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
      for (int j = 0; j < 4; j++) {
        int px = d.x + dx[j], py = d.y + dy[j];
        if (px < 0 || py < 0 || px >= w || py >= h)
          continue;
        if (field[py][px] == 'X')
          continue;
        date next = {px, py, d.cnt + 1};
        Q.push(next);
      }
    }
    ans = start.cnt;
  }

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

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
char field[1000][1000];
struct date {
  int x, y, cnt;
};
int main() {
  int h, w, n;
  cin >> h >> w >> n;
  date start;
  int ans = 0;
  for (int i = 0; i < h; i++) {
    cin >> field[i];
    for (int j = 0; j < w; j++) {
      if (field[i][j] == 'S') {
        start.x = j, start.y = i, start.cnt = 0;
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    queue<date> Q;
    Q.push(start);
    bool flg[1000][1000] = {{0}};
    while (!Q.empty()) {
      date d = Q.front();
      Q.pop();
      if (field[d.y][d.x] == i + '0') {
        start.x = d.x, start.y = d.y, start.cnt = d.cnt;
        break;
      }
      if (flg[d.y][d.x])
        continue;
      flg[d.y][d.x] = 1;
      int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
      for (int j = 0; j < 4; j++) {
        int px = d.x + dx[j], py = d.y + dy[j];
        if (px < 0 || py < 0 || px >= w || py >= h)
          continue;
        if (field[py][px] == 'X')
          continue;
        date next = {px, py, d.cnt + 1};
        Q.push(next);
      }
    }
    ans = start.cnt;
  }

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


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

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

class Data {
public:
  int x, y, count;
  Data() {}
  Data(int x, int y, int count) : x(x), y(y), count(count) {}
};
int main() {
  int h, w, n;
  cin >> h >> w >> n;
  Data start;
  int ans = 0;
  for (int i = 0; i < h; i++) {
    cin >> field[i];
    for (int j = 0; j < w; j++) {
      if (field[i][j] == 'S') {
        start = Data(j, i, 0);
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    queue<Data> Q;
    Q.push(start);
    // bool flg[1000][1000] = {{0}};
    while (!Q.empty()) {
      Data d = Q.front();
      Q.pop();
      if (field[d.y][d.x] == i + '0') {
        start = Data(d.x, d.y, d.count);
        break;
      }
      // if (flg[d.y][d.x]) continue;
      // flg[d.y][d.x] = true;
      for (int j = 0; j < 4; j++) {
        int px = d.x + dx[j], py = d.y + dy[j];
        if (px < 0 || py < 0 || px >= w || py >= h)
          continue;
        if (field[py][px] == 'X')
          continue;
        Q.push(Data(px, py, d.count + 1));
      }
    }
    ans = start.count;
  }

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

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

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

class Data {
public:
  int x, y, count;
  Data() {}
  Data(int x, int y, int count) : x(x), y(y), count(count) {}
};
int main() {
  int h, w, n;
  cin >> h >> w >> n;
  Data start;
  int ans = 0;
  for (int i = 0; i < h; i++) {
    cin >> field[i];
    for (int j = 0; j < w; j++) {
      if (field[i][j] == 'S') {
        start = Data(j, i, 0);
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    queue<Data> Q;
    Q.push(start);
    bool flg[1000][1000] = {{0}};
    while (!Q.empty()) {
      Data d = Q.front();
      Q.pop();
      if (field[d.y][d.x] == i + '0') {
        start = Data(d.x, d.y, d.count);
        break;
      }
      if (flg[d.y][d.x])
        continue;
      flg[d.y][d.x] = true;
      for (int j = 0; j < 4; j++) {
        int px = d.x + dx[j], py = d.y + dy[j];
        if (px < 0 || py < 0 || px >= w || py >= h)
          continue;
        if (field[py][px] == 'X')
          continue;
        Q.push(Data(px, py, d.count + 1));
      }
    }
    ans = start.count;
  }

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


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

int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
char field[1000][1000];
bool flg[1000][1000] = {{0}};

class Data {
public:
  int x, y, count;
  Data() {}
  Data(int x, int y, int count) : x(x), y(y), count(count) {}
};
int main() {
  int h, w, n;
  cin >> h >> w >> n;
  Data start;
  int ans = 0;
  for (int i = 0; i < h; i++) {
    cin >> field[i];
    for (int j = 0; j < w; j++) {
      if (field[i][j] == 'S') {
        start = Data(j, i, 0);
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    queue<Data> Q;
    Q.push(start);
    memset(flg, 0, sizeof(flg));
    while (!Q.empty()) {
      Data d = Q.front();
      Q.pop();
      if (field[d.y][d.x] == i + '0') {
        start = Data(d.x, d.y, d.count);
        break;
      }
      if (flg[d.y][d.x])
        continue;
      flg[d.y][d.x] = true;
      for (int j = 0; j < 4; j++) {
        int px = d.x + dx[j], py = d.y + dy[j];
        if (px < 0 || py < 0 || px >= w || py >= h)
          continue;
        if (field[py][px] == 'X')
          continue;
        Q.push(Data(px, py, d.count + 1));
      }
    }
    ans = start.count;
  }

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


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

#define INF 1 << 29

using namespace std;

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, -1, 0, 1};
char f[1003][1003];
int visited[1003][1003][10];

class S {
public:
  int x;
  int y;
  int lvl;
  int step;

  S(int x, int y, int lvl, int step) : x(x), y(y), lvl(lvl), step(step) {}
};

int main() {
  int h, w, lvl, sx, sy, gx, gy;
  cin >> h >> w >> lvl;
  fill((char *)f, (char *)f + 1003 * 1003, 'X');
  fill((int *)visited, (int *)visited + 1003 * 1003 * 10, INF);

  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      cin >> f[i][j];
      if (f[i][j] == 'S') {
        sx = j;
        sy = i;
      } else if (f[i][j] == lvl + '0') {
        gx = j;
        gy = i;
      }
    }
  }
  deque<S> q;
  q.push_back(S(sx, sy, 1, 0));
  visited[sy][sx][1] = 0;
  int px, py, tmplvl, tmpstep;
  while (!q.empty()) {
    px = q.front().x;
    py = q.front().y;
    tmplvl = q.front().lvl;
    tmpstep = q.front().step;
    q.pop_front();

    // printf("current:(y = %d, x = %d, lvl = %d, step = %d)\\n",
    // py,px,tmplvl,tmpstep);

    if (py == gy && px == gx && tmplvl == lvl + 1) {
      break;
    }
    visited[py][px][tmplvl] = tmpstep;
    for (int i = 0; i < 4; i++) {
      int nx = px + dx[i];
      int ny = py + dy[i];

      if (f[ny][nx] != 'X') {
        if (f[ny][nx] == tmplvl + '0') {
          q.push_back(S(nx, ny, tmplvl + 1, tmpstep + 1));
        } else {
          if (tmpstep + 1 < visited[ny][nx][tmplvl]) {
            q.push_back(S(nx, ny, tmplvl, tmpstep + 1));
            visited[ny][nx][tmplvl] = tmpstep + 1;
          }
        }
      }
    }
  }
  cout << tmpstep << endl;
}

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

#define INF 1 << 29

using namespace std;

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, -1, 0, 1};
char f[1003][1003];
bool visited[1003][1003][10];

class S {
public:
  int x;
  int y;
  int lvl;
  int step;

  S(int x, int y, int lvl, int step) : x(x), y(y), lvl(lvl), step(step) {}
};

int main() {
  int h, w, lvl, sx, sy, gx, gy;
  cin >> h >> w >> lvl;
  fill((char *)f, (char *)f + 1003 * 1003, 'X');
  fill((bool *)visited, (bool *)visited + 1003 * 1003 * 10, false);

  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      cin >> f[i][j];
      if (f[i][j] == 'S') {
        sx = j;
        sy = i;
      } else if (f[i][j] == lvl + '0') {
        gx = j;
        gy = i;
      }
    }
  }
  deque<S> q;
  q.push_back(S(sx, sy, 1, 0));
  visited[sy][sx][1] = true;
  int px, py, tmplvl, tmpstep;
  while (!q.empty()) {
    px = q.front().x;
    py = q.front().y;
    tmplvl = q.front().lvl;
    tmpstep = q.front().step;
    q.pop_front();

    // printf("current:(y = %d, x = %d, lvl = %d, step = %d)\\n",
    // py,px,tmplvl,tmpstep);

    if (py == gy && px == gx && tmplvl == lvl + 1) {
      break;
    }
    visited[py][px][tmplvl] = tmpstep;
    for (int i = 0; i < 4; i++) {
      int nx = px + dx[i];
      int ny = py + dy[i];

      if (f[ny][nx] != 'X') {
        if (f[ny][nx] == tmplvl + '0') {
          q.push_back(S(nx, ny, tmplvl + 1, tmpstep + 1));
        } else {
          if (!visited[ny][nx][tmplvl]) {
            q.push_back(S(nx, ny, tmplvl, tmpstep + 1));
            visited[ny][nx][tmplvl] = true;
          }
        }
      }
    }
  }
  cout << tmpstep << endl;
}


#include <iostream>
#include <queue>
#define x first
#define y second
#define rep(i, a, b) for (int i = a; i < b; i++)
using namespace std;
int h, w, k;
pair<int, int> p[12];
bool t[1010][1010], vis[1010][1010];
queue<pair<int, pair<int, int>>> Q;
int main() {
  cin >> h >> w >> k;
  rep(i, 0, h) rep(j, 0, w) {
    t[i][j] = true;
    char z;
    cin >> z;
    if (z == 'X')
      t[i][j] = 0;
    if (z == 'S')
      p[0] = make_pair(i, j);
    if (z > '0' && z <= '9')
      p[z - '0'] = make_pair(i, j);
  }
  int a = 0;
  rep(r, 0, k) {
    Q.push(make_pair(0, p[r]));
    rep(i, 0, h) rep(j, 0, w) vis[i][j] = 0;
    vis[p[r].x][p[r].y] = 1;
    while (1) {
      int L = Q.front().x, Y = Q.front().y.x, X = Q.front().y.y;
      if (Y == p[r + 1].x && X == p[r + 1].y) {
        a += L;
        break;
      }
      int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
      rep(i, 0, 4) {
        int f = Y + dy[i], g = X + dx[i];
        if (f >= 0 && f < h && g >= 0 && g < w) {
          if (t[f][g] == 1 && vis[f][g] == 0) {
            vis[Y][X] = 1;
            Q.push(make_pair(L + 1, make_pair(f, g)));
          }
        }
      }
      Q.pop();
    }
    while (!Q.empty())
      Q.pop();
  }
  cout << a << endl;
  return 0;
}

#include <iostream>
#include <queue>
#define x first
#define y second
#define rep(i, a, b) for (int i = a; i < b; i++)
using namespace std;
int h, w, k;
pair<int, int> p[12];
bool t[1010][1010], vis[1010][1010];
queue<pair<int, pair<int, int>>> Q;
int main() {
  cin >> h >> w >> k;
  rep(i, 0, h) rep(j, 0, w) {
    t[i][j] = true;
    char z;
    cin >> z;
    if (z == 'X')
      t[i][j] = 0;
    if (z == 'S')
      p[0] = make_pair(i, j);
    if (z > '0' && z <= '9')
      p[z - '0'] = make_pair(i, j);
  }
  int a = 0;
  rep(r, 0, k) {
    Q.push(make_pair(0, p[r]));
    rep(i, 0, h) rep(j, 0, w) vis[i][j] = 0;
    vis[p[r].x][p[r].y] = 1;
    while (1) {
      int L = Q.front().x, Y = Q.front().y.x, X = Q.front().y.y;
      if (Y == p[r + 1].x && X == p[r + 1].y) {
        a += L;
        break;
      }
      int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
      rep(i, 0, 4) {
        int f = Y + dy[i], g = X + dx[i];
        if (f >= 0 && f < h && g >= 0 && g < w) {
          if (t[f][g] == 1 && vis[f][g] == 0) {
            vis[f][g] = 1;
            Q.push(make_pair(L + 1, make_pair(f, g)));
          }
        }
      }
      Q.pop();
    }
    while (!Q.empty())
      Q.pop();
  }
  cout << a << endl;
  return 0;
}


#include <iostream>
#include <queue>
using namespace std;
struct Point {
  int x, y, dist;
};
int main() {
  int H, W, N;
  int vital;
  int i, j;
  string field[1000];
  int dx[4] = {0, 1, 0, -1};
  int dy[4] = {-1, 0, 1, 0};
  int sx, sy, ans;
  bool b;

  cin >> H >> W >> N;
  for (i = 0; i < H; i++)
    cin >> field[i];
  b = 1;
  for (i = 0; b && i < H; i++) {
    for (j = 0; b && j < W; j++) {
      if (field[i][j] == 'S') {
        sy = i;
        sx = j;
        ans = 0;
        b = 0;
      }
    }
  }

  for (vital = 1; vital <= N; vital++) {
    queue<Point> q;
    bool visited[1000][1000] = {0};
    bool f = 1;

    Point p = {sx, sy, 0};
    q.push(p);
    while (f) {
      Point p = q.front();
      q.pop();
      visited[p.y][p.x] = true;

      for (i = 0; f & i < 4; i++) {
        Point p2;
        p2.y = p.y + dy[i];
        p2.x = p.x + dx[i];
        p2.dist = p.dist + 1;
        if (p2.y < 0 || H <= p2.y)
          continue;
        if (p2.x < 0 || W <= p2.x)
          continue;
        if (field[p2.y][p2.x] == 'X')
          continue;
        if (visited[p2.y][p2.x])
          continue;
        if (field[p2.y][p2.x] == (vital + '0')) {
          sy = p2.y;
          sx = p2.x;
          ans += p2.dist;
          f = 0;
        }
        q.push(p2);
      }
    }
  }
  cout << ans << endl;
}

#include <iostream>
#include <queue>
using namespace std;
#define MAX 1000
struct Point {
  int x, y, dist;
};
int main() {
  int H, W, N;
  int vital;
  int i, j;
  char field[MAX][MAX];
  int dx[4] = {0, 1, 0, -1};
  int dy[4] = {-1, 0, 1, 0};
  int sx, sy, ans;

  cin >> H >> W >> N;
  for (i = 0; i < H; i++) {
    for (j = 0; j < W; j++) {
      cin >> field[i][j];
      if (field[i][j] == 'S') {
        sy = i;
        sx = j;
        ans = 0;
      }
    }
  }

  for (vital = 1; vital <= N; vital++) {
    queue<Point> q;
    bool visited[MAX][MAX] = {0};

    Point p = {sx, sy, 0}, p2;
    q.push(p);
    while (1) {
      p = q.front();
      q.pop();

      if (field[p.y][p.x] == (vital + '0')) {
        sy = p.y;
        sx = p.x;
        ans += p.dist;
        break;
      }

      for (i = 0; i < 4; i++) {
        p2.y = p.y + dy[i];
        p2.x = p.x + dx[i];
        p2.dist = p.dist + 1;
        if (p2.y < 0 || H <= p2.y)
          continue;
        if (p2.x < 0 || W <= p2.x)
          continue;
        if (field[p2.y][p2.x] == 'X')
          continue;
        if (visited[p2.y][p2.x])
          continue;
        visited[p2.y][p2.x] = true;
        q.push(p2);
      }
    }
  }
  cout << ans << endl;
}


#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
typedef pair<P, int> T;
char table[1000][1000];
bool done[1000][1000];
int H, W, N;
vector<P> cur;
vector<P> nex;
T search(T s, char goal) {
  memset(done, 0, sizeof(done));
  cur.clear();
  int dist = s.second;
  cur.push_back(s.first);
  int dx[4] = {0, 1, 0, -1};
  int dy[4] = {1, 0, -1, 0};
  while (true) {
    nex.clear();
    dist++;
    for (int i = 0; i < cur.size(); i++) {
      int x = cur[i].first;
      int y = cur[i].second;
      for (int j = 0; j < 4; j++) {
        int xx = x + dx[j];
        int yy = y + dy[j];
        if (0 <= xx && xx < H && 0 <= yy && yy < H && !done[xx][yy]) {
          done[xx][yy] = true;
          if (table[xx][yy] == 'X') {
          } else if (table[xx][yy] == goal) {
            return T(P(xx, yy), dist);
          } else {
            nex.push_back(P(xx, yy));
          }
        }
      }
    }
    nex.swap(cur);
  }
}
int main() {
  cin >> H >> W >> N;
  T s;
  for (int i = 0; i < H; i++) {
    scanf("%s", table[i]);
    for (int j = 0; j < W; j++) {
      if (table[i][j] == 'S') {
        s = T(P(i, j), 0);
      }
    }
  }
  for (int i = 0; i < N; i++) {
    s = search(s, '0' + i + 1);
  }
  cout << s.second << endl;
}

#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
typedef pair<P, int> T;
char table[1000][1000];
char done[1000][1000];
int H, W, N;
vector<P> cur;
vector<P> nex;
T search(T s, char goal) {
  cur.clear();
  int dist = s.second;
  cur.push_back(s.first);
  int dx[4] = {-1, 0, 0, 1};
  int dy[4] = {0, -1, 1, 0};
  while (true) {
    nex.clear();
    dist++;
    for (int i = 0; i < cur.size(); i++) {
      int x = cur[i].first;
      int y = cur[i].second;
      for (int j = 0; j < 4; j++) {
        int xx = x + dx[j];
        int yy = y + dy[j];
        if (0 <= xx && xx < H && 0 <= yy && yy < W && done[xx][yy] != goal) {
          done[xx][yy] = goal;
          if (table[xx][yy] == 'X') {
          } else if (table[xx][yy] == goal) {
            return T(P(xx, yy), dist);
          } else {
            nex.push_back(P(xx, yy));
          }
        }
      }
    }
    nex.swap(cur);
  }
}
int main() {
  cur.reserve(1000 * 1000);
  nex.reserve(1000 * 1000);
  // cin >> H >> W >> N;
  scanf("%d %d %d", &H, &W, &N);
  T s;
  for (int i = 0; i < H; i++) {
    scanf("%s", table[i]);
    for (int j = 0; j < W; j++) {
      if (table[i][j] == 'S') {
        s = T(P(i, j), 0);
      }
    }
  }
  for (int i = 0; i < N; i++) {
    s = search(s, '0' + i + 1);
  }
  printf("%d\\n", s.second);
}


// 待解，调用函数
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#define mp make_pair
using namespace std;
typedef pair<int, int> point;
const int maxn = 1005;
int height, width, n; // n代表硬度
char maze[maxn][maxn];
int dx[] = {0, 1, 0, -1};
int dy[] = {-1, 0, 1, 0};
bool visited[maxn][maxn];
int shortDistance(int sx, int sy, int ex, int ey) {
  // 初始化visted数组
  for (int i = 0; i < height; i++)
    for (int j = 0; j < width; j++)
      visited[i][j] = false;
  visited[sx][sy] = true;

  queue<pair<int, point>> q;
  q.push(mp(0, mp(sy, sx)));
  while (1) {
    pair<int, point> a = q.front();
    q.pop();
    int d = a.first, x = a.second.second, y = a.second.first;
    if (x == ex && y == ey) {
      return d;
    }
    for (int i = 0; i < 4; i++) {
      int nx = x + dx[i];
      int ny = y + dy[i];
      if (nx >= 0 && nx < width && ny >= 0 && ny < height &&
          maze[ny][nx] != 'X' && !visited[ny][nx]) {
        visited[ny][nx] = true;
        q.push(mp(d + 1, mp(ny, nx)));
      }
    }
  }
}

int main() {
  int cx[10], cy[10];
  int cnt = 0;
  // freopen("I:\\\\0558-in2.txt","r",stdin);
  scanf("%d%d%d", &height, &width, &n);
  //输入迷宫
  for (int i = 0; i < height; i++) {
    scanf("%s", maze[i]);
    //查找老鼠巢的位置
    for (int j = 0; j < width; j++) {
      if (maze[i][j] == 'S') {
        cy[0] = i;
        cx[0] = j;
      } else if (isdigit(maze[i][j])) {
        int k = maze[i][j] - '0';
        cx[k] = j;
        cy[k] = i;
      }
    }
  }
  int cost = 0;
  for (int i = 0; i < n; i++)
    cost += shortDistance(cx[i], cy[i], cx[i + 1], cy[i + 1]);
  cout << cost << endl;
  return 0;
}

// 待解，调用函数
#include <cctype>
#include <cstdio>
#include <queue>
#define mp make_pair
using namespace std;
typedef pair<int, int> point;
const int maxn = 1005;
int height, width; // n代表硬度
char maze[maxn][maxn];
const int dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};

bool visited[maxn][maxn];
int shortDistance(int sx, int sy, int ex, int ey) {
  // 初始化visted数组
  for (int i = 0; i < height; i++)
    for (int j = 0; j < width; j++)
      visited[i][j] = false;
  visited[sy][sx] = true;
  queue<pair<int, point>> q;
  q.push(mp(0, mp(sy, sx)));
  while (1) {
    pair<int, point> a = q.front();
    q.pop();
    int d = a.first, x = a.second.second, y = a.second.first;
    if (x == ex && y == ey) {
      return d;
    }
    for (int i = 0; i < 4; i++) {
      int xx = x + dx[i], yy = y + dy[i];
      if (0 <= xx && xx < width && 0 <= yy && yy < height &&
          maze[yy][xx] != 'X' && !visited[yy][xx]) {
        visited[yy][xx] = true;
        q.push(mp(d + 1, mp(yy, xx)));
      }
    }
  }
}

int main() {
  int cx[10], cy[10], n;
  // freopen("I:\\\\0558-in2.txt","r",stdin);
  scanf("%d%d%d", &height, &width, &n);
  //输入迷宫
  for (int i = 0; i < height; i++) {
    scanf("%s", maze[i]);
    //查找老鼠巢的位置
    for (int j = 0; j < width; j++) {
      if (maze[i][j] == 'S') {
        cy[0] = i;
        cx[0] = j;
      } else if (isdigit(maze[i][j])) {
        int k = maze[i][j] - '0';
        cx[k] = j;
        cy[k] = i;
      }
    }
  }
  int cost = 0;

  for (int i = 0; i < n; i++)
    cost += shortDistance(cx[i], cy[i], cx[i + 1], cy[i + 1]);
  printf("%d\\n", cost);
  return 0;
}


#include <iostream>
#include <stdlib.h>
#include <vector>

using namespace std;

int H, W;
char N;
vector<vector<char>> _map(H, vector<char>(W));
int num = 1;

int solve(int i, int j, int c) {
  if (_map[i][j] == N)
    return c;
  for (int dx = -1; dx <= 1; dx++) {
    for (int dy = -1; dy <= 1; dy++) {
      if (dx != dy && dx != -1 * dy && (j + dx < W && i + dy < H)) {
        int tmp;
        tmp = static_cast<char>(num);
        if (_map[i + dy][j + dx] == tmp || _map[i + dy][j + dx] == '.') {
          num++;
          solve(i + dy, j + dx, c + 1);
        }
      }
    }
  }
  return 0;
}

int main() {
  cin >> H >> W >> N;
  int x, y;
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      cin >> _map[i][j];
      if (_map[i][j] == 'S') {
        x = j;
        y = i;
      }
    }
  }
  cout << solve(y, x, 0) << endl;
}

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <vector>
using namespace std;

const int INF = 100000000;
typedef pair<int, int> P;
int sx, sy;

char _map[1000][1001];
int H, W;
char N;
char n = '1';

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

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

int bfs() {
  int ans = 0;
  queue<P> que;
  init();
  que.push(P(sx, sy));
  d[sx][sy] = 0;

  while (que.size()) {
    P p = que.front();
    que.pop();
    if (_map[p.first][p.second] == n) {
      if (n == N) {
        ans += d[p.first][p.second];
        break;
      } else {
        ans += d[p.first][p.second];
        init();
        queue<P> empty;
        swap(que, empty);
        sx = p.first;
        sy = p.second;
        d[sx][sy] = 0;
        n++;
      }
    }
    for (int i = 0; i < 4; i++) {
      int nx = p.first + dx[i], ny = p.second + dy[i];

      if (0 <= nx && nx < H && 0 <= ny && ny < W && _map[nx][ny] != 'X' &&
          d[nx][ny] == INF) {
        que.push(P(nx, ny));
        d[nx][ny] = d[p.first][p.second] + 1;
      }
    }
  }
  return ans;
}

void solve() {
  int res = bfs();
  cout << res << endl;
}

int main() {
  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') {
        sx = i;
        sy = j;
      }
    }
  }
  solve();
}


#include <algorithm>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

#define START 'S'
#define CANTGO 'X'
#define NONE '.'
#define FINUM field[i][j] - '0'

struct Point {
  int x;
  int y;
};

int dx[] = {0, -1, 0, 1}; // ã©çvñè
int dy[] = {1, 0, -1, 0};
string field[1000];
int mfield[1001][1001] = {};
int life = 1;
int counter = 0;
int csum = 0;
int H, W, N;

int open(vector<Point> &tp) {
  counter++;
  int i, j;
  Point inp;
  int size = tp.size();
  vector<Point>::iterator it;

  for (i = 0; i < size; i++) {
    for (j = 0; j < 4; j++) {
      inp.x = tp[i].x + dx[j];
      inp.y = tp[i].y + dy[j];
      if (inp.x < 0 || inp.y < 0 || inp.x >= H || inp.y >= W)
        continue;
      if (field[inp.x][inp.y] != CANTGO && field[inp.x][inp.y] != START &&
          mfield[inp.x][inp.y] != life) {
        // v·éÉÅZ£Ú®Â\\][
        if (field[inp.x][inp.y] ==
            life + '0') // ©ªÉ©Á½`[YÌ©
        {
          tp.clear();
          tp.push_back(inp);
          return counter;
        } else {
          tp.push_back(inp);
          mfield[inp.x][inp.y] = life;
        }
      }
    }
  }
  for (i = 0; i < size; i++) {
    it = tp.begin();
    tp.erase(it);
  }
  // copy(tp.begin() , tp.end() , tp.begin());
  return 0;
}

int main(void) {
  int i, j;
  vector<Point> tp;
  Point inp;
  Point gool;
  int count = 0;
  cin >> H >> W >> N;

  for (i = 0; i < H; i++) // üÍ
  {
    cin >> field[i];
    for (j = 0; j < W; j++) {
      if (field[i][j] == 'S') {
        inp.x = i;
        inp.y = j;
        tp.push_back(inp);
        mfield[inp.x][inp.y] = life;
      }
    }
  } // üÍIíè

  while (1) {
    if (open(tp) != 0) {
      life++;
      csum += counter;
      counter = 0;
    }
    if (life > N)
      break;
  }
  cout << csum << endl;

  return 0;
}

#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
using namespace std;
typedef pair<unsigned short, unsigned short> P;
typedef pair<unsigned char, int> T;
typedef pair<T, P> PP;
#define rep(i, n) for (i = 0; i < n; i++)
#define MAX 1000
char F[MAX][MAX];
char Dx[] = {1, 0, -1, 0}, Dy[] = {0, 1, 0, -1};
unsigned short h, w, n, x, y, nx, ny;
P dist[10];
int bfs() {
  bool used[9][MAX][MAX] = {};
  int c, res = 0, u = 0;
  unsigned char t, i;
  PP p;
  queue<PP> q;
  rep(i, 9) q.push(PP(T(i + '1', 0), dist[i]));
  while (!q.empty()) {
    p = q.front();
    q.pop();
    t = p.first.first;
    if (u & (1 << (t - '1')))
      continue;
    c = p.first.second;
    x = p.second.first;
    y = p.second.second;
    c++;
    rep(i, 4) {
      nx = x + Dx[i];
      ny = y + Dy[i];
      if (nx < w && ny < h && F[ny][nx] != 'X' && !used[t - '1'][ny][nx]) {
        used[t - '1'][ny][nx] = true;
        if (F[ny][nx] == t) {
          u |= (1 << (t - '1'));
          res += c;
        } else {
          q.push(PP(T(t, c), P(nx, ny)));
        }
      }
    }
  }
  return res;
}
int main(void) {
  unsigned short i, j;
  int res;
  scanf("%hd%hd%hd", &h, &w, &n);
  rep(i, h) rep(j, w) {
    scanf(" %c", F[i] + j);
    if (F[i][j] == 'S')
      dist[0] = P(j, i);
    else if (F[i][j] != 'X' && F[i][j] != '.')
      dist[F[i][j] - '0'] = P(j, i);
  }
  res = bfs();
  printf("%d\\n", res);
  return 0;
}


#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <string>
// #include <functional>
#include <cstdio>
#include <fstream>
#include <queue>
using namespace std;

#define START 'S'
#define CANTGO 'X'
#define NONE '.'
#define FINUM field[i][j] - '0'

struct Point {
  int x;
  int y;
};

int dx[] = {0, -1, 0, 1}; // ã©çvñè
int dy[] = {1, 0, -1, 0};
string field[1000];
int mfield[1001][1001] = {};
int life = 1;
int csum = 0;
int H, W, N;

int open(Point gool) {
  int counter = 0;
  queue<Point> tp;
  tp.push(gool);
  int i, j;
  Point inp;
  Point p;
  while (1) {
    counter++;
    int size = tp.size();
    for (i = 0; i < size; i++) {
      p = tp.front();
      tp.pop();
      for (j = 0; j < 4; j++) {
        inp.x = p.x + dx[j];
        inp.y = p.y + dy[j];
        if (inp.x < 0 || inp.y < 0 || inp.y >= H || inp.x >= W)
          continue;
        if (field[inp.y][inp.x] != CANTGO && mfield[inp.y][inp.x] != life) {
          // v·éÉÅZ£Ú®Â\\][
          if (field[inp.y][inp.x] ==
              life + '0') // ©ªÉ©Á½`[YÌ©
          {
            return counter;
          } else {
            tp.push(inp);
            mfield[inp.y][inp.x] = life;
          }
        }
      }
    }
    /*for(i=0;i<H;i++)
    {
            for(j=0;j<W;j++)
            {
                    cout << mfield[i][j];
            }
            cout << endl;
    }*/
  }
  // copy(tp.begin() , tp.end() , tp.begin());
  return 0;
}

int main(void) {
  int i, j;
  queue<Point> tp;
  Point top[10];
  Point inp;
  int count = 0;
  int counter = 0;
  cin >> H >> W >> N;

  for (i = 0; i < H; i++) // üÍ
  {
    cin >> field[i];
    for (j = 0; j < W; j++) {
      if (field[i][j] == 'S') {
        top[0].y = i;
        top[0].x = j;
        mfield[j][i] = life;
      }
      if (field[i][j] >= '0' && field[i][j] <= '9') {
        top[field[i][j] - '0'].y = i;
        top[field[i][j] - '0'].x = j;
      }
    }
  } // üÍIíè

  while (1) {
    if ((counter = open(top[life - 1])) != 0) {
      life++;
      csum += counter;
    }
    if (life > N)
      break;
  }
  cout << csum << endl;

  return 0;
}

#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <string>
// #include <functional>
#include <cstdio>
#include <fstream>
#include <queue>
using namespace std;

#define START 'S'
#define CANTGO 'X'
#define NONE '.'
#define FINUM field[i][j] - '0'

struct Point {
  int x;
  int y;
};

int dx[] = {0, -1, 0, 1}; // ã©çvñè
int dy[] = {1, 0, -1, 0};
string field[1000];
int mfield[1001][1001] = {};
int life = 1;
int csum = 0;
int H, W, N;

int open(Point gool) {
  int counter = 0;
  queue<Point> tp;
  tp.push(gool);
  int i, j;
  Point inp;
  Point p;
  while (1) {
    counter++;
    int size = tp.size();
    for (i = 0; i < size; i++) {
      p = tp.front();
      tp.pop();
      for (j = 0; j < 4; j++) {
        inp.x = p.x + dx[j];
        inp.y = p.y + dy[j];
        if (inp.x < 0 || inp.y < 0 || inp.y >= H || inp.x >= W)
          continue;
        if (field[inp.y][inp.x] != CANTGO && mfield[inp.y][inp.x] != life) {
          // v·éÉÅZ£Ú®Â\\][
          if (field[inp.y][inp.x] ==
              life + '0') // ©ªÉ©Á½`[YÌ©
          {
            return counter;
          } else {
            tp.push(inp);
            mfield[inp.y][inp.x] = life;
          }
        }
      }
    }
    /*for(i=0;i<H;i++)
    {
            for(j=0;j<W;j++)
            {
                    cout << mfield[i][j];
            }
            cout << endl;
    }*/
  }
  // copy(tp.begin() , tp.end() , tp.begin());
  return 0;
}

int main(void) {
  int i, j;
  queue<Point> tp;
  Point top[10];
  Point inp;
  int count = 0;
  int counter = 0;
  cin >> H >> W >> N;

  for (i = 0; i < H; i++) // üÍ
  {
    cin >> field[i];
    for (j = 0; j < W; j++) {
      if (field[i][j] == 'S') {
        top[0].y = i;
        top[0].x = j;
        mfield[i][j] = life;
      }
      if (field[i][j] >= '0' && field[i][j] <= '9') {
        top[field[i][j] - '0'].y = i;
        top[field[i][j] - '0'].x = j;
      }
    }
  } // üÍIíè

  while (1) {
    if ((counter = open(top[life - 1])) != 0) {
      life++;
      csum += counter;
    }
    if (life > N)
      break;
  }
  cout << csum << endl;

  return 0;
}


#include <iostream>
#include <queue>
using namespace std;
int h, w, n, ans = 0;
char c[1002][1002];
pair<int, int> a[12], pi;
bool f[1002][1002];

int dist(pair<int, int> s, pair<int, int> g) {
  for (int i = 0; i < 1002; i++)
    for (int j = 0; j < 1002; j++)
      f[i][j] = false;
  // cout<<s.first<<","<<s.second<<" "<<g.first<<","<<g.second<<endl;
  queue<pair<pair<int, int>, int>> que;
  pair<pair<int, int>, int> p;
  p.first = s;
  p.second = 0;
  que.push(p);
  while (que.size() > 0) {
    p = que.front();
    que.pop();
    if (p.first == g)
      return p.second;
    f[p.first.first][p.first.second] = true;
    // cout<<p.first.first<<","<<p.first.second<<endl;
    // if(p.first.first==g.first&&p.first.second==g.second)return p.second;
    if (c[p.first.first - 1][p.first.second] != 'X' &&
        !f[p.first.first - 1][p.first.second]) {
      p.first.first--;
      p.second++;
      que.push(p);
      p.first.first++;
      p.second--;
    }
    if (c[p.first.first + 1][p.first.second] != 'X' &&
        !f[p.first.first + 1][p.first.second]) {
      p.first.first++;
      p.second++;
      que.push(p);
      p.first.first--;
      p.second--;
    }
    if (c[p.first.first][p.first.second - 1] != 'X' &&
        !f[p.first.first][p.first.second - 1]) {
      p.first.second--;
      p.second++;
      que.push(p);
      p.first.second++;
      p.second--;
    }
    if (c[p.first.first][p.first.second + 1] != 'X' &&
        !f[p.first.first][p.first.second + 1]) {
      p.first.second++;
      p.second++;
      que.push(p);
      p.first.second--;
      p.second--;
    }
  }
  return -1;
}

int main() {
  scanf("%d%d%d", &h, &w, &n);
  for (int i = 0; i < 1002; i++)
    for (int j = 0; j < 1002; j++)
      c[i][j] = 'X';
  for (int i = 1; i <= h; i++) {
    scanf("\\n");
    for (int j = 1; j <= w; j++) {
      scanf("%c", &c[i][j]);
      if ('1' <= c[i][j] && c[i][j] <= '9') {
        a[c[i][j] - 48].first = i;
        a[c[i][j] - 48].second = j;
      }
      if (c[i][j] == 'S') {
        a[0].first = i;
        a[0].second = j;
      }
    }
  }
  /*for(int i=1;i<=h;i++){
          for(int j=1;j<=w;j++){
                  printf("%c",c[i][j]);
          }
          printf("\\n");
  }*/
  for (int i = 1; i <= n; i++) {
    // cout<<i<<endl;
    ans += dist(a[i - 1], a[i]);
  }
  printf("%d\\n", ans);
}

#include <iostream>
#include <queue>
using namespace std;
int h, w, n, ans = 0;
char c[1002][1002];
pair<int, int> a[12], pi;
bool f[1002][1002];

int dist(pair<int, int> s, pair<int, int> g) {
  for (int i = 0; i < 1002; i++)
    for (int j = 0; j < 1002; j++)
      f[i][j] = false;
  // cout<<s.first<<","<<s.second<<" "<<g.first<<","<<g.second<<endl;
  queue<pair<pair<int, int>, int>> que;
  pair<pair<int, int>, int> p;
  p.first = s;
  p.second = 0;
  que.push(p);
  while (que.size() > 0) {
    p = que.front();
    que.pop();
    if (p.first == g)
      return p.second;
    f[p.first.first][p.first.second] = true;
    // cout<<p.first.first<<","<<p.first.second<<endl;
    // if(p.first.first==g.first&&p.first.second==g.second)return p.second;
    if (c[p.first.first - 1][p.first.second] != 'X' &&
        !f[p.first.first - 1][p.first.second]) {
      p.first.first--;
      p.second++;
      que.push(p);
      p.first.first++;
      p.second--;
      f[p.first.first - 1][p.first.second] = true;
    }
    if (c[p.first.first + 1][p.first.second] != 'X' &&
        !f[p.first.first + 1][p.first.second]) {
      p.first.first++;
      p.second++;
      que.push(p);
      p.first.first--;
      p.second--;
      f[p.first.first + 1][p.first.second] = true;
    }
    if (c[p.first.first][p.first.second - 1] != 'X' &&
        !f[p.first.first][p.first.second - 1]) {
      p.first.second--;
      p.second++;
      que.push(p);
      p.first.second++;
      p.second--;
      f[p.first.first][p.first.second - 1] = true;
    }
    if (c[p.first.first][p.first.second + 1] != 'X' &&
        !f[p.first.first][p.first.second + 1]) {
      p.first.second++;
      p.second++;
      que.push(p);
      p.first.second--;
      p.second--;
      f[p.first.first][p.first.second + 1] = true;
    }
  }
  return -1;
}

int main() {
  scanf("%d%d%d", &h, &w, &n);
  for (int i = 0; i < 1002; i++)
    for (int j = 0; j < 1002; j++)
      c[i][j] = 'X';
  for (int i = 1; i <= h; i++) {
    scanf("\\n");
    for (int j = 1; j <= w; j++) {
      scanf("%c", &c[i][j]);
      if ('1' <= c[i][j] && c[i][j] <= '9') {
        a[c[i][j] - 48].first = i;
        a[c[i][j] - 48].second = j;
      }
      if (c[i][j] == 'S') {
        a[0].first = i;
        a[0].second = j;
      }
    }
  }
  /*for(int i=1;i<=h;i++){
          for(int j=1;j<=w;j++){
                  printf("%c",c[i][j]);
          }
          printf("\\n");
  }*/
  for (int i = 1; i <= n; i++) {
    // cout<<i<<endl;
    ans += dist(a[i - 1], a[i]);
  }
  printf("%d\\n", ans);
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

typedef long long ll;

using namespace std;

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

int main() {
  int h, w, n, ans = 0;
  bool fl[1000][1000] = {0};
  char in[1000][1001];
  queue<pair<int, int>> qp;
  pair<int, int> p;

  scanf("%d%d%d", &h, &w, &n);

  for (int i = 0; i < h; i++)
    scanf("%s", in[i]);

  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      if (in[i][j] == 'S') {
        qp.push(make_pair(i, j));
        qp.push(make_pair(-5, -5));
        break;
      }

  for (int i = 1; i <= n; i++) {
    while (1) {
      p = qp.front();
      qp.pop();
      if (p.first == -5 && p.second == -5) {
        ans++;
        qp.push(make_pair(-5, -5));
        continue;
      }
      if (p.first < 0 || h <= p.first || p.second < 0 || w <= p.second ||
          fl[p.first][p.second])
        continue;
      if (in[p.first][p.second] == '0' + i)
        break;
      if (in[p.first][p.second] == 'X')
        continue;

      for (int j = 0; j < 4; j++)
        qp.push(make_pair(p.first + mo[j], p.second + mo[(j + 1) % 4]));
    }
    while (!qp.empty())
      qp.pop();
    qp.push(make_pair(p.first, p.second));
    qp.push(make_pair(-5, -5));
  }

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

  return 0;
}

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

typedef long long ll;

using namespace std;

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

int main() {
  int h, w, n, ans = 0;
  bool fl[1000][1000] = {0};
  char in[1000][1001];
  queue<pair<int, int>> qp;
  pair<int, int> p;

  scanf("%d%d%d", &h, &w, &n);

  for (int i = 0; i < h; i++)
    scanf("%s", in[i]);

  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++)
      if (in[i][j] == 'S') {
        qp.push(make_pair(i, j));
        qp.push(make_pair(-5, -5));
        break;
      }

  for (int i = 1; i <= n; i++) {
    while (1) {
      p = qp.front();
      qp.pop();
      if (p.first == -5 && p.second == -5) {
        ans++;
        qp.push(make_pair(-5, -5));
        continue;
      }
      if (p.first < 0 || h <= p.first || p.second < 0 || w <= p.second ||
          fl[p.first][p.second])
        continue;
      if (in[p.first][p.second] == '0' + i)
        break;
      if (in[p.first][p.second] == 'X')
        continue;

      fl[p.first][p.second] = true;

      for (int j = 0; j < 4; j++)
        qp.push(make_pair(p.first + mo[j], p.second + mo[(j + 1) % 4]));
    }
    while (!qp.empty())
      qp.pop();
    qp.push(make_pair(p.first, p.second));
    qp.push(make_pair(-5, -5));

    for (int k = 0; k < h; k++)
      for (int j = 0; j < w; j++)
        fl[k][j] = false;
  }

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

  return 0;
}


#include <algorithm>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <ios>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define XINF INT_MAX
#define INF 1 << 30
#define MAXN 0x7fffffff
#define eps 1e-8
#define zero(a) fabs(a) < eps
#define sqr(a) ((a) * (a))
#define MP(X, Y) make_pair(X, Y)
#define PB(X) push_back(X)
#define PF(X) push_front(X)
#define REP(X, N) for (int X = 0; X < N; X++)
#define REP2(X, L, R) for (int X = L; X <= R; X++)
#define DEP(X, R, L) for (int X = R; X >= L; X--)
#define CLR(A, X) memset(A, X, sizeof(A))
#define IT iterator
#define PI acos(-1.0)
#define test puts("OK");
typedef long long ll;
typedef pair<int, int> PII;
typedef priority_queue<int, vector<int>, greater<int>> PQI;
typedef vector<PII> VII;
typedef vector<int> VI;
#define X first
#define Y second

char maps[1000 + 10][1000 + 10];
int dis[1000 + 10][1000 + 10];
bool vis[1000 + 10][1000 + 10];
const int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
PII fac[20];
int h, w, n;

int bfs(int sx, int sy, int ex, int ey) {
  CLR(vis, 0);
  CLR(dis, 0);
  queue<PII> Q;
  Q.push(MP(sx, sy));
  while (!Q.empty()) {
    PII p = Q.front();
    Q.pop();
    if (p.X == ex && p.Y == ey)
      break;
    vis[p.X][p.Y] = 1;
    REP(i, 4) {
      int tx = p.X + dir[i][0];
      int ty = p.Y + dir[i][1];
      if (tx >= 0 && tx < h && ty >= 0 && ty < w && !vis[tx][ty] &&
          maps[tx][ty] != 'X') {
        Q.push(MP(tx, ty));
        dis[tx][ty] = dis[p.X][p.Y] + 1;
      }
    }
  }
  return dis[ex][ey];
}

int main() {
  ios::sync_with_stdio(false);
  cin >> h >> w >> n;
  REP(i, h)
  REP(j, w) {
    cin >> maps[i][j];
    if (maps[i][j] == 'S') {
      fac[0] = MP(i, j);
      maps[i][j] = '.';
    }
    if (isdigit(maps[i][j]))
      fac[maps[i][j] - '0'] = MP(i, j);
  }
  int ans = 0;
  REP(i, n)
  ans += bfs(fac[i].X, fac[i].Y, fac[i + 1].X, fac[i + 1].Y);
  cout << ans << endl;
  return 0;
}

//
//  AOJ 0558 Chees
//
//  Created by TaoSama on 2015-02-20
//  Copyright (c) 2014 TaoSama. All rights reserved.
//
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>
#define CLR(x, y) memset(x, y, sizeof(x))

using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;

struct Point {
  int x, y;
  Point(int x = 0, int y = 0) : x(x), y(y) {}
} c[15];
int n, m, k, dp[1005][1005];
int d[4][2] = {-1, 0, 1, 0, 0, 1, 0, -1};
char a[1005][1005];

int bfs(int x) {
  memset(dp, 0x3f, sizeof dp);
  queue<Point> q;
  q.push(c[x - 1]);
  dp[c[x - 1].x][c[x - 1].y] = 0;
  while (!q.empty()) {
    Point cur = q.front();
    q.pop();
    for (int i = 0; i < 4; ++i) {
      Point nxt(cur.x + d[i][0], cur.y + d[i][1]);
      if (nxt.x < 1 || nxt.x > n || nxt.y < 1 || nxt.y > m ||
          a[nxt.x][nxt.y] == 'X')
        continue;
      if (dp[nxt.x][nxt.y] == INF) {
        dp[nxt.x][nxt.y] = dp[cur.x][cur.y] + 1;
        q.push(nxt);
      }
    }
  }
  return dp[c[x].x][c[x].y];
}
int main() {
#ifdef LOCAL
  freopen("in.txt", "r", stdin);
//	freopen("out.txt","w",stdout);
#endif
  ios_base::sync_with_stdio(0);

  while (cin >> n >> m >> k) {
    for (int i = 1; i <= n; ++i) {
      for (int j = 1; j <= m; ++j) {
        cin >> a[i][j];
        if (a[i][j] == 'S')
          c[0].x = i, c[0].y = j;
        if (isdigit(a[i][j]))
          c[a[i][j] - '0'].x = i, c[a[i][j] - '0'].y = j;
      }
    }
    int ans = 0;
    for (int i = 1; i <= k; ++i)
      ans += bfs(i);
    cout << ans << endl;
  }
  return 0;
}


#include <cstring>
#include <iostream>
#include <queue>
#include <utility>
using namespace std;
#define INF 10000000
#define rep(i, s, t) for (int i = s; i <= (t); i++)
#define MP(a, b) make_pair(a, b)
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
int h, w, n;
char m[1000][1000];

int bfs(int s) {
  static int d[1000][1000];
  queue<pair<int, int>> q;
  pair<int, int> a, b;
  rep(i, 1, h) rep(j, 1, w) if (m[i][j] == '0' + s) {
    d[i][j] = 0;
    q.push(MP(i, j));
  }
  else d[i][j] = INF;
  while (1) {
    a = q.front();
    q.pop();
    rep(k, 0, 3) {
      b = MP(a.first + dy[k], a.second + dx[k]);
      if (m[b.first][b.second] == 'X')
        continue;
      if (d[a.first][a.second] + 1 < d[b.first][b.second]) {
        d[b.first][b.second] = d[a.first][a.second] + 1;
        if (m[b.first][b.second] == '0' + s + 1)
          return d[b.first][b.second];
        q.push(b);
      }
    }
  }
  return -1;
}
int main() {
  cin >> h >> w >> n;
  memset(m, 'X', sizeof(m));
  rep(i, 1, h) rep(j, 1, w) {
    cin >> m[i][j];
    if (m[i][j] == 'S')
      m[i][j] = '0';
  }
  int ans = 0;
  rep(i, 0, n - 1) ans += bfs(i);
  cout << ans << endl;
}

#include <cstring>
#include <iostream>
#include <queue>
#include <utility>
using namespace std;
#define INF 10000000
#define rep(i, s, t) for (int i = s; i <= (t); i++)
#define MP(a, b) make_pair(a, b)
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
int h, w, n;
char m[1002][1002];

int bfs(int s) {
  static int d[1002][1002];
  queue<pair<int, int>> q;
  pair<int, int> a, b;
  rep(i, 1, h) rep(j, 1, w) if (m[i][j] == '0' + s) {
    d[i][j] = 0;
    q.push(MP(i, j));
  }
  else d[i][j] = INF;
  while (1) {
    a = q.front();
    q.pop();
    rep(k, 0, 3) {
      b = MP(a.first + dy[k], a.second + dx[k]);
      if (m[b.first][b.second] == 'X')
        continue;
      if (d[a.first][a.second] + 1 < d[b.first][b.second]) {
        d[b.first][b.second] = d[a.first][a.second] + 1;
        if (m[b.first][b.second] == '0' + s + 1)
          return d[b.first][b.second];
        q.push(b);
      }
    }
  }
  return -1;
}
int main() {
  cin >> h >> w >> n;
  memset(m, 'X', sizeof(m));
  rep(i, 1, h) rep(j, 1, w) {
    cin >> m[i][j];
    if (m[i][j] == 'S')
      m[i][j] = '0';
  }
  int ans = 0;
  rep(i, 0, n - 1) ans += bfs(i);
  cout << ans << endl;
}


#include <cctype>
#include <iostream>
#include <map>
#include <queue>
#include <stdio.h>
#include <stdlib.h>

#define p(s) puts("s")

using namespace std;
// from は残りのチーズ数
int bfs(int from);
// 訪れたら1
typedef pair<int, int> P;
char atlas[1000][1000] = {0};

int h, w, n;
// int start_i , start_j;
int dj[] = {0, 1, 0, -1};
int di[] = {-1, 0, 1, 0};

int main(int argc, char const *argv[]) {
  // 行数 一行の長さ 工場の数
  cin >> h >> w >> n;
  // atlas配列初期化&start位置取得
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cin >> atlas[i][j];
      // if (atlas[i][j]== 'S')
      //{
      //     P start = pair<int, int>(i, j);
      // }
    }
  }

  int sum = 0;
  for (int i = 0; i < n; i++) {
    // cout << "--------------------------------------------------" << endl;
    // cout << "call bfs(" << i << ")" << endl;
    sum += bfs(i);
    // cout << "bfs(" << i << ")  = " << bfs(i) << endl;
  }
  cout << sum << endl;
  return 0;
}

// チーズsからs+1までの最短経路を返す関数
// start_indexを渡さないと行けない
int bfs(int s) {
  // cout << "enter bfs(" << s << ")"  << endl;

  // スタートを取得
  P start;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (s == 0 && atlas[i][j] == 'S') {
        start = P(i, j);
      } // cout<< "start = "<<  i << ", " <<j <<endl; }
      else if (s != 0 && atlas[i][j] == '0' + s) {
        start = P(i, j);
      } // cout<< "start = "<<  i << ", " <<j <<endl; }
    }
  }

  // is_visit初期化
  int is_visit[1000][1000] = {0};
  queue<P> q;
  map<P, int> dis;

  // 一つ入れる
  q.push(start);
  dis[start] = 0;

  while (q.size()) {
    // 一つ取り出す
    P now = q.front();
    q.pop();

    // 終了判定
    if (atlas[now.first][now.second] == '0' + s + 1) {
      // cout << "end of bfs(" << s << ")" << "now = (" << now.first <<"
      // ,"<<now.second <<")"<< endl;
      return dis[now];
    }

    // 分岐
    for (int i = 0; i < 4; i++) {
      P next = P(now.first + di[i], now.second + dj[i]);
      // 訪れてないか　枠の中か 障害物は無いか
      if (next.first < h && next.second < w && dis.find(next) == dis.end() &&
          atlas[next.first][next.second] != 'X') {
        q.push(next);
        dis[next] = dis[now] + 1;
      }
    }
  }
}

#include <cctype>
#include <iostream>
#include <map>
#include <queue>
#include <stdio.h>
#include <stdlib.h>

#define p(s) puts("s")

using namespace std;
// from は残りのチーズ数
int bfs(int from);
// 訪れたら1
typedef pair<int, int> P;
char atlas[1000][1000] = {0};

int h, w, n;
// int start_i , start_j;
int dj[] = {0, 1, 0, -1};
int di[] = {-1, 0, 1, 0};

int main(int argc, char const *argv[]) {
  // 行数 一行の長さ 工場の数
  cin >> h >> w >> n;
  // atlas配列初期化&start位置取得
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cin >> atlas[i][j];
    }
  }

  int sum = 0;
  for (int i = 0; i < n; i++) {
    // cout << "--------------------------------------------------" << endl;
    // cout << "call bfs(" << i << ")" << endl;
    sum += bfs(i);
    // cout << "bfs(" << i << ")  = " << bfs(i) << endl;
  }
  cout << sum << endl;
  return 0;
}

// チーズsからs+1までの最短経路を返す関数
int bfs(int s) {
  // cout << "enter bfs(" << s << ")"  << endl;

  // スタートを取得
  P start;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      // s==0  0=>S
      if (s == 0 && atlas[i][j] == 'S') {
        start = P(i, j);
      } // cout<< "start = "<<  i << ", " <<j <<endl; }
      else if (s != 0 && atlas[i][j] == '0' + s) {
        start = P(i, j);
      } // cout<< "start = "<<  i << ", " <<j <<endl; }
    }
  }

  // is_visit初期化
  int is_visit[1000][1000] = {0};
  queue<P> q;
  // map初期化
  map<P, int> dis;

  // 一つ入れる
  q.push(start);
  dis[start] = 0;

  while (q.size()) {
    // 一つ取り出す
    P now = q.front();
    q.pop();

    // 終了判定
    if (atlas[now.first][now.second] == '0' + s + 1) {
      // cout << "end of bfs(" << s << ")" << "now = (" << now.first <<"
      // ,"<<now.second <<")"<< endl;
      return dis[now];
    }

    // 分岐
    for (int i = 0; i < 4; i++) {
      P next = P(now.first + di[i], now.second + dj[i]);
      // 訪れてないか　枠の中か 障害物は無いか
      if (-1 < next.first && next.first < h && -1 < next.second &&
          next.second < w && dis.find(next) == dis.end() &&
          atlas[next.first][next.second] != 'X') {
        q.push(next);
        dis[next] = dis[now] + 1;
      }
    }
  }
}


#include <cctype>
#include <cstdio>
#include <queue>
#include <vector>

using namespace std;

struct Position {
  int h, w, time, strength;
  Position(int h, int w, int t, int s) : h(h), w(w), time(t), strength(s) {}
};

const int max_h = 1005;
const int max_w = 1005;
int g_h, g_w, g_strength, g_max_strength, si, sj;
char mat[max_h][max_w];
pair<int, int> factories[20];
int dh[] = {0, 1, 0, -1};
int dw[] = {1, 0, -1, 0};

int main() {
  scanf("%d%d%d", &g_h, &g_w, &g_max_strength);
  for (int i = 0; i < g_h; i++) {
    getchar();
    for (int j = 0; j < g_w; j++) {
      mat[i][j] = getchar();
      if (mat[i][j] == 'S') {
        si = i;
        sj = j;
        mat[i][j] = '.';
      } else if (isdigit(mat[i][j])) {
        factories[mat[i][j] - '0'].first = i;
        factories[mat[i][j] - '0'].second = j;
        mat[i][j] = '.';
      }
    }
  }
  queue<Position> q;
  g_strength = 1;
  q.push(Position(si, sj, 0, 1));
  int result = -1;
  while (!q.empty()) {
    Position p = q.front();
    q.pop();
    if (p.strength < g_strength)
      continue;
    pair<int, int> f = factories[p.strength];
    if (p.h == f.first && p.w == f.second) {
      if (p.strength == g_max_strength) {
        result = p.time;
        break;
      }
      p.strength++;
      g_strength++;
    }
    mat[p.h][p.w] = p.strength + '0';
    for (int i = 0; i < 4; i++) {
      int w = p.w + dw[i];
      int h = p.h + dh[i];
      if (w >= 0 && w < g_w && h >= 0 && h < g_h &&
          (mat[h][w] == '.' ||
           (isdigit(mat[h][w]) && p.strength + '0' > mat[h][w]))) {
        q.push(Position(h, w, p.time + 1, p.strength));
      }
    }
  }
  printf("%d\\n", result);
  return 0;
}

#include <cctype>
#include <cstdio>
#include <queue>
#include <vector>

using namespace std;

struct Position {
  int h, w, time, strength;
  Position(int h, int w, int t, int s) : h(h), w(w), time(t), strength(s) {}
};

const int max_h = 1005;
const int max_w = 1005;
int g_h, g_w, g_strength, g_max_strength, si, sj;
char mat[max_h][max_w];
pair<int, int> factories[20];
int dh[] = {0, 1, 0, -1};
int dw[] = {1, 0, -1, 0};

int main() {
  scanf("%d%d%d", &g_h, &g_w, &g_max_strength);
  for (int i = 0; i < g_h; i++) {
    getchar();
    for (int j = 0; j < g_w; j++) {
      mat[i][j] = getchar();
      if (mat[i][j] == 'S') {
        si = i;
        sj = j;
        mat[i][j] = '.';
      } else if (isdigit(mat[i][j])) {
        factories[mat[i][j] - '0'].first = i;
        factories[mat[i][j] - '0'].second = j;
        mat[i][j] = '.';
      }
    }
  }
  queue<Position> q;
  g_strength = 1;
  q.push(Position(si, sj, 0, 1));
  int result = -1;
  while (!q.empty()) {
    Position p = q.front();
    q.pop();
    if (p.strength < g_strength)
      continue;
    pair<int, int> f = factories[p.strength];
    if (p.h == f.first && p.w == f.second) {
      if (p.strength == g_max_strength) {
        result = p.time;
        break;
      }
      p.strength++;
      g_strength++;
    }
    for (int i = 0; i < 4; i++) {
      int w = p.w + dw[i];
      int h = p.h + dh[i];
      if (w >= 0 && w < g_w && h >= 0 && h < g_h &&
          (mat[h][w] == '.' ||
           (isdigit(mat[h][w]) && p.strength + '0' > mat[h][w]))) {
        mat[h][w] = p.strength + '0';
        q.push(Position(h, w, p.time + 1, p.strength));
      }
    }
  }
  printf("%d\\n", result);
  return 0;
}


#include <cstring>
#include <iostream>
#include <queue>
#include <stdio.h>
using namespace std;

char ma[1005][1005];
int vis[1005][1005];
int w, h, n;

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

struct node {
  int x, y, time;
};
node start;

void bfs(char ed) {
  queue<node> que;
  que.push(start);
  vis[start.x][start.y] = 1;
  while (!que.empty()) {
    node no = que.front();
    que.pop();
    for (int i = 0; i < 4; i++) {
      int x = no.x + dx[i];
      int y = no.y + dy[i];
      if (vis[x][y] || x >= h || x < 0 || y >= w || y < 0 || ma[x][y] == 'X')
        continue;
      if (ma[x][y] == ed) {
        start.x = x;
        start.y = y;
        start.time = no.time + 1;
        return;
      }
      vis[x][y] = 1;
      node no1;
      no1.x = x;
      no1.y = y;
      no1.time = no.time + 1;
      que.push(no1);
    }
  }
}

int main() {
  while (scanf("%d %d %d\\n", &h, &w, &n)) {
    for (int i = 0; i < h; i++) {
      scanf("%s", &ma[i]);
      for (int j = 0; j < w; j++)
        if (ma[i][j] == 'S') {
          start.x = i;
          start.y = j;
          start.time = 0;
        }
    }
    for (int i = 0; i < n; i++) {
      memset(vis, 0, sizeof(vis));
      bfs(i + '1');
    }

    printf("%d\\n", start.time);
  }
  return 0;
}

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
using namespace std;
#define MAX 1005

int h, w, n;
char city[MAX][MAX];
struct node {
  int x, y, time;
} start;
int direc1[4] = {-1, 0, 1, 0}, direc2[4] = {0, 1, 0, -1};
map<int, int> visited;

void dfs(char end) {
  queue<node> que;
  que.push(start);
  visited[start.x * w + start.y] = 1;
  int nextx, nexty;
  while (que.size() != 0) {
    node now = que.front();
    que.pop();
    for (int i = 0; i < 4; i++) {
      nextx = now.x + direc1[i];
      nexty = now.y + direc2[i];
      if (nextx >= 0 && nextx < h && nexty >= 0 && nexty < w &&
          city[nextx][nexty] != 'X' && !visited[nextx * w + nexty]) {

        if (city[nextx][nexty] == end) {
          start.x = nextx;
          start.y = nexty;
          start.time = now.time + 1;
          return;
        } else {
          visited[nextx * w + nexty] = 1;
          node now1;
          now1.x = nextx;
          now1.y = nexty;
          now1.time = now.time + 1;
          que.push(now1);
        }
      }
    }
  }
}

int main() {
  cin >> h >> w >> n;
  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      cin >> city[i][j];
      if (city[i][j] == 'S') {
        start.x = i;
        start.y = j;
        start.time = 0;
      }
    }
  }
  for (int i = 0; i < n; i++) {
    visited.clear();
    dfs(i + '1');
  }
  cout << start.time << endl;
  // system("pause");
  return 0;
}


//
//  main.cpp

#include <iostream>
using namespace std;
using ll = long long;
const ll MAX = 10000000000000;
int h, w, n;
bool matrix[1001][1001] = {{}};
bool visited[1001][1001] = {{}};
pair<int, int> target;

ll min(ll x, ll y) {
  if (x < y) {
    return x;
  } else {
    return y;
  }
}

ll dfs(ll depth, int x, int y) {
  if (!matrix[x][y])
    return MAX;
  if (target.first == x && target.second == y)
    return depth;

  ll a, b, c, d;
  a = b = c = d = MAX;
  if (!visited[x + 1][y]) {
    visited[x + 1][y] = true;
    a = dfs(depth + 1, x + 1, y);
    visited[x + 1][y] = false;
  }
  if (!visited[x - 1][y]) {
    visited[x - 1][y] = true;
    b = dfs(depth + 1, x - 1, y);
    visited[x - 1][y] = false;
  }
  if (!visited[x][y + 1]) {
    visited[x][y + 1] = true;
    c = dfs(depth + 1, x, y + 1);
    visited[x][y + 1] = false;
  }
  if (!visited[x][y - 1]) {
    visited[x][y - 1] = true;
    d = dfs(depth + 1, x, y - 1);
    visited[x][y - 1] = false;
  }
  return min(a, min(b, min(c, d)));
}

int main() {
  for (int i = 0; i < 1001; i++) {
    for (int j = 0; j < 1001; j++) {
      matrix[i][j] = visited[i][j] = false;
    }
  }

  cin >> h >> w >> n;
  pair<int, int> cheese[10];
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      char input;
      cin >> input;
      switch (input) {
      case '.':
        matrix[i][j] = true;
        break;
      case 'X':
        matrix[i][j] = false;
        break;
      case 'S':
        matrix[i][j] = true;
        cheese[0] = make_pair(i, j);
        break;
      default:
        matrix[i][j] = true;
        cheese[input - '0'] = make_pair(i, j);
        break;
      }
    }
  }

  ll answer = 0;
  for (int i = 0; i < n; i++) {
    target = cheese[i + 1];
    visited[cheese[i].first][cheese[i].second] = true;
    answer += dfs(0, cheese[i].first, cheese[i].second);
    visited[cheese[i].first][cheese[i].second] = false;
  }

  cout << answer << endl;
  return 0;
}

//
//  main.cpp

#include <iostream>
#include <queue>
using namespace std;
using ll = long long;
const ll MAX = 10000000000000;
int h, w, n;
bool matrix[1001][1001] = {{}};
bool visited[1001][1001] = {{}};
pair<int, int> target;
struct state {
  int x;
  int y;
  int depth;
};

ll min(ll x, ll y) {
  if (x < y) {
    return x;
  } else {
    return y;
  }
}

/*

ll dfs(ll depth,int x,int y){
        if(!matrix[x][y])return MAX;
        if(target.first == x && target.second == y)return depth;

        ll a,b,c,d;
        a = b = c = d = MAX;
        if(!visited[x+1][y]){
                visited[x+1][y] = true;
                a = dfs(depth+1,x+1,y);
                visited[x+1][y] = false;
        }
        if(!visited[x-1][y]){
                visited[x-1][y] = true;
                b = dfs(depth+1,x-1,y);
                visited[x-1][y] = false;
        }
        if(!visited[x][y+1]){
                visited[x][y+1] = true;
                c = dfs(depth+1,x,y+1);
                visited[x][y+1] = false;
        }
        if(!visited[x][y-1]){
                visited[x][y-1] = true;
                d = dfs(depth+1,x,y-1);
                visited[x][y-1] = false;
        }
        return min(a,min(b,min(c,d)));
}
*/
ll bfs(int x, int y) {
  queue<state> willvisit;
  willvisit.push({x, y, 0});
  ll ret;
  while (1) {
    if (willvisit.empty())
      break;
    state now = willvisit.front();
    willvisit.pop();

    if (now.x == target.first && now.y == target.second) {
      ret = now.depth;
      break;
    }
    if (!visited[now.x + 1][now.y]) {
      if (matrix[now.x + 1][now.y]) {
        visited[now.x + 1][now.y] = true;
        willvisit.push({now.x + 1, now.y, now.depth + 1});
      }
    }
    if (!visited[now.x - 1][now.y]) {
      if (matrix[now.x - 1][now.y]) {
        visited[now.x - 1][now.y] = true;
        willvisit.push({now.x - 1, now.y, now.depth + 1});
      }
    }
    if (!visited[now.x][now.y + 1]) {
      if (matrix[now.x][now.y + 1]) {
        visited[now.x][now.y + 1] = true;
        willvisit.push({now.x, now.y + 1, now.depth + 1});
      }
    }
    if (!visited[now.x][now.y - 1]) {
      if (matrix[now.x][now.y - 1]) {
        visited[now.x][now.y - 1] = true;
        willvisit.push({now.x, now.y - 1, now.depth + 1});
      }
    }
  }

  return ret;
}

void visitedReset() {
  for (int i = 0; i < 1001; i++) {
    for (int j = 0; j < 1001; j++) {
      visited[i][j] = false;
    }
  }
}

int main() {
  for (int i = 0; i < 1001; i++) {
    for (int j = 0; j < 1001; j++) {
      matrix[i][j] = visited[i][j] = false;
    }
  }

  cin >> h >> w >> n;
  pair<int, int> cheese[10];
  for (int i = 1; i <= h; i++) {
    for (int j = 1; j <= w; j++) {
      char input;
      cin >> input;
      switch (input) {
      case '.':
        matrix[i][j] = true;
        break;
      case 'X':
        matrix[i][j] = false;
        break;
      case 'S':
        matrix[i][j] = true;
        cheese[0] = make_pair(i, j);
        break;
      default:
        matrix[i][j] = true;
        cheese[input - '0'] = make_pair(i, j);
        break;
      }
    }
  }

  ll answer = 0;
  for (int i = 0; i < n; i++) {
    target = cheese[i + 1];
    visited[cheese[i].first][cheese[i].second] = true;
    answer += bfs(cheese[i].first, cheese[i].second);
    visitedReset();
  }
  /*
  for(int i=0;i<n;i++){
          target = cheese[i+1];
          visited[cheese[i].first][cheese[i].second] = true;
          answer += dfs(0,cheese[i].first,cheese[i].second);
          visited[cheese[i].first][cheese[i].second] = false;
  }
  */
  cout << answer << endl;
  return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long int ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef pair<int, pair<int, int>> tup;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()

#define EACH(i, c)                                                             \\
  for (typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define SORT(c) sort((c).begin(), (c).end())

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
const double PI = acos(-1.0);
#define CLR(a) memset((a), 0, sizeof(a))

// int tansaku[110];
// map<string,string> d;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  bool visited[1010][1010];
  char field[1010][1010];
  queue<tup> kuwa;
  int H, W, N;
  // CLR(visited);
  REP(i, W) { REP(j, H) visited[i][j] = false; }
  cin >> H >> W >> N;
  REP(j, H) {
    REP(i, W) { cin >> field[i][j]; }
  }
  tup start;
  cin.ignore();
  REP(i, W) {
    REP(j, H) {
      if (field[i][j] == 'S') {
        start = {0, {i, j}};
      }
    }
  }
  kuwa.push(start);
  int ans = 0;
  int cost = 0;
  char cheeze = '1';
  while (!kuwa.empty()) {
    tup r = kuwa.front();
    kuwa.pop();
    int haba = r.first;
    PII p = r.second;
    visited[p.first][p.second] = true;
    if (field[p.first][p.second] == cheeze) {
      cost += haba;
      if (cheeze - '0' == N)
        break;
      cheeze++;
      queue<tup> daisuke;
      swap(kuwa, daisuke);
      kuwa.push(make_pair(0, p));
      // CLR(visited);
      REP(i, W) { REP(j, H) visited[i][j] = false; }

      continue;
    }
    for (int i = 0; i < 4; i++) {
      PII new_xy = {p.first + dx[i], p.second + dy[i]};
      if (0 <= new_xy.first && new_xy.first < W && 0 <= new_xy.second &&
          new_xy.second < H && !visited[new_xy.first][new_xy.second] &&
          field[new_xy.first][new_xy.second] != 'X') {
        kuwa.push(make_pair(haba + 1, new_xy));
      }
    }
  }
  cout << cost << endl;
  return 0;
}

#include <bits/stdc++.h>

using namespace std;
typedef long long int ll;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef pair<int, pair<int, int>> tup;
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()

#define EACH(i, c)                                                             \\
  for (typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define SORT(c) sort((c).begin(), (c).end())

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
const double PI = acos(-1.0);
#define CLR(a) memset((a), 0, sizeof(a))

// int tansaku[110];
// map<string,string> d;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  bool visited[1010][1010];
  char field[1010][1010];
  queue<tup> kuwa;
  int H, W, N;
  // CLR(visited);
  REP(i, W) { REP(j, H) visited[i][j] = false; }
  cin >> H >> W >> N;
  REP(j, H) {
    REP(i, W) { cin >> field[i][j]; }
  }
  tup start;
  cin.ignore();
  REP(i, W) {
    REP(j, H) {
      if (field[i][j] == 'S') {
        start = {0, {i, j}};
      }
    }
  }
  kuwa.push(start);
  int ans = 0;
  int cost = 0;
  char cheeze = '1';
  while (!kuwa.empty()) {
    tup r = kuwa.front();
    kuwa.pop();
    int haba = r.first;
    PII p = r.second;
    visited[p.first][p.second] = true;
    if (field[p.first][p.second] == cheeze) {
      cost += haba;
      if (cheeze - '0' == N)
        break;
      cheeze++;
      queue<tup> daisuke;
      swap(kuwa, daisuke);
      kuwa.push(make_pair(0, p));
      // CLR(visited);
      REP(i, W) { REP(j, H) visited[i][j] = false; }

      continue;
    }
    for (int i = 0; i < 4; i++) {
      PII new_xy = {p.first + dx[i], p.second + dy[i]};
      if (0 <= new_xy.first && new_xy.first < W && 0 <= new_xy.second &&
          new_xy.second < H && !visited[new_xy.first][new_xy.second] &&
          field[new_xy.first][new_xy.second] != 'X') {
        kuwa.push(make_pair(haba + 1, new_xy));
        visited[new_xy.first][new_xy.second] = true;
      }
    }
  }
  cout << cost << endl;
  return 0;
}