/* * 2005/12/2 * * 色々ハマって、嫌な事に。 */ import java.util.Scanner; public class Push { public static final int RIGHT = 0; public static final int LEFT = 1; public static final int UP = 2; public static final int DOWN = 3; public static int[][] table; public static int[][][] cache; public static int[][] cache2; public static int W, H, goalX, goalY; public static final String[] name = { "nothing", "pillar", "cargo", "goal", "man" }; public static void innerIsManMove(int x, int y, int X, int Y, int cargox, int cargoy) { cache2[x][y] = 1; if(x < W-1 && name[table[x + 1][y]] != "pillar" && !(x == cargox && y == cargoy) && cache2[x + 1][y] == 0) { innerIsManMove(x+1, y, X, Y, cargox, cargoy); } if(x > 0 && name[table[x - 1][y]] != "pillar" && !(x == cargox && y == cargoy) && cache2[x - 1][y] == 0) { innerIsManMove(x-1, y, X, Y, cargox, cargoy); } if(y < H-1 && name[table[x][y + 1]] != "pillar" && !(x == cargox && y == cargoy) && cache2[x][y + 1] == 0) { innerIsManMove(x, y+1, X, Y, cargox, cargoy); } if(y > 0 && name[table[x][y - 1]] != "pillar" && !(x == cargox && y == cargoy) && cache2[x][y - 1] == 0) { innerIsManMove(x, y-1, X, Y, cargox, cargoy); } } public static boolean isManMove(int x, int y, int X, int Y, int cargox, int cargoy) { cache2 = new int[W][H]; cache2[x][y] = 1; if(x < W-1 && name[table[x + 1][y]] != "pillar" && !(x == cargox && y == cargoy) && cache2[x + 1][y] == 0) { innerIsManMove(x+1, y, X, Y, cargox, cargoy); } if(x > 0 && name[table[x - 1][y]] != "pillar" && !(x == cargox && y == cargoy) && cache2[x - 1][y] == 0) { innerIsManMove(x-1, y, X, Y, cargox, cargoy); } if(y < H-1 && name[table[x][y + 1]] != "pillar" && !(x == cargox && y == cargoy) && cache2[x][y + 1] == 0) { innerIsManMove(x, y+1, X, Y, cargox, cargoy); } if(y > 0 && name[table[x][y - 1]] != "pillar" && !(x == cargox && y == cargoy) && cache2[x][y - 1] == 0) { innerIsManMove(x, y-1, X, Y, cargox, cargoy); } return cache2[X][Y] == 1; } public static boolean isMoveRight(int manx, int many, int x, int y){ if(x == W-1 || x == 0 || name[table[x + 1][y]] == "pillar") { return false; } else return isManMove(manx, many, x - 1, y, x, y); } public static boolean isMoveLeft(int manx, int many,int x, int y){ if(x == W-1 || x == 0 || name[table[x - 1][y]] == "pillar") { return false; } else return isManMove(manx, many, x + 1, y, x, y); } public static boolean isMoveUp(int manx, int many,int x, int y){ if(y == H-1 || y == 0 || name[table[x][y - 1]] == "pillar") { return false; } else return isManMove(manx, many, x, y + 1, x, y); } public static boolean isMoveDown(int manx, int many,int x, int y){ if(y == H-1 || y == 0 || name[table[x][y + 1]] == "pillar") { return false; } else return isManMove(manx, many, x, y - 1, x, y); } public static void search(int manx, int many, int x, int y, int dist, int t) { if(cache[x][y][dist] == 0) { cache[x][y][dist] = t; } else { cache[x][y][dist] = Math.min(cache[x][y][dist], t); } if(isMoveRight(manx, many, x, y) && (cache[x + 1][y][RIGHT] >= t || cache[x + 1][y][RIGHT] == 0)) { search(x, y, x + 1, y, RIGHT, t + 1); } if(isMoveLeft(manx, many, x, y) && (cache[x - 1][y][LEFT] >= t || cache[x - 1][y][LEFT] == 0)) { search(x, y, x - 1, y, LEFT, t + 1); } if(isMoveUp(manx, many, x, y) && (cache[x][y - 1][UP] >= t || cache[x][y - 1][UP] == 0)) { search(x, y, x, y - 1, UP, t + 1); } if(isMoveDown(manx, many, x, y) && (cache[x][y + 1][DOWN] >= t || cache[x][y + 1][DOWN] == 0)) { search(x, y, x, y + 1, DOWN, t + 1); } } public static int search(int manx, int many, int x, int y) { int t = 0; if(isMoveRight(manx, many, x, y) && (cache[x + 1][y][RIGHT] >= t || cache[x + 1][y][RIGHT] == 0)) { search(x, y, x + 1, y, RIGHT, t + 1); } if(isMoveLeft(manx, many, x, y) && (cache[x - 1][y][LEFT] >= t || cache[x - 1][y][LEFT] == 0)) { search(x, y, x - 1, y, LEFT, t + 1); } if(isMoveUp(manx, many, x, y) && (cache[x][y - 1][UP] >= t || cache[x][y - 1][UP] == 0)) { search(x, y, x, y - 1, UP, t + 1); } if(isMoveDown(manx, many, x, y) && (cache[x][y + 1][DOWN] >= t || cache[x][y + 1][DOWN] == 0)) { search(x, y, x, y + 1, DOWN, t + 1); } int ans = -1; for(int i = 0; i < 4; i++) { if(ans == -1) { if(cache[goalX][goalY][i] > 0) { ans = cache[goalX][goalY][i]; } } else { if(cache[goalX][goalY][i] > 0) { ans = Math.min(ans, cache[goalX][goalY][i]); } } } return ans; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); while(sc.hasNext()) { W = sc.nextInt(); H = sc.nextInt(); if(W == H && W == 0) { break; } table = new int[W][H]; cache = new int[W][H][4]; int[][] tmp = new int[H][W]; for(int i = 0; i < H; i++) { for(int j = 0; j < W; j++) { tmp[i][j] = sc.nextInt(); } } for(int i = 0; i < W; i++) { for(int j = 0; j < H; j++) { table[i][j] = tmp[j][i]; } } int startx = 0, starty = 0; int manx = 0, many = 0; for(int i = 0; i < W; i++) { for(int j = 0; j < H; j++) { if(name[table[i][j]] == "cargo") { startx = i; starty = j; } else if(name[table[i][j]] == "goal") { goalX = i; goalY = j; } else if(name[table[i][j]] == "man") { manx = i; many = j; } } } System.out.println(search(manx, many, startx, starty)); } } }