# bzoj 1671: [Usaco2005 Dec]Knights of Ni 骑士

#include<iostream>
#include<cstdio>
#include<queue>

#define inf 10000000

using namespace std;

struct point{
int x,y;
friend bool operator == (point a,point b){
if(a.x==b.x && a.y==b.y)return true;
else return false;
}
};

struct node{
bool guan;
point now;
int num;
friend bool operator < (node a,node b){
return a.num>b.num;
}
};

int tox[4]={-1,0,1,0};
int toy[4]={0,1,0,-1};
point s,t;
int n,m;
int a[1010][1010];
int Min[1010][1010][2];
priority_queue<node>q;

int main(){
scanf("%d%d",&m,&n);
for(int i=1; i<=n; i++){
for(int j=1; j<=m; j++){
scanf("%d",&a[i][j]);
if(a[i][j]==2)s.x=i,s.y=j;
if(a[i][j]==3)t.x=i,t.y=j;
Min[i][j][0]=Min[i][j][1]=inf;
}
}
node tt;
tt.guan=false;
tt.now=s;
Min[s.x][s.y][0]=0;
tt.num=0;
q.push(tt);
while(!q.empty()){
tt=q.top();
q.pop();
if(tt.guan && tt.now==t){
break;
}
for(int i=0; i<4; i++){
node t1=tt;
t1.now.x+=tox[i];
t1.now.y+=toy[i];
if(t1.now.x<1 || t1.now.x>n || t1.now.y<1 || t1.now.y>m)continue;
if(a[t1.now.x][t1.now.y]==1)continue;
if(Min[t1.now.x][t1.now.y][t1.guan]<=t1.num+1)continue;
Min[t1.now.x][t1.now.y][t1.guan]=t1.num+1;
if(t1.guan==false && a[t1.now.x][t1.now.y]==4){
t1.guan=true;
Min[t1.now.x][t1.now.y][t1.guan]=Min[t1.now.x][t1.now.y][0];
}
t1.num++;
q.push(t1);
}
}
printf("%d\n",tt.num);

return 0;
}