#include #include using namespace std; struct State { int cargo_x, cargo_y; int ware_x, ware_y; int move; State() { move = 0; } bool operator < (const State& s) const { if (move != s.move) { return move < s.move; } if (cargo_x != s.cargo_x) { return cargo_x < s.cargo_x; } if (cargo_y != s.cargo_y) { return cargo_y < s.cargo_y; } if (ware_x != s.ware_x) { return ware_x < s.ware_x; } if (ware_y != s.ware_y) { return ware_y < s.ware_y; } return false; } }; struct less2 { bool operator () (const State& o1, const State& o2) const { if (o1.cargo_x != o2.cargo_x) { return o1.cargo_x < o2.cargo_x; } if (o1.cargo_y != o2.cargo_y) { return o1.cargo_y < o2.cargo_y; } if (o1.ware_x != o2.ware_x) { return o1.ware_x < o2.ware_x; } if (o1.ware_y != o2.ware_y) { return o1.ware_y < o2.ware_y; } return false; } }; int field[10][10]; int x, y; const int dirx[] = { 0, 0, 1, -1 }; const int diry[] = { 1, -1, 0, 0 }; bool next_state(const State& s, State* next, int dir) { int dx = dirx[dir]; int dy = diry[dir]; next->move = s.move; next->cargo_x = s.cargo_x; next->cargo_y = s.cargo_y; if (dx + s.ware_x < 0 || dx + s.ware_x >= x) { return false; } if (dy + s.ware_y < 0 || dy + s.ware_y >= y) { return false; } next->ware_x = dx + s.ware_x; next->ware_y = dy + s.ware_y; if (field[next->ware_x][next->ware_y] == 1) { return false; } if (next->ware_x == next->cargo_x && next->ware_y == next->cargo_y) { if (next->cargo_x + dx < 0 || dx + next->cargo_x >= x) { return false; } if (next->cargo_y + dy < 0 || dy + next->cargo_y >= y) { return false; } next->cargo_x += dx; next->cargo_y += dy; if (field[next->cargo_x][next->cargo_y] == 1) { return false; } next->move++; } return true; } int main() { State start; while (cin >> y >> x && x && y) { for (int i = 0; i < x; i++) { for (int j = 0; j < y; j++) { cin >> field[i][j]; if (field[i][j] == 2) { start.cargo_x = i; start.cargo_y = j; } if (field[i][j] == 4) { start.ware_x = i; start.ware_y = j; } } } set Q; set cache; Q.insert(start); cache.insert(start); int ans = -1; while (!Q.empty()) { State s = *Q.begin(); Q.erase(s); if (field[s.cargo_x][s.cargo_y] == 3) { ans = s.move; break; } for (int i = 0; i < 4; i++) { State next; if (!next_state(s, &next, i)) { continue; } if (cache.find(next) != cache.end()) { continue; } Q.insert(next); cache.insert(next); } } cout << ans << endl; } return 0; }