#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <numeric>
#include <iomanip>

#define REP(i,n) for(i=0; i < (n); i++)
#define REPONE(i, n) for(i=1; i <= (n); i++)
#define LOOP(n) for(int loopCount=1; loopCount <= (n); loopCount++)
#define ITER(c) __typeof((c).begin())
#define EACH(c,it) for(ITER(c) it =(c).begin(); it!=(c).end(); it++)
#define SZ(c) ((int) (c).size())
#define ALL(c) c.begin(), c.end()
#define SUM(c) accumulate(ALL(c), 0)
#define EXIST(c,v) (find(ALL(c), (v)) != (c).end())
#define PB push_back
#define MP make_pair
#define fs first
#define sc second

using namespace std;
static const double EPS = 1e-9;
static const double PI = 3.141592653589793238462643383279;
typedef long long ll;
typedef pair<int, int> pi;
typedef pair<pi, pi> ppi;

static int board[10][10];
static int memo[100][100];
int dx[] = {1,0,-1,0};
int dy[] = {0,1,0,-1};

inline int getNum(pi a){
    return a.fs*10 + a.sc;
}

inline pi getPair(ppi a){
    return MP(getNum(a.fs), getNum(a.sc));
}

inline  int getDir(ppi a){
    pi m = a.sc, c = a.fs;
    if(m.sc == c.sc){
        if(m.fs == c.fs - 1) return 0;
        if(m.fs == c.fs + 1) return 2;
    }
    else if(m.fs == c.fs){
        if(m.sc == c.sc - 1) return 1;
        if(m.sc == c.sc + 1) return 3;
    }

    return -1;
}

inline int getMemo(ppi a){
    pi t = getPair(a);
    return memo[t.fs][t.sc];
}

inline void touchMemo(ppi a, int v){
    pi t = getPair(a);
    memo[t.fs][t.sc] = v;
    return ;
}

inline bool isFree(pi a){
    return board[a.fs][a.sc] == 0;
}

void display(ppi a){
    printf("(%d, %d), (%d, %d) -- %d\n", a.fs.fs, a.fs.sc, a.sc.fs, a.sc.sc, getMemo(a));
}

int main(){
    int i, j, w, h, dir, l;
    ppi cur, next;
    queue<ppi> Q;
    while(scanf("%d%d",&w,&h)){
        if(!(w|h))break;
        REP(i,10)REP(j,10)board[i][j] = 1;
        REPONE(i,h)REPONE(j,w)scanf("%d",&board[i][j]);
        REP(i,100)REP(j,100) memo[i][j] = 1<<29;

        pi man, cargo, goal;
        REPONE(i,h)REPONE(j,w){
            if(board[i][j] == 2){
                cargo = MP(i,j);
                board[i][j] = 0;
            }
            else if(board[i][j] == 3){
                goal = MP(i,j);
                board[i][j] = 0;
            }
            else if(board[i][j] == 4){
                man = MP(i,j);
                board[i][j] = 0;
            }
        }

        touchMemo(MP(cargo,man), 0);
        Q.push(MP(cargo, man));
        while(!Q.empty()){
            cur = Q.front();
            dir = getDir(cur);
            l = getMemo(cur);
            REP(i,4){
                next = cur;
                if(i==dir){
                    next.fs.fs += dx[i];
                    next.fs.sc += dy[i];
                    if(isFree(next.fs) && l + 1< getMemo(next)){
                        Q.push(next);
                        touchMemo(next, l+1);
                    }
                }
                else{
                    next.sc.fs += dx[i];
                    next.sc.sc += dy[i];
                    if(isFree(next.sc) && l < getMemo(next)){
                        Q.push(next);
                        touchMemo(next, l);
                    }
                }
            }
            Q.pop();
        }
        int ans = 1<<29;
        REP(i,100)if(memo[getNum(goal)][i] >= 0){
            ans = min(ans, memo[getNum(goal)][i]);
        }
        printf("%d\n",(ans==(1<<29))?-1:ans);
    }
    return 0;
}

Measured memory_bytes: 0