#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:268435456")
using namespace std;
template <typename T>
inline T abs(T a) {
  return ((a < 0) ? -a : a);
}
template <typename T>
inline T sqr(T a) {
  return a * a;
}
template <class T>
T gcd(T a, T b) {
  return a ? gcd(b % a, a) : b;
}
template <class T>
T lcm(T a, T b) {
  return a / gcd(a, b) * b;
}
template <class T>
T sign(T a) {
  return a > 0 ? 1 : (a < 0 ? -1 : 0);
}
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};
const int dxK[] = {-1, -1, 0, 1, 1, 1, 0, -1};
const int dyK[] = {0, 1, 1, 1, 0, -1, -1, -1};
const int dxKn[] = {-2, -1, 1, 2, 2, 1, -1, -2};
const int dyKn[] = {1, 2, 2, 1, -1, -2, -2, -1};
const int N = int(3e2) + 5;
const int M = int(3e2) + 9;
const int LOGN = 21;
const int SQN = 350;
const int MOD = int(1e9) + 7;
const int INF = int(1e9) + 100;
const long long INF64 = 2e18;
const double PI = double(3.1415926535897932384626433832795);
const double e = double(2.7182818284590452353602874713527);
const double EPS = 1e-9;
int n, m;
string s[N * 4];
int a[N][N];
int dp[N][N][2][2];
int DP[N];
int f(string cur, int cnt) {
  string s3 = "O...O...O";
  string s2 = "O.......O";
  string s6 = "OOO...OOO";
  if (cnt == 2) return (cur == s2 ? 1 : 2);
  if (cnt == 3) return (cur == s3 ? 1 : 2);
  if (cnt == 6) return (cur == s6 ? 1 : 2);
}
int calc(int i);
int calc(int i, int j, bool needH, bool uH) {
  int &res = dp[i][j][needH][uH];
  if (res != -1) return res;
  if (i == n) {
    int res = 1;
    if (needH && !uH) res = 0;
    res *= calc(j + 1 + needH);
    res %= MOD;
    return res;
  }
  res = 0;
  if (needH) {
    if (a[i][j] != 2 && a[i][j + 1] != 2) {
      res += calc(i + 1, j, needH, true);
      res %= MOD;
    }
    if (i + 1 < n && a[i][j] != 1 && a[i + 1][j] != 1 && a[i][j + 1] != 1 &&
        a[i + 1][j + 1] != 1) {
      res += calc(i + 2, j, needH, uH);
      res %= MOD;
    }
    return res;
  } else {
    if (i == n - 1) return res = 0;
    if (a[i][j] == 1 || a[i + 1][j] == 1) return res = 0;
    return calc(i + 2, j, needH, uH);
  }
  return res;
}
int calc(int j) {
  int &res = DP[j];
  if (res != -1) return res;
  if (j == m) return res = 1;
  res = 0;
  res += calc(0, j, 0, 0);
  res %= MOD;
  if (j + 1 < m) res += calc(0, j, 1, 0);
  res %= MOD;
  return res;
}
void solve() {
  cin >> n >> m;
  for (int i = 0; i < (int)(4 * n + 1); ++i) cin >> s[i];
  for (int i = 0; i < (int)(n); ++i)
    for (int j = 0; j < (int)(m); ++j) {
      int cnt = 0;
      string cur = "";
      for (int ii = i * 4 + 1; ii < i * 4 + 4; ++ii)
        for (int jj = j * 4 + 1; jj < j * 4 + 4; ++jj) {
          if (s[ii][jj] == 'O') ++cnt;
          cur += s[ii][jj];
        }
      if (cnt == 2)
        a[i][j] = f(cur, 2);
      else if (cnt == 3)
        a[i][j] = f(cur, 3);
      else if (cnt == 6)
        a[i][j] = f(cur, 6);
      else
        a[i][j] = 0;
    }
  memset(dp, -1, sizeof dp);
  memset(DP, -1, sizeof DP);
  cout << calc(0);
}
int main() {
  srand(time(NULL));
  cout << setprecision(25) << fixed;
  cerr << setprecision(25) << fixed;
  solve();
  return 0;
}
