#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int g[1005][1005];
bool vis1[1005][1005];
bool vis2[1005][1005];
int w,h;
int sum1[1005][1005];//sum1[i][j]表示从起点到(i,j)位置所需步数
int sum2[1005][1005];//sum2[i][j]表示从终点到(i,j)位置所需步数
struct node
{
int x,y;
};
queue<node> q1;
queue<node> q2;
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
void bfs1()
{
while(!q1.empty())
{
node now=q1.front();
q1.pop();
for(int i=0;i<4;i++)
{
int tx=now.x+dx[i];
int ty=now.y+dy[i];
if(!vis1[tx][ty])
{
vis1[tx][ty]=1;
sum1[tx][ty]=sum1[now.x][now.y]+1;
q1.push({tx,ty});
}
}
}
}
void bfs2()
{
while(!q2.empty())
{
node now=q2.front();
q2.pop();
for(int i=0;i<4;i++)
{
int tx=now.x+dx[i];
int ty=now.y+dy[i];
if(!vis2[tx][ty])
{
vis2[tx][ty]=1;
sum2[tx][ty]=sum2[now.x][now.y]+1;
q2.push({tx,ty});
}
}
}
}
int main()
{
cin>>w>>h;
for(int i=1;i<=h;i++)
{
vis1[i][0]=vis1[i][w+1]=vis2[i][0]=vis2[i][w+1]=true;//把图的边缘标记为true
for(int j=1;j<=w;j++)
{
cin>>g[i][j];
sum1[i][j]=sum2[i][j]=1e+9;
vis1[0][j]=vis1[h+1][j]=vis2[0][j]=vis2[h+1][j]=true;
if(g[i][j]==1)
{
vis1[i][j]=vis2[i][j]=true;
}
else if(g[i][j]==2)
{
q1.push({i,j});
vis1[i][j]=1;
sum1[i][j]=0;
}
else if(g[i][j]==3)
{
q2.push({i,j});
vis1[i][j]=vis2[i][j]=1;
sum2[i][j]=0;
}
}
}
bfs1();
bfs2();
int ans=1e+9;
for(int i=1;i<=h;i++)
{
for(int j=1;j<=w;j++)
{
if(g[i][j]==4)
{
ans=min(ans,sum1[i][j]+sum2[i][j]);
}
}
}
cout<<ans<<endl;
return 0;
}