#include <bits/stdc++.h>
using namespace std;
template <class T>
T abs(T x) {
  return x > 0 ? x : -x;
}
const string dom[2][7] = {{".........", "....O....", "O.......O", "O...O...O",
                           "O.O...O.O", "O.O.O.O.O", "OOO...OOO"},
                          {".........", "....O....", "..O...O..", "..O.O.O..",
                           "O.O...O.O", "O.O.O.O.O", "O.OO.OO.O"}};
const int mod = 1000000007;
int n;
int m;
char w[1002][1002];
int g[250][250];
int can[250], can2[250];
int cnt[251], res[251];
int get(int i, int j) {
  string s = "";
  for (int p = 0; p < 3; p++)
    for (int q = 0; q < 3; q++) s += w[i + p][j + q];
  int res = 0;
  for (int p = 0; p < 2; p++)
    for (int q = 0; q < 7; q++)
      if (s == dom[p][q]) res |= (p + 1);
  return res;
}
int main() {
  scanf("%d%d", &n, &m);
  gets(w[0]);
  for (int i = 0; i < 4 * n + 1; i++) gets(w[i]);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) g[i][j] = get(4 * i + 1, 4 * j + 1);
  for (int j = 0; j < m; j++) {
    can[j] = int(n % 2 == 0);
    for (int i = 0; i < n; i++) can[j] &= int((g[i][j] & 2) != 0);
  }
  for (int j = 0; j + 1 < m; j++) {
    memset(cnt, 0, sizeof(cnt));
    cnt[0] = 1;
    for (int i = 0; i < n; i++) {
      if (g[i][j] & g[i][j + 1] & 1) cnt[i + 1] = (cnt[i + 1] + cnt[i]) % mod;
      if (i + 1 < n &&
          int(g[i][j] & g[i + 1][j] & g[i][j + 1] & g[i + 1][j + 1] & 2))
        cnt[i + 2] = (cnt[i + 2] + cnt[i]) % mod;
    }
    can2[j] = (cnt[n] - can[j] * can[j + 1] + mod) % mod;
  }
  memset(res, 0, sizeof(res));
  res[0] = 1;
  for (int j = 0; j < m; j++) {
    if (can[j]) res[j + 1] = (res[j + 1] + res[j]) % mod;
    if (j + 1 < m)
      res[j + 2] = (res[j + 2] + (long long)res[j] * can2[j]) % mod;
  }
  printf("%d\n", res[m]);
  return 0;
}
