#include <bits/stdc++.h>
using namespace std;
int decode(string q) {
  int count = 0;
  for (int i = 0; i < 9; ++i) count += (q[i] == 'O');
  if (count == 0 || count == 1 || count == 4 || count == 5) return 3;
  if (count == 2 || count == 3) return 1 + (q[0] == 'O');
  return 1 + (q[1] == 'O');
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n, m;
  cin >> n >> m;
  vector<string> v(4 * n + 1);
  for (int i = 0; i < 4 * n + 1; ++i) cin >> v[i];
  vector<vector<int> > a(n, vector<int>(m));
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j)
      a[i][j] = decode(v[4 * i + 1].substr(4 * j + 1, 3) +
                       v[4 * i + 2].substr(4 * j + 1, 3) +
                       v[4 * i + 3].substr(4 * j + 1, 3));
  vector<long long> vert(m - 1);
  const long long MOD = 1000000007;
  vector<bool> isVert(m, 0);
  if (n % 2 == 0) {
    for (int j = 0; j < m; ++j) {
      bool fail = 0;
      for (int i = 0; i < n; ++i)
        if (a[i][j] == 2) {
          fail = 1;
          break;
        }
      if (!fail) isVert[j] = 1;
    }
  }
  for (int j = 0; j < m - 1; ++j) {
    vector<long long> dp(n + 1);
    dp[0] = 1;
    for (int i = 0; i < n; ++i) {
      dp[i + 1] = 0;
      if ((a[i][j] & 2) && (a[i][j + 1] & 2)) dp[i + 1] = dp[i];
      if (i && (a[i - 1][j] & 1) && (a[i - 1][j + 1] & 1) && (a[i][j] & 1) &&
          (a[i][j + 1] & 1))
        dp[i + 1] = (dp[i + 1] + dp[i - 1]) % MOD;
    }
    vert[j] = dp[n];
    if (isVert[j] && isVert[j + 1]) --vert[j];
  }
  vector<long long> dp(m + 1);
  dp[0] = 1;
  for (int i = 0; i < m; ++i) {
    dp[i + 1] = 0;
    if (isVert[i]) dp[i + 1] = dp[i];
    if (i == 0) continue;
    dp[i + 1] = (((vert[i - 1] * dp[i - 1]) % MOD) + dp[i + 1]) % MOD;
  }
  cout << dp[m] << endl;
}
