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

#define TASKNAME "covering"

const int MaxN = 9, MaxK = 3, MaxP = 12;

int a [MaxN * 3] [MaxN * 3];
bool b [MaxK] [MaxK];
int d [MaxN * 3] [MaxN * 3];
int count, min, lim;
int m, n;

void recur (int x0, int y0, int x1, int y1, int x2, int y2)
{
 if (x0 < 0 || x0 >= MaxN * 3) return;
 if (y0 < 0 || y0 >= MaxN * 3) return;
 if (d[x0][y0]) return;
 d[x0][y0] = true;
 recur (x0 - x1, y0 - y1, x1, y1, x2, y2);
 recur (x0 + x1, y0 + y1, x1, y1, x2, y2);
 recur (x0 - x2, y0 + y2, x1, y1, x2, y2);
 recur (x0 + x2, y0 - y2, x1, y1, x2, y2);
}

void mark (int dx, int dy, int tx, int ty)
{
 int i, j, p, q;
 bool ok;
 tx += dx; ty += dy;
/*
 printf ("dx = %d, dy = %d\n", dx, dy);
 for (i = dx; i < m + dx; i++)
 {
  for (j = dy; j < n + dy; j++)
   printf ("%d", d[i][j]);
  printf ("\n");
 }
*/
 for (i = dx; i < m + dx + MaxK - 1; i++)
  for (j = dy; j < n + dy + MaxK - 1; j++)
   if (d[i][j] == 1)
   {
    ok = false;
    for (p = 0; p < MaxK; p++)
     for (q = 0; q < MaxK; q++)
      if (!a[i + p][j + q] && b[p][q])
      {
       if (i + p >= tx && i + p < m + tx && j + q >= ty && j + q < n + ty)
        ok = true;
       a[i + p][j + q]++;
      }
    if (ok)
    {
     d[i][j] = 2;
     count++;
    }
   }
/*
 printf ("a:\n");
 for (i = dx; i < m + dx + MaxK - 1; i++)
 {
  for (j = dy; j < n + dy + MaxK - 1; j++)
   printf ("%d", a[i][j]);
  printf ("\n");
 }
*/
}

void excess (int dx, int dy, int tx, int ty)
{
 int i, j, p, q;
 bool ok;
 tx += dx; ty += dy;
 for (i = dx; i < m + dx + MaxK - 1; i++)
  for (j = dy; j < n + dy + MaxK - 1; j++)
   if (d[i][j] == 2)
   {
    ok = false;
     for (p = 0; p < MaxK; p++)
      for (q = 0; q < MaxK; q++)
      if (a[i + p][j + q] == 1 && b[p][q])
       if (i + p >= tx && i + p < m + tx && j + q >= ty && j + q < n + ty)
        ok = true;
    if (!ok)
    {
     for (p = 0; p < MaxK; p++)
      for (q = 0; q < MaxK; q++)
       if (b[p][q])
        a[i + p][j + q]--;
     d[i][j] = 1;
     count--;
    }
   }
/*
 printf ("count = %d\n", count);
 for (i = dx; i < m + dx + MaxK - 1; i++)
 {
  for (j = dy; j < n + dy + MaxK - 1; j++)
   printf ("%d", a[i][j]);
  printf ("\n");
 }
*/
}

void clear (void)
{
 int i, j;
 for (i = 0; i < MaxN * 3; i++)
  for (j = 0; j < MaxN * 3; j++)
   if (d[i][j] == 2)
    d[i][j] = 1;
}

bool check (int dx, int dy)
{
 int i, j;
 bool ok;
 ok = true;
 for (i = dx; i < m + dx; i++)
  for (j = dy; j < n + dy; j++)
   ok &= a[i][j];
/*
 if (ok)
  printf ("checkcount = %d\n", count);
*/
 return ok;
}

int main (void)
{
 int i, j, k, p, q, u, v, x, y, z, t;
 bool ok;
 char c;
 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');
   }
  min = m * n + 1;
  for (x = 0; x <= 5; x++)
   for (y = 0; y <= 5; y++) if (x + y >= 2 && x + y <= 6)
   {
//    fprintf (stderr, "x = %d, y = %d\n", x, y);
    for (z = 0; z <= 5; z++)
     for (t = 1; t <= 5; t++) if (z + t >= 2 && z + t <= 6)
     {
//      if (x != 2 || y != 2 || z != 2 || t != 1) continue;
      memset (d, 0, sizeof (d));
      recur (0, 0, x, y, z, t);
      for (i = 0; i < 6; i++)
       for (j = 0; j < 6; j++)
        for (u = 0; u < MaxK; u++)
         for (v = 0; v < MaxK; v++)
         {
          memset (a, 0, sizeof (a));
          count = 0;
          mark (i, j, u, v);
          excess (i, j, u, v);
          clear ();
          if (check (i + u, j + v))
           if (min > count)
            min = count;
         }
     }
   }
//  fprintf (stderr, "!!!\n");
  for (x = 1; x <= MaxN; x++)
   for (y = 1; y <= MaxN; y++)
    if (x * y < MaxP)
    {
     lim = 1 << (x * y);
     for (u = 0; u < MaxK; u++)
      for (v = 0; v < MaxK; v++)
       for (k = lim - 1; k >= 0; k--)
       {
        memset (a, 0, sizeof (a));
        count = 0;
        for (i = 0; i < m; i++)
         for (j = 0; j < n; j++)
          if (k & (1 << (((i % y) * x) + (j % x))))
          {
           ok = false;
           for (p = 0; p < MaxK; p++)
            for (q = 0; q < MaxK; q++)
             if (!a[i + p][j + q] && b[p][q])
             {
              if (i + p >= u && i + p < m + u && j + q >= v && j + q < n + v)
               ok = true;
              a[i + p][j + q]++;
             }
           if (ok)
           count++;
          }
        for (i = 0; i < m; i++)
         for (j = 0; j < n; j++)
          if (k & (1 << (((i % y) * x) + (j % x))))
          {
           ok = false;
            for (p = 0; p < MaxK; p++)
             for (q = 0; q < MaxK; q++)
             if (a[i + p][j + q] == 1 && b[p][q])
              if (i + p >= u && i + p < m + u && j + q >= v && j + q < n + v)
               ok = true;
           if (!ok)
           {
            for (p = 0; p < MaxK; p++)
             for (q = 0; q < MaxK; q++)
              if (b[p][q])
               a[i + p][j + q]--;
            count--;
           }
          }
        ok = true;
        for (i = u; i < m + u; i++)
         for (j = v; j < n + v; j++)
          ok &= a[i][j];
        if (ok)
         if (min > count)
          min = count;
       }
    }
  printf ("%d\n", min);
 }
 return 0;
}
