#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#define TASKNAME "covering"

const int MaxN = 9, MaxK = 3, NUM = 6, MaxP = 8,
 MaxL = (MaxN + MaxK) * (MaxN + MaxK) + 1;

int a [MaxN + MaxK * 2] [MaxN + MaxK * 2];
bool b [MaxK] [MaxK];
int left [MaxL] [NUM], right [MaxL] [NUM];
bool tile [MaxL];
int cell [MaxL];
int x [MaxP], y [MaxP * NUM];
int count, min;

inline void add (int z)
{
 assert (z && !tile[z]);
 cell[left[z][0]]++;
 cell[left[z][1]]++;
 cell[left[z][2]]++;
 cell[left[z][3]]++;
 cell[left[z][4]]++;
 cell[left[z][5]]++;
 tile[z] = true;
 count++;
}

inline void rem (int z)
{
 assert (z && tile[z]);
 cell[left[z][0]]--;
 cell[left[z][1]]--;
 cell[left[z][2]]--;
 cell[left[z][3]]--;
 cell[left[z][4]]--;
 cell[left[z][5]]--;
 tile[z] = false;
 count--;
}

int main (void)
{
 int i, j, k, l, m, n, p, q, r;
 int t;
 char c;
 srand (12314);
 freopen (TASKNAME ".in", "r", stdin);
 freopen (TASKNAME ".out", "w", stdout);
 while (scanf (" %d %d", &m, &n) != EOF)
 {
  assert (1 <= m && m <= MaxN);
  assert (1 <= n && n <= MaxN);
  for (i = 0; i < MaxK; i++)
   for (j = 0; j < MaxK; j++)
   {
    assert (scanf (" %c", &c) == 1);
    assert (c == 'X' || c == '.');
    b[j][i] = (c == 'X');
   }
  count = 0;
  for (i = 0; i < MaxK; i++)
   for (j = 0; j < MaxK; j++)
    if (b[i][j])
     count++;
  assert (count == NUM);
  memset (a, 0, sizeof (a));
  memset (left, 0, sizeof (left));
  memset (right, 0, sizeof (right));
  l = 1; // cells
  for (i = MaxK; i < m + MaxK; i++)
   for (j = MaxK; j < n + MaxK; j++)
    a[i][j] = l++;
  k = 1; // tiles
  for (i = 1; i < m + MaxK; i++)
   for (j = 1; j < n + MaxK; j++)
   {
    r = 0;
    for (p = 0; p < MaxK; p++)
     for (q = 0; q < MaxK; q++)
      if (b[p][q])
       left[k][r++] = a[i + p][j + q];
    k++;
   }
  for (i = 1; i < l; i++)
  {
   r = 0;
   for (j = 1; j < k; j++)
    for (p = 0; p < NUM; p++)
     if (left[j][p] == i)
      right[i][r++] = j;
   assert (r == NUM);
  }
  // left is from tile to cell
  // right is from cell to tile
  memset (cell, 0, sizeof (cell));
  memset (tile, 0, sizeof (tile));
  count = 0;
  for (i = 1; i < k; i++)
   add (i);
  min = MaxL;
  for (t = 0; t < 1000000; t++)
  {
   r = rand () % MaxP + 1;
   for (i = 0; i < r; i++)
   {
    if (count <= 0) break;
    do
    {
     x[i] = rand () % (k - 1) + 1;
    }
    while (!tile[x[i]]);
    rem (x[i]);
   }
   r = i;
   p = 0;
   for (i = 1; i < l; i++)
    if (!cell[i])
    {
     y[p] = right[i][rand () % NUM];
     add (y[p]);
     p++;
    }
   if (min > count)
    min = count;
  }
  printf ("%d\n", min);
 }
 return 0;
}
