#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <cstring>
#include <cctype>
#include <complex>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <functional>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
using namespace std;
const int dx[]={1,0,-1,0,1,-1,-1,1};
const int dy[]={0,1,0,-1,1,1,-1,-1};
const int INF = 1<<30;
const int EPS = 1e-8;
#define PB push_back
#define fi first
#define se second
#define ll long long
#define reps(i,j,k) for(int i = (j); i < (k); i++)
#define rep(i,j) reps(i,0,j)
#define MOD 1000000007
typedef pair<int,int> Pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int > Pii;
int panel[32];
int tech[32];
int memo[1<<16][32];
int n,c;
int bitCount(int a,int b){
	int cnt = 0;
	rep(i,16){
		if(a>>i & 1 && b>>i & 1){
			cnt++;
		}
	}
	return cnt;
}
int search(int bit,int dep){
	if(dep == n){
		return 0;
	}
	if(memo[bit][dep] != -1){
		return memo[bit][dep];
	}
	int ans = 0;
	rep(i,c){
		ans = max(ans,bitCount(bit,tech[i])+search(bit&~tech[i]|panel[dep+1],dep+1));
	}
	return memo[bit][dep] = ans;
}
int main(){
	while(scanf("%d%d",&n,&c),(n|c)){
		memset(panel,0,sizeof(panel));
		memset(tech,0,sizeof(tech));
		memset(memo,-1,sizeof(memo));
		rep(i,n){
			rep(j,16){
				int tmp;
				scanf("%d",&tmp);
				if(tmp){
					panel[i] += 1<<j;
				}
			}
		}
		rep(i,c){
			rep(j,16){
				int tmp;
				scanf("%d",&tmp);
				if(tmp)tech[i] += 1<<j;
			}
		}
		printf("%d\n",search(panel[0],0));
	}
	return 0;
}