#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <utility>
#include <cstdlib>
#include <memory>
#include <queue>
#include <cassert>
#include <cmath>
#include <ctime>
#include <complex>
#include <bitset>

using namespace std;

#define pb push_back
#define fst first
#define snd second
#define mp make_pair 
#define sz(C) ((int) (C).size())
#define forn(i, n) for (int i = 0; i < (int) n; ++i)
#define ford(i, n) for (int i = ((int) n) - 1; i >= 0; --i)
#define y1 gftxdtrtfhyjfctrxujkvbhyjice
#define y0 ehfoiuvhefroerferjhfjkehfjke
#define left sdhfsjkshdjkfsdfgkqqweqweh
#define right yytrwtretywretwreytwreytwr
#define next jskdfksdhfjkdsjksdjkgf
#define prev koeuigrihjdkjdfj
#define hash kjfdkljkdhgjdkfhgurehg
#define all(C) begin(C), end(C)

typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair <int,int> pii;
typedef pair <ll, ll> pll;
typedef vector <ll> vll;
typedef vector <int> vi;
typedef vector <vector <int> > vvi;
typedef vector <pii> vii;
typedef long double ld;
typedef complex<double> cd;
typedef vector<cd> vcd;

#define FILE_NAME ""

const ld EPS = 1e-9;
const int MAXN = 50 + 5;
const int MAXM = 1000 + 5;

char g[MAXN][MAXM];
string name[MAXN];
int n, m;
int p[MAXN];

void read() {
  scanf("%d%d", &n, &m);
  forn(i, n) {
    scanf("%d", &p[i]);
  } 
  scanf("\n");
  forn(i, n) {
    getline(cin, name[i]);
  }
  scanf("\n");
  forn(i, n) {
    scanf("%s", g[i]);
  }
}

string name1, name2, name3;
int ans;


int main() {
#ifdef LOCAL
  freopen(FILE_NAME ".in", "r", stdin);
//  freopen(FILE_NAME ".out", "w", stdout);
#endif

  read();

  ans = -1;
  forn(i, n) for (int j = i + 1; j < n; ++j) for (int k = j + 1; k < n; ++k) {
    vvi cnt(3, vi(3, 0));
    int cnt_all = 0;
    vi cnt_one(3, 0);
    forn(z, m) {
      int mask = 0;
      if  (g[i][z] == '1') mask |= 1 << 0;
      if  (g[j][z] == '1') mask |= 1 << 1;
      if  (g[k][z] == '1') mask |= 1 << 2;
      if  (!mask) {
        continue;
      }
      int pop = __builtin_popcount(mask);
      if  (pop == 1) {
        forn(w, 3) {
          if  (mask & (1 << w)) {
            ++cnt_one[w];
            break;
          }
        }
      }
      if  (pop == 3) {
        ++cnt_all;
      }
      if  (pop == 2) {
        int w1 = 0;
        forn(w, 3) {
          if  (mask & (1 << w)) {
            w1 = w;
            break;
          }
        }
        int w2 = 0;
        ford(w, 3) {
          if  (mask & (1 << w)) {
            w2 = w;
            break;
          }
        }
        assert(w1 < w2);
        ++cnt[w1][w2];
      }
    }

    int cur = 0;
    vi can(3, 0);
    can[0] = p[i];
    can[1] = p[j];
    can[2] = p[k];
    forn(w1, 3) forn(w2, 3) printf("cnt[%d][%d] = %d\n", w1, w2, cnt[w1][w2]);
    forn(w, 3) {
      while (cnt_one[w] > 0 && can[w] > 0) {
        ++cur;
        --cnt_one[w];
        --can[w];
      } 
    }

    forn(w, 3) {
      forn(w2, 3) {
        if  (w == w2) {
          continue;
        }
        while  (cnt[min(w, w2)][max(w, w2)] > can[w2] && can[w] > 0) {
          --cnt[min(w, w2)][max(w, w2)];
          --can[w];
          ++cur;
//          printf("w = %d\n", w);
        }
      }
    }

    forn(w, 3) forn(w2, 3) {
      if  (w != w2) {
        while (cnt[min(w, w2)][max(w, w2)] > 0 && can[w] > 0) {
          --can[w];
          --cnt[min(w, w2)][max(w, w2)];
          ++cur;
//          printf("w = %d\n", w);
        }
      }
    }

    forn(w, 3) {
      while (cnt_all > 0 && can[w] > 0) {
        --cnt_all;
        --can[w];
        ++cur;
      }
    }

    if  (cur > ans) {
      ans = cur;
      name1 = name[i];
      name2 = name[j];
      name3 = name[k];
    }
  }

  cout << ans << endl << name1 << " " << name2 << " " << name3 << endl;
  return 0;
}
