// Original C++ solution (slower):
#include <stdio.h>

#include <cmath>

#include <algorithm>

#include <stack>

#include <queue>

#include <vector>



using namespace std;



int**dp;



void func(int N,int C){

	int beat[N][16],push[C][16];



	int maximum = 0;



	for(int i = 0; i < N; i++){

		for(int k = 0; k < 16; k++)scanf("%d",&beat[i][k]);

	}



	for(int i = 0; i < C; i++){

		for(int k = 0; k < 16; k++)scanf("%d",&push[i][k]);

	}



	int tmp,S,code;



	int work[C][16];



	S = 1;

	code = 0;

	for(int i = 0; i < 16; i++){

		code += S*beat[0][i];

		S *= 2;

	}

	dp[1][code] = 0;





	for(int k = 0; k < C; k++){

		tmp = 0;

		for(int p = 0; p < 16; p++){

			work[k][p] = beat[0][p];

			if(work[k][p] == 1){

				if(push[k][p] == 1){

					work[k][p] = 0;

					tmp++;

				}

			}

		}



		S = 1;

		code = 0;

		for(int i = 0; i < 16; i++){

			code += S*work[k][i];

			S *= 2;

		}

		dp[1][code] = max(dp[1][code],tmp);

		maximum = max(maximum,dp[1][code]);

	}



	for(int i = 1; i < N; i++){

		for(int state = 0; state < 65536; state++){

			if(dp[i][state] != -1){



				S = 1;

				code = 0;

				for(int loop = 0; loop < 16; loop++){

					if(state & (1 << loop)){

						code += S;

					}else{

						code += S*beat[i][loop];

					}

					S *= 2;

				}

				dp[i+1][code] = dp[i][state];



				for(int k = 0; k < C; k++){

					tmp = 0;

					for(int p = 0; p < 16; p++){

						if(state & (1 << p)){

							if(push[k][p] == 1){

								work[k][p] = 0;

								tmp++;

							}else{

								work[k][p] = 1;

							}



						}else{

							work[k][p] = beat[i][p];

							if(work[k][p] == 1){

								if(push[k][p] == 1){

									work[k][p] = 0;

									tmp++;

								}

							}

						}

					}



					S = 1;

					code = 0;

					for(int a = 0; a < 16; a++){

						code += S*work[k][a];

						S *= 2;

					}

					dp[i+1][code] = max(dp[i+1][code],tmp+dp[i][state]);

				}

			}

		}

	}



	for(int i = 0; i < 65536; i++)maximum = max(maximum,dp[N][i]);



	printf("%d\n",maximum);

}



int main(){



	int N,C;

	dp = new int*[31];

	for(int i = 0; i < 31; i++){

		dp[i] = new int[65536];

	}



	while(true){

		scanf("%d %d",&N,&C);

		if(N == 0 && C == 0)break;



		for(int i = 0; i <= N; i++){

			for(int k = 0; k < 65536; k++)dp[i][k] = -1;

		}



		func(N,C);

	}



    return 0;

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

typedef long long int ll;

typedef unsigned long long int ull;

#define BIG_NUM 2000000000

#define MOD 1000000007

#define EPS 0.000000001

using namespace std;





#define NUM 30

#define SIZE 16



int N,C;

int POW[17];

int shine_table[NUM][SIZE],push_table[NUM][SIZE];

int shine_value[NUM+1],push_value[NUM];

int dp[2][65536];



void func(){



	int sum;



	for(int i = 0; i < N; i++){



		sum = 0;

		for(int k = 0; k < SIZE; k++){

			scanf("%d",&shine_table[i][k]);



			sum += shine_table[i][k]*POW[k];

		}

		shine_value[i] = sum;

	}



	shine_value[N] = POW[SIZE]-1;



	for(int i = 0; i < C; i++){



		sum = 0;

		for(int k = 0; k < SIZE; k++){

			scanf("%d",&push_table[i][k]);



			sum += push_table[i][k]*POW[k];

		}

		push_value[i] = sum;

	}



	int CURRENT = 0,NEXT = 1;



	for(int state = 0; state < POW[SIZE]; state++){

		dp[CURRENT][state] = -1;

		dp[NEXT][state] = -1;

	}



	dp[CURRENT][shine_value[0]] = 0;

	int rest,next_state,add;



	for(int i = 0; i < N; i++){



		for(int state = 0; state < POW[SIZE]; state++){

			if(dp[CURRENT][state] == -1)continue;



			next_state = state|shine_value[i+1];

			dp[NEXT][next_state] = max(dp[NEXT][next_state],dp[CURRENT][state]);



			for(int k = 0; k < C; k++){



				add = 0;

				rest = 0;



				for(int loop = 0; loop < SIZE; loop++){



					if((state & (1 << loop))){

						if(push_table[k][loop] == 1){

							add++;

						}else{

							rest += POW[loop];

						}

					}

				}



				next_state = rest|shine_value[i+1];



				dp[NEXT][next_state] = max(dp[NEXT][next_state],dp[CURRENT][state]+add);

			}

		}



		for(int state = 0; state < POW[16]; state++){

			dp[CURRENT][state] = -1;

		}



		swap(CURRENT,NEXT);

	}



	int ans = 0;

	for(int state = 0; state < POW[SIZE]; state++)ans = max(ans,dp[CURRENT][state]);



	printf("%d\n",ans);

}



int main(){



	for(int i = 0; i < 17; i++)POW[i] = pow(2,i);



	while(true){

		scanf("%d %d",&N,&C);

		if(N == 0 && C == 0)break;



		func();

	}



	return 0;

}




// Fastest known solution for this problem: