#include<iostream>
#include<algorithm>
#include<queue>

using namespace std;

const int MAX = 8;
const int INF = (1<<25);

struct State{
  int x,y,t,bx,by;
  State(){}
  State(int x, int y, int t, int bx, int by):x(x),y(y),t(t),bx(bx),by(by){}
  bool operator < (const State& s) const { return t > s.t;}
};

int M[MAX][MAX];
int T[MAX][MAX][MAX][MAX];
//T[i][j][k][l]:= shortest time i,j (y,x) when box is on k,l (y,x)

int sx,sy,gx,gy,sbx,sby;
int w,h;

bool isInside(int x, int y){ return 0<=x&&x<w&&0<=y&&y<h;}

void init(){
  fill(T[0][0][0],T[0][0][0]+MAX*MAX*MAX*MAX,INF);
}

void input(){
  for(int i = 0; i < h; i++)
    for(int j = 0; j < w; j++){
      cin >> M[i][j];
      if(M[i][j] == 2) sbx=j,sby=i;
      if(M[i][j] == 3) gx=j,gy=i;
      if(M[i][j] == 4) sx=j,sy=i;
    }
}

void solve(){

  int dx[] = {0,1,0,-1};
  int dy[] = {-1,0,1,0};
  
  T[sy][sx][sby][sbx] = 0;
  priority_queue<State> Q;
  Q.push(State(sx,sy,0,sbx,sby)); 

  while(!Q.empty()){
    State now = Q.top();
    Q.pop();

    for(int i = 0; i < 4; i++){
      State nex = now;
      nex.x += dx[i];
      nex.y += dy[i];

      if(!isInside(nex.x,nex.y) || M[nex.y][nex.x] == 1) continue;

      if(nex.x == nex.bx && nex.y == nex.by){
	//move cargo
	nex.bx += dx[i];
	nex.by += dy[i];
	nex.t++;
	if(isInside(nex.bx,nex.by) && M[nex.by][nex.bx] != 1 && T[nex.y][nex.x][nex.by][nex.bx] > nex.t){
	  T[nex.y][nex.x][nex.by][nex.bx] = nex.t;
	  Q.push(nex);
	}
      
      }else{
	//move myself
	if(T[nex.y][nex.x][nex.by][nex.bx] > nex.t){
	  T[nex.y][nex.x][nex.by][nex.bx] = nex.t;
	  Q.push(nex);
	}
      }
    }

  }

  int ans = INF;
  for(int i = 0; i < h; i++)
    for(int j = 0; j < w; j++) ans = min(ans,T[i][j][gy][gx]);

  if(ans == INF) cout << -1 << endl;
  else cout << ans << endl;
}

int main(){
  
  while(cin >> w >> h && w+h){
    init();
    input();
    solve();
  }
  return 0;
}