import java.io.*;
import java.util.*;
class Main{
static BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
static int N = 13, M = 1 << 12;
static int[][] dp = new int[N][M];
public static void main(String[] args) throws Exception{
String[] ss = read.readLine().split(" ");
int n = Integer.valueOf(ss[0]);
int m = Integer.valueOf(ss[1]);
int mod = 100000000;
//初始化, 存玉米田地
List<List<Integer>> arr = new ArrayList();
for(int i = 1; i <= n; i++){
ss = read.readLine().split(" ");
List<Integer> tmp = new ArrayList();
for(int j = 1; j <= m; j++){
//取反, 方便后面计算
int a = Integer.valueOf(ss[j - 1]) ^ 1;
tmp.add(a);
}
arr.add(tmp);
}
//把转换成10进制的玉米田状态存入一个数组中
List<Integer> using = new ArrayList();
//第0行的玉米田不能中玉米,全部初始化为1
using.add((1 << m) - 1);
for(List<Integer> tmp: arr){
using.add(calculate(tmp));
}
//初始化, 保存不连续为1的状态
List<Integer> notContinueOneList = new ArrayList();
for(int i = 0; i < 1 << m; i++){
if(!continueOne(i, m)) notContinueOneList.add(i);
}
//初始化, 保存状态j,k不连续, 且j & k == 0
List<int[]> need = new ArrayList();
for(int i = 0; i < notContinueOneList.size(); i++){
int j = notContinueOneList.get(i);
for(int o = 0; o < notContinueOneList.size(); o++){
int k = notContinueOneList.get(o);
if((j & k) == 0) need.add(new int[]{j, k});
}
}
//初始化dp
dp[0][0] = 1;
for(int i = 1; i <= n; i++){
//t1 当前第i - 1行玉米地的状态
int t1 = using.get(i - 1);
int t2 = using.get(i);
for(int[] ints: need){
int j = ints[0];
int k = ints[1];
if((t1 & k) == 0 && (t2 & j) == 0){
dp[i][j] = (dp[i][j] + dp[i-1][k]) % mod;
}
}
}
int ans = 0;
for(int i = 0; i < 1 << m; i++){
if((i & using.get(n)) == 0) ans = (ans + dp[n][i]) % mod;
}
System.out.println(ans);
}
//判断是否存在连续的1
public static boolean continueOne(int a, int n){
for(int i = 1; i < n; i++){
if((a >> i & 1) != 0 && (a >> i - 1 & 1) != 0) return true;
}
return false;
}
//将二进制转换为十进制
public static int calculate(List<Integer> tmp){
int ans = 0;
for(int i = tmp.size() - 1; i >= 0; i--){
if(tmp.get(i) == 1) ans += (int) Math.pow(2, i);
}
return ans;
}
}
%%%
太巨了