#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:16777216")
using namespace std;
template <class T>
void pv(T a, T b) {
  for (T i = a; i != b; ++i) cout << (int)*i << " ";
  cout << endl;
}
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
const long long INF = 0x3f3f3f3f3f3f3f3fLL;
const int maxn = 300;
const int mod = 1e9 + 7;
int grid[maxn][maxn], n, m;
long long f[maxn], g[maxn], h[maxn][2], tmp[maxn][2];
int horizontal[20][20];
int vertical[20][20];
char c[1 << 10][1 << 10];
string A[7] = {".........", "....O....", "..O...O..", "..O.O.O..",
               "O.O...O.O", "O.O.O.O.O", "O.OO.OO.O"};
string B[7];
map<string, int> mapa;
void dump(int x, int id = 0) {
  string s;
  for (map<string, int>::iterator iter = mapa.begin(); iter != mapa.end();
       iter++)
    if (iter->second == x) s = iter->first;
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) printf("%c", s[id++]);
    printf("\n");
  }
}
string getB(string s) {
  char tab[3][3], id = 0;
  for (int j = 2; j >= 0; j--)
    for (int i = 0; i < 3; i++) tab[i][j] = s[id++];
  string r("");
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++) r += tab[i][j];
  return r;
}
int main() {
  for (int i = 0; i < 7; i++) {
    B[i] = getB(A[i]);
    mapa[A[i]] = mapa[B[i]] = 1;
    swap(A[i], B[i]);
  }
  int id = 1;
  for (map<string, int>::iterator iter = mapa.begin(); iter != mapa.end();
       iter++) {
    iter->second = id++;
  }
  for (int i = 0; i < 7; i++)
    for (int j = 0; j < 7; j++) {
      horizontal[mapa[A[i]]][mapa[A[j]]] = 1;
      vertical[mapa[B[i]]][mapa[B[j]]] = 1;
    }
  cin >> n >> m;
  for (int i = 0; i < 4 * n + 1; i++) scanf("%s", c[i]);
  if ((n * m) & 1) {
    puts("0");
    return 0;
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      int x = 1 + 4 * i, y = 1 + 4 * j;
      string s("");
      for (int di = 0; di < 3; di++) {
        for (int dj = 0; dj < 3; dj++) {
          s += c[x + di][y + dj];
        }
      }
      assert(mapa.count(s));
      grid[i][j] = mapa[s];
    }
  }
  for (int j = 0; j < m; j++) {
    f[j] = (n % 2 == 0);
    for (int i = 0; i < n; i += 2) {
      f[j] &= vertical[grid[i][j]][grid[i + 1][j]];
    }
  }
  for (int j = 0; j + 1 < m; j++) {
    memset(tmp, 0, sizeof tmp), tmp[0][0] = 1;
    for (int i = 0; i < n; i++)
      for (int k = 0; k < 2; k++) {
        tmp[i + 1][1] += tmp[i][k] * horizontal[grid[i][j]][grid[i][j + 1]];
        tmp[i + 1][1] %= mod;
        tmp[i + 2][k] += tmp[i][k] * vertical[grid[i][j]][grid[i + 1][j]] *
                         vertical[grid[i][j + 1]][grid[i + 1][j + 1]];
        tmp[i + 2][k] %= mod;
      }
    g[j] = tmp[n][1];
  }
  h[0][0] = f[0];
  h[0][1] = g[0];
  for (int i = 1; i < m; i++) {
    h[i][0] = f[i] * (h[i - 1][0] + ((i - 1) ? h[i - 2][1] : 0)) % mod;
    h[i][1] = g[i] * (h[i - 1][0] + ((i - 1) ? h[i - 2][1] : 0)) % mod;
  }
  long long ret = h[m - 1][0] + ((m - 1) ? h[m - 2][1] : 0);
  ret %= mod;
  cout << ret << endl;
  return 0;
}
