#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define up(l,r,i) for(int i=(l);(i)<=(r);++i)
#define pb push_back
#define pii pair<ll,ll>
ll n,m,s,t,grid[33][33],dis[1007],ans[1007];
bool type[1007];
constexpr int inf=1e9,dx[]={1,1,-1,-1,2,2,-2,-2},dy[]={2,-2,2,-2,1,-1,1,-1};
ll get(ll x,ll y){
return (x-1)*m+y;
}
vector<pii> G[1007];
void connect(int x,int y,int add){
int qwq=get(x,y);
for(int i=0;i<8;++i){
int nx=x+dx[i],ny=y+dy[i];
if(nx<1||nx>n||ny<1||ny>m||grid[nx][ny]==2)continue;
if(grid[nx][ny]){
G[qwq].pb(make_pair(get(nx,ny),add));
}
else G[qwq].pb(make_pair(get(nx,ny),1+add));
}
}
priority_queue<pii> pq;
void dijkstra(){
dis[s]=0;
pq.push(make_pair(0,s));
while(pq.size()){
int d=pq.top().first,u=pq.top().second;
pq.pop();
for(auto qwq:G[u]){
ll v=qwq.first,w=qwq.second;
if(dis[v]>d+w){
dis[v]=d+w;
pq.push(make_pair(dis[v],v));
}
}
}
}
ll dfs(int u){
if(u==s)return ans[u]=1;
if(ans[u])return ans[u];
for(auto v:G[u]){
if(dis[v.first]==dis[u]-1&&type[u]==1)ans[u]+=dfs(v.first);
if(dis[v.first]==dis[u]-2&&type[u]==0)ans[u]+=dfs(v.first);
}
return ans[u];
}
int main()
{
int TestCases=1;
while(TestCases--){
cin>>n>>m;
up(1,n,i){
up(1,m,j){
cin>>grid[i][j];
type[get(i,j)]=(grid[i][j]==1||grid[i][j]==3||grid[i][j]==4);
if(grid[i][j]==3)s=get(i,j);
if(grid[i][j]==4)t=get(i,j);
}
}
up(1,n,i){
up(1,m,j){
if(grid[i][j]!=2){
connect(i,j,0);
}
}
}
up(1,n*m,i)dis[i]=inf;
ans[s]=1;
dijkstra();
if(dis[t]==inf)cout<<-1,exit(0);
cout<<dis[t]<<'\n';
up(1,n*m,i)G[i].clear();
up(1,n,i){
up(1,m,j){
if(grid[i][j]!=2){
connect(i,j,1);
}
}
}
up(1,n*m,i)dis[i]=inf;
dijkstra();
cout<<dfs(t);
}
return 0;
}