#include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class T>
using Table = vector<vector<T>>;
const ld eps=1e-9;

//// < "D:\D_Download\Visual Studio 2015\Projects\programing_contest_c++\Debug\a.txt" > "D:\D_Download\Visual Studio 2015\Projects\programing_contest_c++\Debug\b.answer"
int dx[] = { 0,0,0,1,1,1,-1,-1,-1 };
int dy[] = { -1,0,1,-1,0,1,-1,0,1 };
//50~
int main() {
	while (1) {
		int H, N; cin >> H >> N;
		if (!H)break;
		vector<vector<vector<int>>>field(30, vector<vector<int>>(2, vector<int>(2)));
		vector<vector<vector<vector<int>>>>blocks(N, vector<vector<vector<int>>>(2, vector<vector<int>>(2, vector<int>(2))));
		map<char, int>mp;
		mp['#'] = 1;
		mp['.'] = 0;
		for (int z = 0; z< H; ++z) {
			for (int y = 0; y < 2; ++y) {
				string st; cin >> st;
				for (int x = 0; x < 2; ++x) {
					field[z][y][x] = mp[st[x]];
				}
			}
		}
		for (int i = 0; i < N; ++i) {
			for (int z = 0; z < 2; ++z) {
				for (int y = 0; y < 2; ++y) {
					string st; cin >> st;
					for (int x = 0; x < 2; ++x) {
						blocks[i][z][y][x] = mp[st[x]];
					}
				}
			}
			bool flag = true;
			for (int y = 0; y < 2; ++y) {
				for (int x = 0; x < 2; ++x) {
					if (blocks[i][0][y][x])flag = false;
				}
			}
			if (flag) {
				for (int y = 0; y < 2; ++y) {
					for (int x = 0; x < 2; ++x) {
						blocks[i][0][y][x] = blocks[i][1][y][x];
						blocks[i][1][y][x] = 0;
					}
				}
			}
		}
		int amax = 1;
		for (int l = 0; l < N; ++l)amax *= 9;
		int ans = 0;
		for (int i = 0; i < amax; ++i) {
			bool ok = true;
			vector<vector<vector<int>>>nfield(field);
			int num(i);
			vector<int>a(3);
			int erase_num = 0;
			for (int j = 0; j < N; ++j) {
				const int way = num % 9;
				num /= 9;
				vector<vector<vector<int>>>nblock(2, vector<vector<int>>(2, vector<int>(2)));
				for (int z = 0; z < 2; ++z) {
					for (int y = 0; y < 2; ++y) {
						for (int x = 0; x < 2; ++x) {
							if (blocks[j][z][y][x]) {
								const int nz(z);
								const int ny(y + dy[way]);
								const int nx(x + dx[way]);
								if (ny < 0 || ny >= 2 || nx < 0 || nx >= 2) {
									ok = false;
									break;
								}
								nblock[nz][ny][nx] = true;
							}
						}
					}
				}
				if (!ok)break;
				int fallh = 0;
				for (int h = 20; h > 0; h--) {
					for (int z = 0; z < 2; ++z) {
						for (int y = 0; y < 2; ++y) {
							for (int x = 0; x < 2; ++x) {
								if (nblock[z][y][x]) {
									if (nfield[z + h - 1][y][x]) {
										fallh = h;
										break;
									}
								}
							}
						}
					}
					if (fallh)break;
				}
				for (int z = 0; z < 2; ++z) {
					for (int y = 0; y < 2; ++y) {
						for (int x = 0; x < 2; ++x) {
							if (nblock[z][y][x]&&nfield[z + fallh][y][x])assert(false);
							nfield[z + fallh][y][x] ^= nblock[z][y][x];
						}
					}
				}
				//?¶????
				{
					for (int z = 0; z < 30; ++z) {
						bool flag = true;
						for (int x = 0; x < 2; ++x) {
							for (int y = 0; y < 2; ++y) {
								if (!nfield[z][y][x]) {
									flag = false;
								}
							}
						}
						if (flag) {
							erase_num++;
							for (int x = 0; x < 2; ++x) {
								for (int y = 0; y < 2; ++y) {
									nfield[z][y][x] = 0;
								}
							}
						}
					}
				}

				for (int k = 0; k < 30; ++k) {
					for (int z = 0; z < 29; ++z) {
						bool flag = true;
						for (int x = 0; x < 2; ++x) {
							for (int y = 0; y < 2; ++y) {
								if (nfield[z][y][x]) {
									flag = false;
								}
							}
						}
						if (flag) {
							for (int x = 0; x < 2; ++x) {
								for (int y = 0; y < 2; ++y) {
									nfield[z][y][x] = nfield[z + 1][y][x];
								}
							}
						}
					}
				}

			}
			
			if (ok) {
				ans = max(ans, erase_num);
			}
		}
		cout << ans << endl;
	}
	return 0;
}