#include <stdio.h>
#include <limits.h>
#include <math.h>
#include <bitset>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cstring>
#include <string>
#include <sstream>
#include <algorithm>
#include <iomanip>
#include <iostream>

#define VARIABLE(x) cerr << #x << "=" << x << endl
#define BINARY(x) static_cast<bitset<16> >(x);
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define REP(i,m,n) for (int i=m;i<(int)(n);i++)
#define if_range(x, y, w, h) if (0<=(int)(x) && (int)(x)<(int)(w) && 0<=(int)(y) && (int)(y)<(int)(h))

const int INF = 100000000;
typedef double D;
const double EPS = 1e-8;
const double PI = 3.14159;
int dx[4]={-1, 0, 1, 0}, dy[4]={0, -1, 0, 1};
using namespace std;
//typedef pair<int, int> P;
struct P {
	int x, y;
	P(){}
	P(int x_, int y_):x(x_),y(y_){}
};

/** Problem1218 : Push!! **/
int W, H;
const int MAX = 8;
int field[MAX][MAX];
typedef pair<P, P> PP;
string ch = ".#OG&";

bool canMove(P s, P g, P c)
{
	queue<P> Q;
	bool vis[W][H]; fill(vis[0], vis[0]+W*H, false);
	vis[s.x][s.y]=true;
	Q.push(s);
	
	while (Q.size()) {
		P p = Q.front(); Q.pop();
		
		rep(i, 4) {
			int nx = p.x + dx[i], ny = p.y + dy[i];
			
			if_range(nx, ny, W, H) {
				if (field[nx][ny] != 1 && !vis[nx][ny] && (nx != c.x || ny != c.y)) {
					Q.push(P(nx, ny));
					vis[nx][ny] = true;
				}
			}
		}
	}
	return vis[g.x][g.y];
}
 
int main()
{
	while (cin>>W>>H, W||H) {
		P s, m, g;
		memset(field, 0, sizeof(field));

		rep(y, H) {
			rep(x, W) {
				cin>>field[x][y];
				
				if (field[x][y] == 4) {
					m = P(x, y);
				} else if (field[x][y] == 2) {
					s = P(x, y);
				} else if (field[x][y] == 3) {
					g = P(x, y);
				}
			}
		}
		
		queue<PP> Q;
		int vis[W][H][W][H]; fill(vis[0][0][0], vis[0][0][0]+W*H*W*H, INF);
		vis[s.x][s.y][m.x][m.y]=0;
		Q.push(PP(s, m));
		
		while (Q.size()) {
			PP p = Q.front(); Q.pop();
			
			if (p.first.x == g.x && p.first.y == g.y)
				break;
			
			rep(i, 4) {
				int nx = p.first.x + dx[i], ny = p.first.y + dy[i];
				int nmx = p.first.x - dx[i], nmy = p.first.y - dy[i];
				
				if_range(nx, ny, W, H) {
					if_range(nmx, nmy, W, H) {
						if (field[nx][ny] != 1 && vis[nx][ny][nmx][nmy] == INF && canMove(P(p.second.x, p.second.y), P(nmx, nmy), p.first)) {
							Q.push(PP(P(nx, ny), P(nmx, nmy)));
							vis[nx][ny][nmx][nmy] = vis[p.first.x][p.first.y][p.second.x][p.second.y]+1;
						}
					}
				}
			}
		}
		
		int ans = INF;
		rep(i, H) {
			rep(j, W) {
				ans = min(ans, vis[g.x][g.y][j][i]);
			}
		}
		cout << (ans!=INF?ans:-1) << endl;
	}
}