#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>
#include <tuple>
using namespace std;
using Board = vector< vector< vector<int> > >;

int H, N;

int dx[] = {0, 1, -1, 0, 1, -1, 0, 1, -1};
int dy[] = {0, 0, 0, 1, 1, 1, -1, -1, -1};

// 全て埋まっている: 1, なにも埋まっていない: 2, それ以外: 0
int comp(Board board, int z) {
    bool complete = true, none = true;
    for(int x=0; x<2; x++) {
        for(int y=0; y<2; y++) {
            if(board[z][x][y] == 1) {
                none = false;
            }
            else {
                complete = false;
            }
        }
    }
    if(complete) return 1;
    if(none) return 2;
    return 0;
}

void boardfall(Board &board) {
    for(int z = 20; z > 0; z--) {
        int top = z - 1;
        if(comp(board, top) == 2) {
            swap(board[z], board[top]);
        }
    }
}

void print_board(Board board) {
    for(int z=0; z<20; z++) {
        if(comp(board, z) == 2) continue;
        printf("board (z = %d):\n", z);
        for(auto x : board[z][0]) cout << x;
        cout << endl;
        for(auto x : board[z][1]) cout << x;
        cout << endl << endl;
    }
}

pair<Board, int> modify_board(Board board, Board block) {
    int z;
    // block の下の段に何もなければ swap
    if(comp(block, 0) == 2) swap(block[0], block[1]);

    for(z = 20; z > 0; z--) {
        // block の底面が z に位置する
        // 下に行けるかどうかのチェック
        int top = z - 1;
        bool ok = true;
        for(int dz=0; dz<2; dz++) {
            for(int x=0; x<2; x++) {
                for(int y=0; y<2; y++) {
                    if(board[top+dz][x][y] && block[dz][x][y]) ok = false;
                }
            }
        }

        if(!ok) break;
    }

    // printf("! z = %d\n", z);

    for(int dz=0; dz<2; dz++) {
        for(int x=0; x<2; x++) {
            for(int y=0; y<2; y++) {
                board[z+dz][x][y] |= block[dz][x][y];
            }
        }
    }

    int get_combo = 0;
    for(int z=0; z<20; z++) {
        // 全て埋まっている
        if(comp(board, z) == 1) {
            for(int x=0; x<2; x++) {
                for(int y=0; y<2; y++) {
                    board[z][x][y] = 0;
                }
            }
            get_combo++;
        }
    }

    boardfall(board);
    return make_pair(board, get_combo);
}

int dfs(const Board board, const vector<Board> &blocks, int idx=0, int combo=0) {
    // printf("step: %d\n", idx+1);
    // print_board(board);

    if(idx == N) return combo;
    int ret = 0;

    // ブロックの水平移動
    for(int k=0; k<9; k++) {
        bool ok = true;
        Board block = blocks[idx];
        Board n_block = Board(2, vector< vector<int> >(2, vector<int>(2)));
        for(int z=0; z<2; z++) {
            for(int x=0; x<2; x++) {
                for(int y=0; y<2; y++) {
                    int nx = x + dx[k], ny = y + dy[k];
                    if((nx < 0 || nx >= 2 || ny < 0 || ny >= 2) && block[z][x][y]) {
                        ok = false;
                        continue;
                    }
                    else {
                        if(nx < 0 || nx >= 2 || ny < 0 || ny >= 2) continue;
                        n_block[z][nx][ny] = block[z][x][y];
                    }
                }
            }
        }

        if(ok) {
            Board n_board;
            int get_combo;
            tie(n_board, get_combo) = modify_board(board, n_block);
            ret = max(ret, dfs(n_board, blocks, idx+1, combo+get_combo));
        }
    }
    return ret;
}

int main() {
    while(cin >> H >> N, H || N) {
        Board board(30, vector< vector<int> >(2, vector<int>(2)));
        for(int i=0; i<H; i++) {
            for(int x=0; x<2; x++) {
                for(int y=0; y<2; y++) {
                    char c; cin >> c;
                    board[i][x][y] = (c == '#');
                }
            }
        }

        vector<Board> blocks(N, Board(2, vector< vector<int> >(2, vector<int>(2))));
        for(int i=0; i<N; i++) {
            for(int z=0; z<2; z++) {
                for(int x=0; x<2; x++) {
                    for(int y=0; y<2; y++) {
                        char c; cin >> c;
                        blocks[i][z][x][y] = (c == '#');
                    }
                }
            }
        }

        int ans = dfs(board, blocks, 0);
        cout << ans << endl;
    }
    return 0;
}


Measured memory_bytes: 3212