#include <cstring>
#include <queue>
#include <iostream>
#define REP(i,n) for(int i=0; i<(int)(n); i++)
#define IN(x,s,g) ((x) >= (s) && (x) < (g))
#define ISIN(x,y,w,h) (IN((x),0,(w)) && IN((y),0,(h)))

#include <cstdio>
inline int getInt(){ int s; scanf("%d", &s); return s; }

#include <set>

using namespace std;

int dp[10][10][4][4][4][10];

int idOf(pair<int, int> prev, pair<int, int> next){
  if(prev.first  + 1 == next.first) return 0;
  if(prev.first  - 1 == next.first) return 1;
  if(prev.second + 1 == next.second) return 2;
  if(prev.second - 1 == next.second) return 3;
  throw 0;
}

pair<int, int> posOf(pair<int, int> prev, int id){
  if(id == 0){ prev.first  += 1; return prev; }
  if(id == 1){ prev.first  -= 1; return prev; }
  if(id == 2){ prev.second += 1; return prev; }
  if(id == 3){ prev.second -= 1; return prev; }
  throw 0;
}

struct State{
  int x;
  int y;
  int b1;
  int b2;
  int b3;
  int next;

  State(){}
  State(int x, int y, int b1, int b2, int b3, int next)
    : x(x), y(y), b1(b1), b2(b2), b3(b3), next(next){
  }

  int &dp() const{
    return ::dp[y][x][b1][b2][b3][next];
  }

  vector<pair<int, int> > pos() const{
    vector<pair<int, int> > ret;
    ret.push_back(make_pair(x, y));
    ret.push_back(posOf(ret.back(), b1));
    ret.push_back(posOf(ret.back(), b2));
    ret.push_back(posOf(ret.back(), b3));
    return ret;
  }
};

bool operator < (const State &lhs, const State &rhs){
  return lhs.next > rhs.next;
}

char g[16][16];

int ex[10];
int ey[10];

int bx[10];
int by[10];

const int _dx[] = {0,1,0,-1};
const int _dy[] = {-1,0,1,0};

int main(){
  const int h = getInt();
  const int w = getInt();
  const int n = getInt();

  REP(i,h) scanf("%s", g[i]);
  REP(i,h) REP(j,w){
    if(isdigit(g[i][j])){
      const int k = g[i][j] - '1';
      ex[k] = j; ey[k] = i;
      g[i][j] = '.';
    }else if(isalpha(g[i][j])){
      const int k = g[i][j] == 'S' ? 0 : g[i][j] - 'a' + 1;
      bx[k] = j; by[k] = i;
      g[i][j] = '.';
    }
  }

  State init(bx[0], by[0],
	     idOf(make_pair(bx[0], by[0]), make_pair(bx[1], by[1])),
	     idOf(make_pair(bx[1], by[1]), make_pair(bx[2], by[2])),
	     idOf(make_pair(bx[2], by[2]), make_pair(bx[3], by[3])),
	     0);

  typedef pair<int, State> data;
  priority_queue<data, vector<data>, greater<data> > pq;

  memset(dp, -1, sizeof(dp));
  pq.push(make_pair(0, init));

  while(pq.size()){
    const data d = pq.top(); pq.pop();
    int cost = d.first;
    State state = d.second;

    if(state.dp() != -1) continue;
    state.dp() = cost;

    if(state.next == n){
      printf("%d\n", cost);
      return 0;
    }

    const vector<pair<int, int> > pos = state.pos();
    REP(k,4){
      const int x = pos[0].first + _dx[k];
      const int y = pos[0].second + _dy[k];
      if(!ISIN(x, y, w, h)) continue;
      if(g[y][x] == '#') continue;

      const pair<int, int> next = make_pair(x, y);
      if(next != pos[0] && next != pos[1] && next != pos[2] && next != pos[3]){
	int nn = state.next;
	if(next.first == ex[state.next] && next.second == ey[state.next]) nn++;

	State s(next.first, next.second,
		idOf(next, pos[0]),
		idOf(pos[0], pos[1]),
		idOf(pos[1], pos[2]),
		nn);
	if(s.dp() == -1){
	  pq.push(make_pair(cost + 1, s));
	}
      }
    }
  }

  puts("-1");
  return 0;
}


Measured memory_bytes: 1504