#include <iostream>usingnamespacestd;
constint maxn = 20;
constint INF = (1 << 13);
constint mod = 100000000;
int state[INF];
int dp[20][INF];
int cur[maxn];
int n, m, top;
bool ok(int s)
{
if (s&(s << 1))//判断放的位置是否有相邻的情况returnfalse;
returntrue;
}
bool fit(int x, int k)
{
if (x&cur[k])//判断状态x 与k行是否可以摆放returnfalse;
returntrue;
}
void init()
{
top = 0;
int ans = 1 << n;//有n列每列可以放或者不放所以有2^n种情况for (int i = 0; i < ans; i++)
{
if (ok(i))
state[++top] = i;//存下所有放的位置合法的情况
}
}
int main()
{
while (cin >> m >> n)
{
init();
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= m; i++)
{
cur[i] = 0;
int num;
for (int j = 1; j <= n; j++)
{
cin >> num;
if (num == 0)
{
cur[i] += 1 << (n - j);//如果num为0表示这个位置不可以摆放, 所以在cur中将这个位置表示为1表示不可以摆放
}
}
}
;
for (int i = 1; i <= top; i++)
{
if (fit(state[i], 1))
dp[1][i] = 1;
}
for(int i = 2; i <= m; i++)
{
for (int k = 1; k <= top; k++)
{
if (!fit(state[k], i))//判 断第i行是否可以摆放(不考虑第i-1行的情况下)continue;
for (int j = 1; j <= top; j++)
{
if (!fit(state[j], i - 1))//判断第i-1行是否可以摆放continue;
if (state[k] & state[j])//判断相邻的两行是否可以摆放,与运算continue;
dp[i][k] = (dp[i][k]+dp[i - 1][j])%mod;
}
}
}
int ans = 0;
for (int i = 1; i <= top; i++)
ans = (ans + dp[m][i]) % mod;//只需要将最后一行情况相加即可printf("%d\n", ans);
}
}