Problem: Yuta is addicted to the popular game "Beat Panel" at a nearby arcade. The game consists of a total of 16 panel-type buttons, 4x4, arranged in a grid as shown.

<image>


As shown in the figure, the buttons are arranged in the order of button 1, button 2,…, button 16 from the upper left to the lower right. In the game, you will hear a beat sound at regular intervals and a final sound at the end. Multiple buttons light up at the same time as the beat sounds. In some cases, even one does not shine. The player can press multiple buttons at the same time using the fingers of both hands from immediately after the beat sound to the next sound. It is also possible not to press anything. The game ends as soon as the end sound is heard.

Yuta has mastered c ways of pressing, and each time a beat sounds, he decides one of those pressing methods and presses the button. If the buttons you press are lit, those buttons will be lit and the number of buttons that have disappeared will be added to the player's score. Also, once a button is lit, the light will not go out until the button is pressed.

A program that outputs the maximum score that Yuta can obtain by inputting how to illuminate the button when the beat sound is played n times and how to press the button in c ways that Yuta has learned. Please create.



input

The input consists of multiple datasets. The end of the input is indicated by two lines of zeros. Each dataset is given in the following format.


n c
a1,1 a1,2 ... a1,16
a2,1 a2,2 ... a2,16
...
an, 1 an, 2 ... an, 16
b1,1 b1,2 ... b1,16
b2,1 b2,2 ... b2,16
...
bc,1 bc,2 ... bc,16


The first line consists of two integers separated by one space. n (1 ≤ n ≤ 30) indicates the number of beat sounds, and c (1 ≤ c ≤ 30) indicates the number of button presses that you have learned. The following n + c lines give how to illuminate the button and how to press the button. The input item in the line is separated by one blank. ak and i indicate how the button i shines when the kth beat sound is heard, and bj and i indicate whether the button i is pressed by pressing the jth button in the middle of c. As for the values ​​of ak and i, 0 means "does not shine" and 1 means "shines". For the values ​​of bj and i, 0 means "do not press" and 1 means "press".

The number of datasets does not exceed 20.

output

For each data set, the maximum score is output on one line.

Example

Input

2 2
0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1
1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0
0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1
1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0
2 2
0 0 1 0 1 1 1 1 0 0 1 0 0 0 1 0
0 1 0 1 0 1 1 1 0 1 0 1 0 0 0 0
0 0 1 0 1 0 0 0 0 0 1 0 0 0 1 0
0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0
5 3
0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0
1 0 0 1 0 1 1 0 0 1 1 0 1 0 0 1
0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0
0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0
0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0
1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0
0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1
0 0


Output

8
7
16

Solution (in CPP):

Solution:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <cfloat>
#include <ctime>
#include <cassert>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <numeric>
#include <list>
#include <iomanip>
#include <fstream>
#include <bitset>
   
using namespace std;
   
 
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define foreach(it, c) for (__typeof__((c).begin()) it=(c).begin(); it != (c).end(); ++it)
#define rforeach(it, c) for (__typeof__((c).rbegin()) it=(c).rbegin(); it != (c).rend(); ++it)
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define CL(arr, val) memset(arr, val, sizeof(arr))
#define COPY(dest, src) memcpy(dest, src, sizeof(dest))
#define ten(n) ((long long)(1e##n))
#define bin(n) (1LL << (n))
#define erep(i, n) for (int i = 0; i <= (int)(n); ++i)
#define revrep(i, n) for (int i = (n); i >= 0; --i)
#define pb push_back

template <class T> void chmax(T& a, const T& b) { a = max(a, b); }
template <class T> void chmin(T& a, const T& b) { a = min(a, b); }

template <class T> T round_up(T a, T b) { return (a + b - 1) / b; }

template <class T> void uniq(vector<T>& c) { sort(c.begin(), c.end()); c.erase(unique(c.begin(), c.end()), c.end()); }
 
template <class T> string to_s(const T& a) { ostringstream os; os << a; return os.str(); }
template <class T> T to_T(const string& s) { istringstream is(s); T res; is >> res; return res; }
  
template <class T, class U> ostream& operator<<(ostream& os, pair<T, U>& p) { os << "( " << p.first << ", " << p.second << " )"; return os; }
  
template <class T> void print(T a, int n, const string& deli = " ", int br = 1) { for (int i = 0; i < n; ++i) { cout << a[i]; if (i + 1 != n) cout << deli; } while (br--) cout << endl; }
template <class T> void print(const T& c, const string& deli = " ", int br = 1) { foreach (it, c) { cout << *it; if (++it != c.end()) cout << deli;--it; } while (br--) cout << endl; }
template <class T> void print2d(T a, int w, int h, int width = -1, int br = 1) { for (int i = 0; i < h; ++i) { for (int j = 0; j < w; ++j) {    if (width != -1) cout.width(width); cout << a[i][j] << ' '; } cout << endl; } while (br--) cout << endl; }
   
template <class T> void input(T& a, int n) { for (int i = 0; i < n; ++i) cin >> a[i]; }
template <class T> void input(T* a, int n) { for (int i = 0; i < n; ++i) cin >> a[i]; }

void fix_pre(int n) { cout.setf(ios::fixed, ios::floatfield); cout.precision(10); }
void fast_io() { cin.tie(0); ios::sync_with_stdio(false); }
#define trace(x) (cout << #x << ": " << (x) << endl)
 
bool in_rect(int x, int y, int w, int h) { return 0 <= x && x < w && 0 <= y && y < h; }
 

typedef long long ll;
typedef pair<int, int> pint;
 
// y(v): v>^<  y(^): ^>v<
const int dx[] = { 0, 1, 0, -1 };
const int dy[] = { 1, 0, -1, 0 };

const double PI = acos(-1.0);

#define F first
#define S second



vector<int> inp(int n)
{
    vector<int> res(n);
    rep(i, n)
    {
        int a[16];
        input(a, 16);
        rep(j, 16)
            res[i] |= a[j] * bin(j);
    }
    return res;
}
int main()
{
    int n, c;
    while (cin >> n >> c, n)
    {
        vector<int> a = inp(n);
        vector<int> b = inp(c);

        const int inf = ten(6);
        static int dp[33][1 << 16];
        static int score[33][1 << 16];
        rep(i, c) rep(s, bin(16))
            score[i][s] = __builtin_popcount(b[i] & s);

        erep(i, n) rep(s, bin(16))
            dp[i][s] = -inf;
        dp[0][0] = 0;
        rep(i, n) rep(s, bin(16))
        {
            if (dp[i][s] >= 0)
            {
                int f = s | a[i];
                rep(j, c)
                    chmax(dp[i + 1][f & ~b[j]], dp[i][s] + score[j][f]);
            }
        }

        cout << *max_element(dp[n], dp[n] + bin(16)) << endl;
    }
}