1 #include<cstdio>
2 #include<cstring>
3 #include<iostream>
4 using namespace std;
5 #define N 15
6 #define mod 100000000
7
8 int map[N][N],map_num[N],dp[N][1<<N];
9
10 bool check_raw(int num)//判断同一行上是否合法,如10110则不合法
11 {
12 for(int i=1; i<num; i<<=1 )//一位一位判断,每合法一位则左移一位
13 {
14 if((num & i) != 0 && (num & (i<<1)) != 0)
15 return false;
16 }
17 return true;
18 }
19
20 bool check_line (int a,int b)//判断同一列上是否合法
21 {
22 if((a & b)==0)
23 return true;
24 else
25 return false;
26 }
27
28 bool check_map(int num , int mp_num)//判断是否种在肥沃土地上
29 /*
30 1010110
31 0010100
32 则合法
33 */
34 {
35 if((num & mp_num)==num)
36 return true ;
37 else
38 return false;
39 }
40
41 int main()
42 {
43 int n,m;
44 while(~scanf("%d%d", &n,&m))
45 {
46 for(int i=0; i<n; i++)
47 {
48 int sum = 0;
49 int k = m-1;
50 for(int j=0; j<m; j++)
51 {
52 scanf("%d",&map[i][j]);
53 sum += map[i][j] * (1<<k);
54 k--;
55 }
56 map_num[i] = sum;//每行的和
57 }
58
59 int len = 1 << m;
60 memset(dp,0,sizeof(dp));
61
62 for(int j=0; j<len; j++)
63 {
64 if(check_raw(j) && check_map(j,map_num[0]))
65 dp[0][j] = 1;
66 }
67
68 for(int i=1; i<n; i++)
69 {
70 for(int j=0; j<len; j++)
71 {
72 for(int k=0; k<len; k++)
73 {
74 if(dp[i-1][k] && check_raw(j) && check_map(j,map_num[i]) && check_line(j,k))
75 {
76 dp[i][j] += dp[i-1][k];
77 dp[i][j] %= mod;
78 }
79 }
80 }
81 }
82 int ans =0 ;
83 for(int j=0; j<len; j++)
84 {
85 ans += dp[n-1][j];
86 ans %= mod;
87 }
88 printf("%d\n",ans);
89 }
90 return 0;
91 }