#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <cmath>
using namespace std;

typedef pair <int, int> PII;
typedef pair <PII, PII> PPP;
typedef pair <int, PPP> Node;
typedef priority_queue <Node, vector<Node>, greater<Node> > Queue;

const int inf = 1<<24; 
const int size = 8;
int w, h;
int M[size][size];
bool O[size][size];

const int dr[4] = { 0, 0, 1, -1 };
const int dc[4] = { 1, -1, 0, 0 };

int solve( int sr, int sc, int cr, int cc, int gr, int gc ) {
    int M[size][size][size][size];
    for ( int i = 0; i < size; i++ ) {
        for ( int j = 0; j < size; j++ ) {
            for ( int k = 0; k < size; k++ ) {
                for ( int l = 0; l < size; l++ ) {
                    M[i][j][k][l] = inf;
                }
            }
        }
    }
    Queue Q;
    Node start( 0, PPP( PII( sr, sc ), PII( cr, cc ) ) );
    Q.push( start );
    M[sr][sc][cr][cc] = 0;

    while ( !Q.empty() ) {
        Node node = Q.top();
        Q.pop();

        int cost = node.first;
        int r = node.second.first.first;
        int c = node.second.first.second;
        int cr = node.second.second.first;
        int cc = node.second.second.second;

        if ( cr == gr && cc == gc ) {
            return cost;
        }

        for ( int i = 0; i < 4; i++ ) {
            int nr = r + dr[i];
            int nc = c + dc[i];
            if ( nr < 0 || nr >= h || nc < 0 || nc >= w ) {
                continue;
            }
            if ( O[nr][nc] ) {
                continue;
            }
            int ncost = cost;
            int ncr = cr;
            int ncc = cc;
            if ( nr == cr && nc == cc ) {
                ncr += dr[i];
                ncc += dc[i];
                if ( ncr < 0 || ncr >= h || ncc < 0 || ncc >= w ) {
                    continue;
                }
                if ( O[ncr][ncc] ) {
                    continue;
                }
                ncost += 1;
            }
            if ( ncost >= M[nr][nc][ncr][ncc] ) {
                continue;
            }
            M[nr][nc][ncr][ncc] = ncost;
            Node nnode( ncost, PPP( PII( nr, nc ), PII( ncr, ncc ) ) );
            Q.push( nnode );
        }
    }

    return -1;
}

/*
0: nothing (simply a floor tile)
1: a pillar
2: the cargo
3: the goal
4: the warehouseman (Mr. Schwarz)
*/

int main() {
    while ( cin >> w >> h ) {
        if ( w == 0 && h == 0 ) break;
        // init
        for ( int i = 0; i < h; i++ ) {
            for ( int j = 0; j < w; j++ ) {
                O[i][j] = false;
            }
        }

        for ( int i = 0; i < h; i++ ) {
            for ( int j = 0; j < w; j++ ) {
                cin >> M[i][j];
            }
        }

        int sr, sc;
        int cr, cc;
        int gr, gc;
        for ( int i = 0; i < h; i++ ) {
            for ( int j = 0; j < w; j++ ) {
                if ( M[i][j] == 1 ) {
                    O[i][j] = true;
                } else if ( M[i][j] == 4 ) {
                    sr = i;
                    sc = j;
                } else if ( M[i][j] == 2 ) {
                    cr = i;
                    cc = j;
                } else if ( M[i][j] == 3 ) {
                    gr = i;
                    gc = j;
                }
            }
        }

        cout << solve( sr, sc, cr, cc, gr, gc ) << endl;
    }
    return 0;
}

Measured memory_bytes: 0