import java.util.*; import java.io.*; public class SnakeGodmar { static int m, n; static int applei, applej; public static void main(String []av) { var sc = new Scanner(System.in); m = sc.nextInt(); n = sc.nextInt(); char [][]b = new char[m][]; byte []snakei = new byte[16]; byte []snakej = new byte[16]; int snakeL = 0; for (byte i = 0; i < m; i++) { b[i] = sc.next().toCharArray(); for (byte j = 0; j < n; j++) { char c = b[i][j]; if (c == 'A') { applei = i; applej = j; } if (('0' <= c && c <= '9') || ('a' <= c && c <= 'f')) { int p = Integer.parseInt("" + c, 16); snakei[p] = i; snakej[p] = j; snakeL = Math.max(snakeL, p); } } } snakeL++; // snakes of length 1 trivially reach the apple if (snakeL == 1) { System.out.println(1); return; } byte []initialSnake = new byte[2+snakeL]; initialSnake[0] = snakei[0]; initialSnake[1] = snakej[0]; if (snakeL > 1) { initialSnake[2] = snakei[1]; initialSnake[3] = snakej[1]; for (int j = 2; j < snakeL; j++) { initialSnake[j+2] = orientation(snakei[j-2], snakej[j-2], snakei[j-1], snakej[j-1], snakei[j], snakej[j]); } } var visited = new HashSet(); var start = new State(initialSnake); var bfs = new ArrayDeque(); bfs.offer(start); while (!bfs.isEmpty()) { State s = bfs.poll(); //System.err.println("Processing "); //s.print(System.err); for (int d = -1; d <= 1; d++) { State ns = s.moveHead(d); if (ns == null) continue; if (ns.isGoal()) { System.out.println(1); return; } if (!visited.contains(ns)) { visited.add(ns); bfs.offer(ns); } } } System.out.println(0); } static class State { byte []snake; State(byte []snake) { this.snake = snake; } @Override public int hashCode() { return Arrays.hashCode(this.snake); } @Override public boolean equals(Object _that) { State that = (State)_that; return Arrays.equals(this.snake, that.snake); } boolean isGoal() { return snake[0] == applei && snake[1] == applej; } State moveHead(int dir) { // head moves in direction int di = snake[0] - snake[2]; int dj = snake[1] - snake[3]; byte ni, nj; // new head switch (dir) { case 0: ni = (byte)(snake[0] + di); nj = (byte)(snake[1] + dj); break; case -1: ni = (byte)(snake[0] + dj); nj = (byte)(snake[1] - di); break; case 1: ni = (byte)(snake[0] - dj); nj = (byte)(snake[1] + di); break; default: throw new Error("invalid direction"); } if (!(ni >= 0 && nj >= 0 && ni < m && nj < n)) return null; // check if we'd run into our body int bi = snake[2]; int bj = snake[3]; di *= -1; dj *= -1; for (int j = 4; j < snake.length - 1; j++) { advance(snake[j], bi, bj, di, dj); if (ni == npi && nj == npj) { return null; } di = npi - bi; dj = npj - bj; bi = npi; bj = npj; } byte []newsnake = new byte[snake.length]; System.arraycopy(new byte[] { ni, nj, snake[0], snake[1] // old head becomes second position }, 0, newsnake, 0, 4); if (newsnake.length > 4) { // move tail if we have any newsnake[4] = (byte) dir; System.arraycopy(snake, 4, newsnake, 5, snake.length-5); } return new State(newsnake); } int npi, npj; void advance(int d, int bi, int bj, int di, int dj) { switch (d) { case 0: npi = (byte)(bi + di); npj = (byte)(bj + dj); break; case -1: npi = (byte)(bi - dj); npj = (byte)(bj + di); break; case 1: npi = (byte)(bi + dj); npj = (byte)(bj - di); break; default: throw new Error("invalid direction"); } } void print(PrintStream out) { char [][] b = new char[m][n]; for (char []r : b) Arrays.fill(r, '.'); b[applei][applej] = 'A'; b[snake[0]][snake[1]] = '0'; b[snake[2]][snake[3]] = '1'; int bi = snake[2]; int bj = snake[3]; int di = snake[2] - snake[0]; int dj = snake[3] - snake[1]; for (int j = 4; j < snake.length - 1; j++) { advance(snake[j], bi, bj, di, dj); b[npi][npj] = Integer.toString(j-2, 16).charAt(0); di = npi - bi; dj = npj - bj; bi = npi; bj = npj; } for (int i = 0; i < m; i++) out.println(new String(b[i])); } @Override public String toString() { return Arrays.toString(snake); } } /* * 0 - straight * 1 - turn right * -1 - turn left */ static byte orientation(byte i0, byte j0, byte i1, byte j1, byte i2, byte j2) { int di0 = i1 - i0; int di1 = i2 - i1; int dj0 = j1 - j0; int dj1 = j2 - j1; return (byte)(di1 * dj0 - di0 * dj1); } }