import java.util.Scanner;
import java.util.Queue;
import java.util.LinkedList;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] arr = in.nextLine().split(" ");
int m = Integer.valueOf(arr[0]);
int n = Integer.valueOf(arr[1]);
char[][] grid = new char[m][n];
int startX = 0;
int startY = 0;
for (int i = 0; i < m; i++) {
String str = in.nextLine();
for (int j = 0; j < n; j++) {
grid[i][j] = str.charAt(j);
if (grid[i][j] == '2') {
startX = i;
startY = j;
}
}
}
int result = bfs(startX, startY, grid);
System.out.println(result);
}
private static int bfs(int startX, int startY, char[][] grid) {
// 记录x,y,key,step
Queue<int[]> queue = new LinkedList<>();
// 记录访问状态
int m = grid.length;
int n = grid[0].length;
boolean[][][] visited = new boolean[m][n][1024];
visited[startX][startY][0] = true;
// 方向数组
int[][] direction = new int[][]{{1, 0}, {-1, 0}, {0, -1}, {0, 1}};
queue.offer(new int[]{startX, startY, 0, 0});
while (!queue.isEmpty()) {
int[] arr = queue.poll();
if (grid[arr[0]][arr[1]] == '3') {
// 返回结果步数
return arr[3];
}
for (int i = 0; i < 4; i++) {
int nextX = arr[0] + direction[i][0];
int nextY = arr[1] + direction[i][1];
if (nextX >= m || nextX < 0 || nextY >= n || nextY < 0 || grid[nextX][nextY] == '0') {
continue;
}
int key = arr[2];
if (grid[nextX][nextY] >= 'a' && grid[nextX][nextY] <= 'z') {
key = key | (1 << (grid[nextX][nextY] - 'a'));
}
if (grid[nextX][nextY] >= 'A' && grid[nextX][nextY] <= 'Z' && (key & (1 << grid[nextX][nextY] - 'A')) == 0) {
continue;
}
if (!visited[nextX][nextY][key]) {
visited[nextX][nextY][key] = true;
queue.offer(new int[]{nextX, nextY, key, arr[3] + 1});
}
}
}
return 0;
}
}