#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
#define ll long long
#define inf 1e10+1
using namespace std;
const int N = 100000;
int n, m;
int x_s, y_s, x_e, y_e;
int G[400][400];
int vis[400][400];
int ma[][2] = { {1, 2}, {2, 1}, {1, -2}, {2, -1}, {-1, 2}, {-2, 1}, {-1, -2}, {-2, -1} };
int ne[N], to[N], val[N],he[N],tot=0;
ll dis[N];
ll f[N];
struct node {
ll dis, u;
bool operator<(const node b)const {
return dis > b.dis;
}
};
priority_queue<node>s;
int v[N];
ll ans = inf;
ll read();
void fi();
void dfs(int x, int y, ll num);
void se();
void add(int u, int v, int w);
void dfs2(int x, int y, ll cnt);
int main() {
fi();
if (ans == inf) {
cout << -1; return 0;
}
cout << ans << endl;
se();
return 0;
}
ll read()
{
char ch = getchar();
ll res = 0;
while (ch < '0' || ch > '9')
{
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
res = res * 10 + ch - '0';
ch = getchar();
}
return res;
}
void fi() {
m = read(), n = read();
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
G[i][j] = read();
if (G[i][j] == 3)
{
x_s = i;
y_s = j;
}
else if (G[i][j] == 4)
{
x_e = i;
y_e = j;
}
}
}
memset(vis, 0, sizeof(vis));
dfs(x_s, y_s, 0);
}
void dfs(int x,int y,ll num) {
if (num > ans) {
return;
}
if (x == x_e && y == y_e) {
ans = num;
return;
}
for (int i = 0; i <= 7; i++) {
int xx = x + ma[i][0], yy = y + ma[i][1];
if (xx > m || xx < 1 || yy > n || yy < 1 || vis[xx][yy]|| G[xx][yy] == 2)continue;
vis[xx][yy] = 1;
if (G[xx][yy] == 0)
dfs(xx, yy, num + 1);
else
dfs(xx, yy, num);
vis[xx][yy] = 0;
}
}
void se() {
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (G[i][j] == 2)continue;
memset(vis, 0, sizeof(vis));
dfs2(i, j, 0);
}
}
memset(dis, 0x7f, sizeof(dis));
memset(f, 0, sizeof(f));
memset(v, 0, sizeof(v));
int start = (x_s - 1) * n + y_s;
f[start] = 1;
dis[start] = 0;
s.push({ 0,start });
while (s.size()) {
int now = s.top().u;
s.pop();
if (v[now])continue;
v[now] = 1;
for (int i = he[now]; i; i = ne[i]) {
int u = to[i];
if (dis[u] > dis[now] + val[i]) {
dis[u] = dis[now] + val[i];
f[u] = 0;
if (!v[u])
s.push({ dis[u],u });
}
if (dis[u] == dis[now] + val[i]) {
f[u] += f[now];
}
}
}
int end= (x_e - 1) * n + y_e;
cout << f[end] << endl;
}
void add(int u, int v, int w) {
tot++;
to[tot] = v;
val[tot] = w;
ne[tot] =he[u];
he[u] = tot;
}
void dfs2(int x, int y, ll cnt) {
for (int i = 0; i <= 7; i++) {
int xx = x + ma[i][0], yy = y + ma[i][1];
if (xx > m || xx < 1 || yy > n || yy < 1 || vis[xx][yy] || G[xx][yy] == 2)continue;
vis[xx][yy] = 1;
if (G[xx][yy] == 0) {
add((x - 1) * n + y, (xx - 1) * n + yy, cnt + 1);
dfs(xx, yy, cnt + 1);
}
else if (G[xx][yy] == 4) {
add((x - 1) * n + y, (xx - 1) * n + yy, cnt);
dfs(xx, yy, cnt + 1);
}
else
dfs(xx, yy, cnt);
}
}