#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <algorithm>
using namespace std;
const int INF = 1e9;
int N, W, H;
char grid[505][505];
int dist[10][10][505][505];
pair<int, int> memo_move[4][505][505];
bool visiting[4][505][505];
int dx[] = {-1, 0, 1, 0}; // Up, Right, Down, Left
int dy[] = {0, 1, 0, -1};
// Precompute robot movement including rotating plates
pair<int, int> get_destination(int d, int r, int c) {
if (memo_move[d][r][c].first != 0) return memo_move[d][r][c];
if (visiting[d][r][c]) return memo_move[d][r][c] = {-1, -1}; // Loop detected
visiting[d][r][c] = true;
int nd = d;
if (grid[r][c] == 'A') nd = (d + 3) % 4; // Anti-clockwise
else if (grid[r][c] == 'C') nd = (d + 1) % 4; // Clockwise
int nr = r + dx[nd], nc = c + dy[nd];
pair<int, int> res;
if (nr < 0 || nr >= H || nc < 0 || nc >= W || grid[nr][nc] == 'x') {
res = {r, c};
} else {
res = get_destination(nd, nr, nc);
}
visiting[d][r][c] = false;
return memo_move[d][r][c] = res;
}
struct State {
int r, c, d;
bool operator>(const State& other) const { return d > other.d; }
};
void run_dijkstra(int i, int j) {
priority_queue<State, vector<State>, greater<State>> pq;
for (int r = 0; r < H; ++r) {
for (int c = 0; c < W; ++c) {
if (dist[i][j][r][c] < INF) pq.push({r, c, dist[i][j][r][c]});
}
}
while (!pq.empty()) {
State curr = pq.top(); pq.pop();
if (curr.d > dist[i][j][curr.r][curr.c]) continue;
for (int d = 0; d < 4; ++d) {
pair<int, int> dest = get_destination(d, curr.r, curr.c);
if (dest.first != -1 && dist[i][j][dest.first][dest.second] > curr.d + 1) {
dist[i][j][dest.first][dest.second] = curr.d + 1;
pq.push({dest.first, dest.second, dist[i][j][dest.first][dest.second]});
}
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cin >> N >> W >> H;
for (int i = 1; i <= N; ++i)
for (int j = 1; j <= N; ++j)
for (int r = 0; r < H; ++r)
for (int c = 0; c < W; ++c)
dist[i][j][r][c] = INF;
for (int r = 0; r < H; ++r) {
for (int c = 0; c < W; ++c) {
cin >> grid[r][c];
if (grid[r][c] >= '1' && grid[r][c] <= '9') {
dist[grid[r][c] - '0'][grid[r][c] - '0'][r][c] = 0;
}
}
}
for (int len = 1; len <= N; ++len) {
for (int i = 1; i <= N - len + 1; ++i) {
int j = i + len - 1;
for (int r = 0; r < H; ++r) {
for (int c = 0; c < W; ++c) {
for (int k = i; k < j; ++k) {
dist[i][j][r][c] = min(dist[i][j][r][c], dist[i][k][r][c] + dist[k+1][j][r][c]);
}
}
}
run_dijkstra(i, j);
}
}
int ans = INF;
for (int r = 0; r < H; ++r) {
for (int c = 0; c < W; ++c) {
ans = min(ans, dist[1][N][r][c]);
}
}
cout << (ans == INF ? -1 : ans) << endl;
return 0;
}