#include <bits/stdc++.h>
using namespace std;
vector<string> ver[7] = {{"...", "...", "..."}, {"...", ".O.", "..."},
                         {"..O", "...", "O.."}, {"..O", ".O.", "O.."},
                         {"O.O", "...", "O.O"}, {"O.O", ".O.", "O.O"},
                         {"O.O", "O.O", "O.O"}};
vector<string> hor[7] = {{"...", "...", "..."}, {"...", ".O.", "..."},
                         {"O..", "...", "..O"}, {"O..", ".O.", "..O"},
                         {"O.O", "...", "O.O"}, {"O.O", ".O.", "O.O"},
                         {"OOO", "...", "OOO"}};
char ss[1200][1200];
int n, m;
vector<string> rr[255][255];
long long type[255][255];
bool verOk[255];
long long horOk[255][255];
long long horNum[255];
long long dp[255], dp2[255];
long long vv[255][255][255], vv2[255][255];
const long long MOD = 1000000007;
long long sol(int pos) {
  if (pos < 0) return 1;
  if (dp[pos] != -1) return dp[pos];
  auto &ele = dp[pos];
  if (pos == 0) {
    if (verOk[0])
      return ele = 1;
    else
      return ele = 0;
  } else {
    long long ans1 = sol(pos - 1);
    long long ans2 = sol(pos - 2);
    int ret = 0;
    if (verOk[pos]) ret = (ret + ans1) % MOD;
    long long tmp = (long long)horNum[pos - 1] * ans2 % MOD;
    ret = (ret + tmp) % MOD;
    return ele = ret;
  }
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < 4 * n + 1; i++) {
    scanf("%s", ss[i]);
  }
  for (int i = 1; i <= 4 * n - 3; i += 4) {
    for (int j = 1; j <= 4 * m - 3; j += 4) {
      int r1 = i, r2 = i + 2;
      vector<string> tmp;
      for (int r = r1; r <= r2; r++) {
        tmp.push_back(string(ss[r] + j, ss[r] + j + 3));
      }
      rr[i / 4][j / 4] = tmp;
    }
  }
  for (int r = 0; r < n; r++) {
    for (int c = 0; c < m; c++) {
      bool find = 0;
      for (int s = 0; s < 7; s++) {
        if (rr[r][c] == hor[s]) {
          find = 1;
          break;
        }
      }
      bool find2 = 0;
      for (int s = 0; s < 7; s++) {
        if (rr[r][c] == ver[s]) {
          find2 = 1;
          break;
        }
      }
      if (find && find2)
        type[r][c] = 3;
      else if (find)
        type[r][c] = 1;
      else
        type[r][c] = 2;
    }
  }
  memset(horOk, 0, sizeof(horOk)), memset(verOk, 0, sizeof(verOk)),
      memset(vv2, 0, sizeof(vv2));
  for (int c = 0; c < m; c++) {
    if (n % 2 == 1)
      verOk[c] = 0;
    else {
      bool ok = 1;
      for (int r = 0; r < n; r++)
        if (type[r][c] == 1) {
          ok = 0;
          break;
        }
      verOk[c] = ok;
    }
    for (int r = 1; r < n; r++) {
      if (type[r][c] != 1 && type[r - 1][c] != 1) vv2[c][r] = 1;
    }
  }
  memset(vv, 0, sizeof(vv));
  for (int c = 0; c < m; c++) {
    for (int s = 2; s <= n; s = s + 2) {
      for (int r = 0; r <= n - s; r++) {
        int r2 = r + s - 1;
        if (s == 2)
          vv[c][r][r2] = vv2[c][r2];
        else {
          if (vv2[c][r2] == 0)
            vv[c][r][r2] = 0;
          else
            vv[c][r][r2] = vv[c][r][r2 - 2];
        }
      }
    }
  }
  for (int c = 0; c < m - 1; c++) {
    for (int r = 0; r < n; r++) {
      if (type[r][c] != 2 && type[r][c + 1] != 2) {
        horOk[r][c] = 1;
      } else
        horOk[r][c] = 0;
    }
  }
  for (int c = 0; c < m - 1; c++) {
    horNum[c] = 0;
    memset(dp2, 0, sizeof(dp2));
    for (int r = 0; r < n; r++) {
      if (horOk[r][c] == 1) {
        if (r == 0 || (vv[c][0][r - 1] && vv[c + 1][0][r - 1])) dp2[r] = 1;
        for (int i = 0; i < r; i++) {
          if ((r - i - 1) % 2 == 0 && horOk[i][c] == 1 &&
              (i + 1 == r ||
               (vv[c][i + 1][r - 1] && vv[c + 1][i + 1][r - 1]))) {
            dp2[r] = (dp2[r] + dp2[i]) % MOD;
          }
        }
        if (r == n - 1 || (vv[c][r + 1][n - 1] && vv[c + 1][r + 1][n - 1])) {
          horNum[c] = (horNum[c] + dp2[r]) % MOD;
        }
      }
    }
  }
  memset(dp, -1, sizeof(dp));
  printf("%lld\n", sol(m - 1));
  return 0;
}
