#include <iostream>
#include <queue>
using namespace std;
const int N = 8 + 5;
struct point
{
int x,y;
};
int map[N][N];
int x,y,n,m,nx,ny,live = 6;
bool vis[N][N];
int dis[N][N];
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
queue<point> dui;
bool alive(int x,int y, int live)
{
if(0 < x && x < n && 0 < y && y < m)
{
return map[x - 1][y - 1] != 0 && map[x][y - 1] != 0 && map[x - 1][y] != 0 && map[x][y] != 0 && live == 1;
}
return false;
}
int bfs(int x,int y)
{
point in;
in.x = x;
in.y = y;
dui.push(in);
dis[x][y] = 0;
vis[x][y] = true;
point next;
while(dui.empty())
{
point now = dui.front();
dui.pop();
if(map[now.x][now.y] == 3)
{
return dis[now.x][now.y];
}
for(int i = 0; i < 4; i++)
{
nx += dx[i];
ny += dy[i];
live--;
if(!alive(nx,ny,live))
{
break;
}
if(!vis[nx][ny])
{
if(map[nx][ny] == 4)
{
dis[nx][ny] = dis[now.x][now.y] + 1;
next.x = nx;
next.y = ny;
dui.push(next);
live = 6;
vis[nx][ny] = true;
}
else
{
dis[nx][ny] = dis[now.x][now.y] + 1;
next.x = nx;
next.y = ny;
dui.push(next);
live = 6;
vis[nx][ny] = true;
}
}
}
}
return -1;
}
int main()
{
cin >> n >> m;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
cin >> map[i][j];
if(map[i][j] == 2)
{
x = i;
y = j;
}
}
}
cout << bfs(x,y) << endl;
return 0;
}