#include <ios>
#include <iostream>
#include <queue>
#include <vector>
#include <cassert>
using namespace std;
// 0
//1 3
// 2
struct position{
int x,y;
explicit operator bool(){
return x != -1;
}
position forward(int dir){
return position{x+(dir&1)*(dir-2), y+(!(dir&1))*(dir-1)};
}
bool operator==(const position& b) const{
return x == b.x && y == b.y;
}
void _print(){
cout << y << ' ' << x;
}
void print(){
cout << y << ' ' << x << '\n';
}
};
class Board{
public:
vector<vector<int>> types;
vector<vector<vector<position>>> jumps;
int w, h;
vector<position> bots;
int nbBots;
Board(){}
Board(int _w, int _h, int _nbBots):
w(_w),
h(_h),
types(_h, vector<int>(_w)),
jumps(_h, vector<vector<position>>(_w, vector<position>(4, {-1, -1}))),
nbBots(_nbBots),
bots(_nbBots){}
void read(){
for(int y=0; y<h; y++){
string line;
getline(cin, line);
while(!line.size())getline(cin, line);
for(int x=0; x<w; x++){
if(isupper(line[x]))
types[y][x] = (line[x] == 'C')+1;
else if(isalpha(line[x]))
types[y][x] = 3;
else if(isdigit(line[x]))
bots[line[x]-'1'] = {x, y};
}
}
}
int changedir(position pos, int dir){
if(types[pos.y][pos.x] == 1)
return (dir+1)&3;
else if(types[pos.y][pos.x] == 2)
return (dir-1)&3;
return dir;
}
bool isvalid(position pos){
return
pos.x >= 0 && pos.x < w &&
pos.y >= 0 && pos.y < h &&
types[pos.y][pos.x] != 3;
}
position jump(position cur, int dir){
if((bool)jumps[cur.y][cur.x][dir]){
return jumps[cur.y][cur.x][dir];
}
position start = cur;
int startdir = dir;
vector<pair<position, int>> stack;
stack.push_back({cur, dir});
while(isvalid(cur.forward(dir))){
cur = cur.forward(dir);
dir = changedir(cur, dir);
stack.push_back({cur, dir});
}
assert(isvalid(cur));
for(auto state:stack){
jumps[state.first.y][state.first.x][state.second] = cur;
}
//start._print();cout << '(' << startdir << ") -> ";
//cur.print();
return cur;
}
};
int n, w, h;
int MAX;
Board board;
//[sizerange][startrange][y][x]
vector<vector<vector<vector<int>>>> fromStart;
vector<pair<position, int>> Q;
void bfs(position pos, int id){
int start = 0;
int end = 0;
Q[end++] = {pos, 0};
fromStart[0][id][pos.y][pos.x] = 0;
while(start < end){
auto cur = Q[start++];
for(int dir=0; dir<4; dir++){
position nextpos = board.jump(cur.first, dir);
if(fromStart[0][id][nextpos.y][nextpos.x] == MAX){
fromStart[0][id][nextpos.y][nextpos.x] = cur.second+1;
Q[end++] = {nextpos, cur.second+1};
}
}
}
}
struct state{
position pos;
int size;
bool operator<(const state& b) const{
return size > b.size;
}
};
void normalize(vector<vector<int>>& A){
priority_queue<state> prioQ;
for(int y=0; y<h; y++){
for(int x=0; x<w; x++){
if(A[y][x] >= MAX)continue;
position curpos = {x, y};
prioQ.push({curpos, A[y][x]});
}
}
while(!prioQ.empty()){
state cur=prioQ.top();
prioQ.pop();
if(cur.size > A[cur.pos.y][cur.pos.x])continue;
A[cur.pos.y][cur.pos.x] = cur.size;
for(int dir=0; dir<4; dir++){
state next = {board.jump(cur.pos, dir), cur.size+1};
if(next.size < A[next.pos.y][next.pos.x]){
A[next.pos.y][next.pos.x] = next.size;
prioQ.push(next);
}
}
}
}
void fuse(int start, int end){
//cout << start << " " << end << '\n';
int span = end-start-1;
for(int mid=start+1; mid<end; mid++){
for(int y=0; y<h; y++){
for(int x=0; x<w; x++){
fromStart[span][start][y][x] = min(
fromStart[span][start][y][x],
fromStart[mid-start-1][start][y][x] + fromStart[end-mid-1][mid][y][x]
);
}
}
}
normalize(fromStart[span][start]);
//for(int y=0; y<h; y++){
// for(int x=0; x<w; x++){
// cout << fromStart[span][start][y][x] << '\t';
// }
// cout << '\n';
//}
}
int main(){
ios_base::sync_with_stdio(false);cin.tie(0);
cin >> n >> w >> h;
board = Board(w, h, n);
MAX = n*w*h;
board.read();
Q.resize(w*h);
fromStart.resize(n);
for(int i=0; i<n; i++){
fromStart[i] = vector<vector<vector<int>>>(n-i,
vector<vector<int>> (h,
vector<int> (w, MAX)));
}
//board.jump(board.bots[1], 0).print();
//board.bots[1].forward(0).print();
//board.jump(board.bots[3], 1).print();
//board.jump(board.bots[2], 1).print();
for(int i=0; i<n; i++){
bfs(board.bots[i], i);
}
for(int i=1; i<n; i++){
for(int start=0; start <= n-i-1; start++){
fuse(start, start+i+1);
}
}
int res = w*h*n;
for(int y=0; y<h; y++){
for(int x=0; x<w; x++){
res = min(res, fromStart[n-1][0][y][x]);
}
//cout << '\n';
}
if(res >= MAX){
cout << "-1\n";
}else
cout << res << '\n';
}