1 /*Author:WNJXYK*/
2 #include<cstdio>
3 #include<queue>
4 #include<cstring>
5 using namespace std;
6
7 const int Maxn=30;
8 int n,m;
9 int map[Maxn+10][Maxn+10];
10
11 queue<pair<int,int> > que;
12 int cost[Maxn+10][Maxn+10];
13 int dist[Maxn+10][Maxn+10];
14 long long ways[Maxn+10][Maxn+10];
15 bool inque[Maxn+10][Maxn+10];
16 int dx[]={0,1,2,2,1,-1,-2,-2,-1};
17 int dy[]={0,-2,-1,1,2,2,1,-1,-2};
18
19 inline void BFS(int s_x,int s_y,int e_x,int e_y){
20 que.push(make_pair(s_x,s_y));
21 memset(cost,127,sizeof(cost));
22 cost[s_x][s_y]=0;
23 dist[s_x][s_y]=0;
24 ways[s_x][s_y]=1;
25 inque[s_x][s_y]=true;
26 while(!que.empty()){
27 int nowx=que.front().first,nowy=que.front().second;
28 que.pop();
29 if (nowx==e_x && nowy==e_y) continue;
30 for (int k=1;k<=8;k++){
31 int x=nowx+dx[k],y=nowy+dy[k];
32 if (!(1<=x && x<=n && 1<=y && y<=m)) continue;
33 if (map[x][y]==2) continue;
34 int w=0;if (map[x][y]==0) w=1;
35 if (cost[x][y]>cost[nowx][nowy]+w){
36 cost[x][y]=cost[nowx][nowy]+w;
37 dist[x][y]=dist[nowx][nowy]+1;
38 ways[x][y]=ways[nowx][nowy];
39 if (inque[x][y]==false){
40 inque[x][y]=true;
41 que.push(make_pair(x,y));
42 }
43 }else if (cost[x][y]==cost[nowx][nowy]+w){
44 if(dist[x][y]>dist[nowx][nowy]+1){
45 dist[x][y]=dist[nowx][nowy]+1;
46 ways[x][y]=ways[nowx][nowy];
47 if (inque[x][y]==false){
48 inque[x][y]=true;
49 que.push(make_pair(x,y));
50 }
51 }else if (dist[x][y]==dist[nowx][nowy]+1){
52 ways[x][y]+=ways[nowx][nowy];
53 if (inque[x][y]==false){
54 inque[x][y]=true;
55 que.push(make_pair(x,y));
56 }
57 }
58 }
59 }
60 inque[nowx][nowy]=false;
61 }
62 }
63
64 int main(){
65 scanf("%d%d",&n,&m);
66 int sx,sy,ex,ey;
67 for (int i=1;i<=n;i++){
68 for (int j=1;j<=m;j++){
69 scanf("%d",&map[i][j]);
70 if (map[i][j]==3){
71 sx=i;sy=j;
72 }
73 if (map[i][j]==4){
74 ex=i;ey=j;
75 }
76 }
77 }
78 BFS(sx,sy,ex,ey);
79 if (cost[ex][ey]==cost[0][0] || ways[ex][ey]==0){
80 printf("-1\n");
81 }else{
82 printf("%d\n%d\n%lld\n",cost[ex][ey],dist[ex][ey],ways[ex][ey]);
83 }
84 return 0;
85 }