#include <iostream>
#include <cstring>
using namespace std;


int N, C, A[32], B[32];
int memo[1 << 16][32];


int rec(int panel, int now)
{
	if(now == N) return 0;
	if(memo[panel][now] != -1) return memo[panel][now];

	int next = panel | A[now];

	int best = 0;
	
	for(int i = 0; i < C; i++) {
		best = max(best, rec(next & ~B[i], now+1) + __builtin_popcount(next & B[i]));
	}

	return memo[panel][now] = best;
}


int main()
{
	for(; cin >> N >> C && (N || C); ) {
		memset(A, 0, sizeof A);
		memset(B, 0, sizeof B);
		memset(memo, -1, sizeof memo);

		for(int i = 0; i < N; i++) {
			for(int j = 0; j < 16; j++) {
				int b;
				cin >> b;

				A[i] |= (b << j);
			}
		}
		
		for(int i = 0; i < C; i++) {
			for(int j = 0; j < 16; j++) {
				int b;
				cin >> b;

				B[i] |= (b << j);
			}
		}

		cout << rec(0, 0) << endl;
	}
}