#include <cstdio>
#include <queue>
#include <cstring>
#include <vector>
using namespace std;

#define MAX 8
#define MAX_V 64
int F[MAX][MAX];
int w, h;

struct edge {
    int from, to;
    int cost;
    edge(int from=0, int to=0, int cost=0) : from(from), to(to), cost(cost) {}
};

typedef vector<edge> node;
node graph[MAX_V];
int number[MAX][MAX];

struct P {
    int y, x;
    int t;
    P(int y, int x, int t) : y(y), x(x), t(t) {}
};

typedef pair<int, int> S;
#define INF (1<<28)

const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};

int d[MAX_V];
void dijkstra() {
    //printf("DIJKSTRA\n");
    fill(d, d+MAX_V, INF);
    priority_queue< S, vector<S>, greater<S> > q;
    q.push(S(0, 0));
    d[0] = 0;
    while (!q.empty()) {
        S s = q.top(); q.pop();
        int v = s.second;
        if (d[v] < s.first) continue;
        for (int i = 0; i < graph[v].size(); i++) {
            edge e = graph[v][i];
            if (d[e.to] > d[v] + e.cost) {
                d[e.to] = d[v] + e.cost;
                q.push(S(d[e.to], e.to));
            }
        }
    }
    //printf("END OF DIJKSTRA\n");
}

int main() {
    while (scanf("%d %d", &w, &h), w || h) {
        memset(number, -1, sizeof(number));
        for (int i = 0; i < h; i++) graph[i].clear();
        for (int i = 0; i < h; i++) 
            for (int j = 0; j < w; j++) 
                scanf("%d", &F[i][j]);

        int cur = 2;
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                if (F[i][j] == 2) number[i][j] = 0;
                if (F[i][j] == 3) number[i][j] = 1;
                if (F[i][j] == 4) number[i][j] = cur++;
            }
        }

        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                if (F[i][j] == 2 || F[i][j] == 3 || F[i][j] == 4) {
                    //printf("i: %d j: %d\n", i, j);
                    bool used[h][w]; memset(used, 0, sizeof(used));
                    queue<P> q;
                    q.push(P(i, j, 0));
                    used[i][j] = true;
                    while (!q.empty()) {
                        P p = q.front(); q.pop();
                        if (p.t >= 6) continue;
                        if (number[p.y][p.x] > 0) {
                            int from = number[i][j];
                            int to = number[p.y][p.x];
                            graph[from].push_back(edge(from, to, p.t));
                        }
                        for (int k = 0; k < 4; k++) {
                            int ny = p.y + dy[k];
                            int nx = p.x + dx[k];
                            if (0 <= nx && nx < w && 0 <= ny && ny < h && !used[ny][nx] && F[ny][nx] != 0) {
                                used[ny][nx] = true;
                                q.push(P(ny, nx, p.t+1));
                            }
                        }
                    }
                }
            }
        }
        dijkstra();
        //for (int i = 0; i < cur; i++) {
        //    printf("%d: ", i);
        //    for (int j = 0; j < graph[i].size(); j++) {
        //        printf("%d ", graph[i][j].to);
        //    }
        //    printf("\n");
        //}
        printf("%d\n", (d[1] == INF ? -1 : d[1]));
    }
    return 0;
}

Measured memory_bytes: 1044