#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
typedef long long int ll;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Info{
	Info(){
		eat_after = row = col = hp = time = 0;
	}

	void set(int arg_row,int arg_col,int arg_hp,int arg_time,int arg_eat_after){
		row = arg_row;
		col = arg_col;
		hp = arg_hp;
		time = arg_time;
		eat_after = arg_eat_after;
	}

	int row,col,hp,time,eat_after;
	short check[8][8];
};

struct Data{
	int row,col;
};

int W,H,div_row[4] = {-1,0,0,1},div_col[5] = {0,-1,1,0};
bool isCrearable;

Data data[7];
int data_index,distMap[8][8],map[8][8];
int start_row,start_col,goal_row,goal_col;


bool rangeCheck(int row,int col){
	if(row >= 0 && row <= H-1 && col >= 0 && col <= W-1)return true;
	else{
		return false;
	}
}

void dist5(int row,int col){
	int next_row,next_col;
	for(int i = 0; i < 4; i++){
		next_row = row+div_row[i],next_col = col+div_col[i];
		if(rangeCheck(next_row,next_col) == true && map[next_row][next_col] != 0 && distMap[next_row][next_col] > distMap[row][col]+1 && distMap[row][col] <= 4){
			distMap[next_row][next_col] = min(distMap[next_row][next_col],distMap[row][col]+1);
			if(map[next_row][next_col] == 4){
				distMap[next_row][next_col] = 0;
				dist5(next_row,next_col);
			}else if(next_row == start_row && next_col == start_col){
				isCrearable = true;
				return;
			}else{
				dist5(next_row,next_col);
			}
		}
	}
}

void func(){

	for(int i = 0; i < H; i++){
		for(int k = 0; k < W; k++){
			scanf("%d",&map[i][k]);
			if(map[i][k] == 2){
				start_row = i;
				start_col = k;
				map[i][k] = 1;
			}else if(map[i][k] == 3){
				goal_row = i;
				goal_col = k;
			}
		}
	}

	isCrearable = false;
	for(int i = 0; i < H; i++){
		for(int k = 0; k < W; k++)distMap[i][k] = BIG_NUM;
	}

	distMap[goal_row][goal_col] = 0;
	data_index = 0;

	dist5(goal_row,goal_col);

	if(isCrearable == false){
		printf("-1\n");
		return;
	}

	int ans = -1,limit = 36;
	queue<Info> Q;
	Info current;

	Info first;

	for(int i = 0; i < H; i++){
		for(int k = 0; k < W; k++)first.check[i][k] = 0;
	}

	first.check[start_row][start_col] = 1;
	first.set(start_row,start_col,6,0,3);

	Q.push(first);

	while(!Q.empty()){
		current = Q.front();
		Q.pop();

		if(current.hp == 0)continue;

		if(map[current.row][current.col] == 3){
			ans = current.time;
			break;
		}else if(map[current.row][current.col] == 4){
			current.hp = 6;
			current.eat_after = 0;
		}

		if(current.time + abs(current.row-goal_row)+abs(current.col-goal_col) > limit)continue;

		for(int i = 0; i < 4; i++){
			if(rangeCheck(current.row+div_row[i],current.col+div_col[i]) == true && map[current.row+div_row[i]][current.col+div_col[i]] != 0 &&
					((current.check[current.row+div_row[i]][current.col+div_col[i]] == 0) || (current.check[current.row+div_row[i]][current.col+div_col[i]] == 1 &&	current.eat_after <= 1))){
				Info new_info;
				for(int a = 0; a < H; a++){
					for(int b = 0; b < W; b++){
						new_info.check[a][b] = current.check[a][b];
					}
				}
				new_info.check[current.row+div_row[i]][current.col+div_col[i]]++;
				new_info.set(current.row+div_row[i],current.col+div_col[i],current.hp-1,current.time+1,current.eat_after+1);
				Q.push(new_info);
			}
		}
	}
	printf("%d\n",ans);
}

int main(){

	while(true){
		scanf("%d %d",&W,&H);
		if(W == 0 && H == 0)break;

		func();
	}

	return 0;
}

Measured memory_bytes: 24036