#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
#define reps(i,b,n) for(int i = b ; i < (int)n ; ++i )
#define rep(i,n) reps(i,0,n)
#define fr first
#define sc second
typedef pair<int,int> Pt;
typedef pair<Pt,Pt> pp;
typedef pair<int,pp> P;
const int dx[] = {1,-1,0,0}, dy[] = {0,0,1,-1};
int w,h,mas[7][7];
Pt St,kago,Gl;
bool used[7][7][7][7];
bool check(int x,int y){
  return x >= 0 && x < h && y >= 0 && y < w && mas[x][y] != 1;
}
int Dijkstra(){
  priority_queue< P,vector<P>,greater<P> > que;
  que.push(P(0,pp(St,kago)));
  used[St.fr][St.sc][kago.fr][kago.sc] = true;
  while(!que.empty()){
    Pt now = que.top().sc.fr , box = que.top().sc.sc;
    int cost = que.top().fr;
    que.pop();
    if(box == Gl) return cost;
    rep(i,4){
      int nx = now.fr + dx[i] , ny = now.sc + dy[i];
      if(!check(nx,ny)) continue;
      int boxx = box.fr , boxy = box.sc , cnt = cost;
      if( nx == boxx && ny == boxy ){
          boxx += dx[i] , boxy += dy[i] , cnt++;
          if(!check(boxx,boxy)) continue;
      }
      if(!used[nx][ny][boxx][boxy]){
        que.push(P(cnt,pp(Pt(nx,ny),Pt(boxx,boxy))));
        used[nx][ny][boxx][boxy] = true;
      }
    }
  }
  return -1;
}
int main(){
  while(cin >> w >> h , w){
    rep(i,h) rep(j,w){
      cin >> mas[i][j];
      if(mas[i][j] == 4) St = Pt(i,j);
      else if(mas[i][j] == 2) kago = Pt(i,j);
      else if(mas[i][j] == 3) Gl = Pt(i,j);
    }
    cout << Dijkstra() << endl;
    fill_n(used[0][0][0],7*7*7*7,false);
  }
}