#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 35, M = N * N , E = M * N;
int n, m;
LL cnt[M];
bool vis[M];
LL dist[M];
int idx[N][N];
bool st[N][N];
int map[N][N];
PII start, last;
int h[M], e[E], ne[E], w[E], idxs;
int dx[8] = {2, 2, -2, -2, 1, -1, 1, -1};
int dy[8] = {-1, 1, -1, 1, 2, 2, -2, -2};
void add(int a, int b)
{
e[idxs] = b;
ne[idxs] = h[a];
h[a] = idxs;
idxs ++ ;
}
void dfs(int x, int y)
{
if (st[x][y]) return ;
st[x][y] = true;
for (int i = 0; i < 8; i ++ )
{
int a = x + dx[i], b = y + dy[i];
if (a < 1 || a > n || b < 1 || b > m) continue;
if (st[a][b]) continue;
if (map[a][b] == 1) dfs(a, b);
else if (map[a][b] != 2)
{
st[a][b] = true;
add(idx[x][y], idx[a][b]);
}
}
}
void spfa(int S)
{
queue<int> q;
q.push(S);
memset(dist, 0x3f, sizeof dist);
dist[S] = 0;
cnt[S] = 1;
while (q.size())
{
int t = q.front();
q.pop();
vis[t] = false;
for (int i = h[t]; i != -1; i = ne[i])
{
int j = e[i];
if (dist[j] > dist[t] + 1)
{
cnt[j] = cnt[t];
dist[j] = dist[t] + 1;
if (!vis[j])
{
q.push(j);
vis[j] = true;
}
}
else if (dist[j] == dist[t] + 1) cnt[j] += cnt[t];
}
}
}
int main()
{
cin >> n >> m;
memset(h, -1, sizeof h);
for (int i = 1, t = 0; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
{
cin >> map[i][j];
idx[i][j] = ++ t;
if (map[i][j] == 3) start = {i, j};
if (map[i][j] == 4) last = {i, j};
}
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
if (map[i][j] == 0 || map[i][j] == 3)
{
memset(st, false, sizeof st);
dfs(i, j);
}
spfa(idx[start.x][start.y]);
if (dist[idx[last.x][last.y]] == 0x3f3f3f3f) puts("-1");
else
{
cout << dist[idx[last.x][last.y]] - 1<< endl;
cout << cnt[idx[last.x][last.y]] << endl;
}
return 0;
}