#include <bits/stdc++.h>

using namespace std;
using ll = long long;
// #define int ll
using PII = pair<ll, ll>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()

template<typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template<typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template<typename T> bool IN(T a, T b, T x) { return a<=x&&x<b; }
template<typename T> T ceil(T a, T b) { return a/b + !!(a%b); }

template<typename T> vector<T> make_v(size_t a) { return vector<T>(a); }
template<typename T,typename... Ts>
auto make_v(size_t a,Ts... ts) {
    return vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));
}
template<typename T,typename V> typename enable_if<is_class<T>::value==0>::type
fill_v(T &t, const V &v) { t=v; }
template<typename T,typename V> typename enable_if<is_class<T>::value!=0>::type
fill_v(T &t, const V &v ) { for(auto &e:t) fill_v(e,v); }

template<class S,class T>
ostream &operator <<(ostream& out,const pair<S,T>& a) {
    out<<'('<<a.first<<','<<a.second<<')'; return out;
}
template<class T>
ostream &operator <<(ostream& out,const vector<T>& a){
    out<<'[';
    for(const T &i: a) out<<i<<',';
    out<<']';
    return out;
}
template<class T>
ostream &operator <<(ostream& out, const set<T>& a) {
    out<<'{';
    for(const T &i: a) out<<i<<',';
    out<<'}';
    return out;
}
template<class T, class S>
ostream &operator <<(ostream& out, const map<T,S>& a) {
    out<<'{';
    for(auto &i: a) out<<i<<',';
    out<<'}';
    return out;
}

int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0}; // DRUL
const int INF = 1<<30;
const ll LLINF = 1LL<<60;
const ll MOD = 1000000007;

signed main(void)
{
    cin.tie(0);
    ios::sync_with_stdio(false);

    ll test = 0;
    while(1) {
        ll h, n;
        cin >> h >> n;
        if(!h) break;
        vector<string> vv(h+2*n, string(4, '.'));
        REP(i, h) {
            string s, t;
            cin >> s >> t;
            vv[i] = s + t;
        }
        using P = pair<string, string>;
        vector<P> a(n);
        REP(i, n) {
            string s1, s2;
            cin >> s1 >> s2;
            a[i].second = s1 + s2;
            cin >> s1 >> s2;
            a[i].first = s1 + s2;
        }

        // cout << "init" << endl;
        // REP(i, h) cout << vv[i] << endl;
        // cout << endl;

        ll m = 1, ret = 0;
        REP(i, n) m *= 9;
        REP(mask, m) {
            // cout << "mask:" << mask << endl;
            vector<P> b(a);
            ll t = mask;
            bool muri = false;
            REP(i, n) {
                ll rot = t%9;
                t /= 9;

                if(rot == 0) {

                }
                // 右に寄せる
                else if(rot == 1) {
                    if(a[i].first[1]=='#'||a[i].first[3]=='#'||a[i].second[1]=='#'||a[i].second[3]=='#') muri = true;
                    b[i].first[0] = b[i].first[2] = b[i].second[0] = b[i].second[2] = '.';
                    b[i].first[1] = a[i].first[0];
                    b[i].first[3] = a[i].first[2];
                    b[i].second[1] = a[i].second[0];
                    b[i].second[3] = a[i].second[2];
                }
                // 左に寄せる
                else if(rot == 2) {
                    if(a[i].first[0]=='#'||a[i].first[2]=='#'||a[i].second[0]=='#'||a[i].second[2]=='#') muri = true;
                    b[i].first[1] = b[i].first[3] = b[i].second[1] = b[i].second[3] = '.';
                    b[i].first[0] = a[i].first[1];
                    b[i].first[2] = a[i].first[3];
                    b[i].second[0] = a[i].second[1];
                    b[i].second[2] = a[i].second[3];
                }
                // 上に寄せる
                else if(rot == 3) {
                    if(a[i].first[0]=='#'||a[i].first[1]=='#'||a[i].second[0]=='#'||a[i].second[1]=='#') muri = true;
                    b[i].first[2] = b[i].first[3] = b[i].second[2] = b[i].second[3] = '.';
                    b[i].first[0] = a[i].first[2];
                    b[i].first[1] = a[i].first[3];
                    b[i].second[0] = a[i].second[2];
                    b[i].second[1] = a[i].second[3];
                }
                // 下に寄せる
                else if(rot == 4) {
                    if(a[i].first[2]=='#'||a[i].first[3]=='#'||a[i].second[2]=='#'||a[i].second[3]=='#') muri = true;
                    b[i].first[1] = b[i].first[0] = b[i].second[1] = b[i].second[0] = '.';
                    b[i].first[2] = a[i].first[0];
                    b[i].first[3] = a[i].first[1];
                    b[i].second[2] = a[i].second[0];
                    b[i].second[3] = a[i].second[1];
                }
                // 左上に寄せる
                else if(rot == 5) {
                    if(a[i].first[1]=='#'||a[i].first[2]=='#'||a[i].first[0]=='#'||a[i].second[1]=='#'||a[i].second[2]=='#'||a[i].second[0]=='#') muri = true;
                    b[i].first[3] = b[i].second[3] = '.';
                    b[i].first[0] = a[i].first[3];
                    b[i].second[0] = a[i].second[3];
                }
                // 右上に寄せる
                else if(rot == 6) {
                    if(a[i].first[1]=='#'||a[i].first[0]=='#'||a[i].first[3]=='#'||a[i].second[1]=='#'||a[i].second[0]=='#'||a[i].second[3]=='#') muri = true;
                    b[i].first[2] = b[i].second[2] = '.';
                    b[i].first[1] = a[i].first[2];
                    b[i].second[1] = a[i].second[2];
                }
                // 左下に寄せる
                else if(rot == 7) {
                    if(a[i].first[0]=='#'||a[i].first[2]=='#'||a[i].first[3]=='#'||a[i].second[0]=='#'||a[i].second[2]=='#'||a[i].second[3]=='#') muri = true;
                    b[i].first[1] = b[i].second[1] = '.';
                    b[i].first[2] = a[i].first[1];
                    b[i].second[2] = a[i].second[1];
                }
                // 右下に寄せる
                else if(rot == 8) {
                    if(a[i].first[1]=='#'||a[i].first[2]=='#'||a[i].first[3]=='#'||a[i].second[1]=='#'||a[i].second[2]=='#'||a[i].second[3]=='#') muri = true;
                    b[i].first[0] = b[i].second[0] = '.';
                    b[i].first[3] = a[i].first[0];
                    b[i].second[3] = a[i].second[0];
                }
            }
            if(muri) continue;

            // REP(i, n) cout << b[i] << endl;

            ll cnt = 0;
            auto v(vv);
            REP(i, n) {
                bool flag1 = false, flag2 = false, stop = false;
                REP(j, 4) {
                    if(b[i].second[j]=='#') flag1 = true;
                    if(b[i].first[j]=='#') flag2 = false;
                }
                // 高さjにブロックの下の段が来るパターン
                for(ll j=h+2*n-1; j>=0; --j) {
                    if((j==0&&flag1) || (j&&v[j-1][0]=='#'&&v[j-1][0]==b[i].second[0]) || (j&&v[j-1][1]=='#'&&v[j-1][1]==b[i].second[1]) || (j&&v[j-1][2]=='#'&&v[j-1][2]==b[i].second[2]) || (j&&v[j-1][3]=='#'&&v[j-1][3]==b[i].second[3])) {
                        // cout << "hit second " << j << endl;
                        REP(k, 4) {
                            if(b[i].second[k]=='#') v[j][k] = '#';
                            if(b[i].first[k]=='#') v[j+1][k] = '#';
                        }
                        stop = true;
                        break;
                    }
                    if((v[j][0]=='#'&&v[j][0]==b[i].first[0]) || (v[j][1]=='#'&&v[j][1]==b[i].first[1]) || (v[j][2]=='#'&&v[j][2]==b[i].first[2]) || (v[j][3]=='#'&&v[j][3]==b[i].first[3])) {
                        // cout << "hit first " << j << endl;
                        REP(k, 4) {
                            if(b[i].second[k]=='#') v[j][k] = '#';
                            if(b[i].first[k]=='#') v[j+1][k] = '#';
                        }
                        stop = true;
                        break;
                    }
                }
                if(!stop) {
                    // cout << "hit first last " << endl;
                    REP(k, 4) {
                        if(b[i].first[k]=='#') v[0][k] = '#';
                    }
                }
                // REP(j, h+2*n) cout << "height=" << j << " " << v[j] << endl;
                // 消える段があったら消す
                REP(j, h+2*n) {
                    if(v[j][0]=='#'&&v[j][1]=='#'&&v[j][2]=='#'&&v[j][3]=='#') {
                        v[j][0] = v[j][1] = v[j][2] = v[j][3] = '.';
                        FOR(k, j, h+2*n-1) {
                            v[k][0] = v[k+1][0];
                            v[k][1] = v[k+1][1];
                            v[k][2] = v[k+1][2];
                            v[k][3] = v[k+1][3];
                        }
                        j--;
                        cnt++;
                    }
                }
            }
            chmax(ret, cnt);
        }

        cout << ret << endl;
    }

    return 0;
}



Measured memory_bytes: 3240