#include <bits/stdc++.h>
using namespace std;
int n, k, v[17][17];
string s;
int dp[17][100001];
int nxt[17][100001];
bool bad[17][1 << 17];
bool reallyBad[1 << 17];
int Log[1 << 17];
bool DP[1 << 17];
int get(int l, int r) {
  if (l > r) return 0;
  int lg = Log[r - l + 1];
  return dp[lg][l] | dp[lg][r - (1 << lg) + 1];
}
int main() {
  for (int i = 2; i < (1 << 17); ++i) Log[i] = Log[i >> 1] + 1;
  cin >> n >> k;
  cin >> s;
  for (int i = 0; i < k; ++i)
    for (int j = 0; j < k; ++j) cin >> v[i][j];
  int f[26] = {};
  for (int i = 0; i < s.size(); ++i) ++f[s[i] - 'a'];
  memset(nxt, -1, sizeof(nxt));
  for (int i = n - 1; i >= 0; --i) {
    for (int j = 0; j < k; ++j) nxt[j][i] = nxt[j][i + 1];
    nxt[s[i] - 'a'][i] = i;
    dp[0][i] = 1 << (s[i] - 'a');
  }
  for (int k = 1; k < 17; ++k)
    for (int i = 0; i + (1 << k) <= n; ++i)
      dp[k][i] = dp[k - 1][i] | dp[k - 1][i + (1 << (k - 1))];
  for (int i = 0; i < n; ++i) {
    int x = s[i] - 'a';
    for (int y = 0; y < k; ++y)
      if (!v[x][y]) {
        int l = i + 1;
        int r = nxt[y][i + 1] - 1;
        int ret = get(l, r);
        bad[x][ret] = true;
      }
  }
  for (int x = 0; x < k; ++x) {
    bool *cur = bad[x];
    cur[0] = false;
    for (int i = 0; i < k; ++i)
      for (int mask = 0; mask < (1 << k); ++mask)
        if (mask & (1 << i)) cur[mask] = cur[mask] | cur[mask ^ (1 << i)];
    for (int mask = 0; mask < (1 << k); ++mask)
      if (cur[mask] && !((mask >> x) & 1)) reallyBad[mask] = true;
  }
  DP[0] = true;
  int res = n;
  for (int mask = 1; mask < (1 << k); ++mask) {
    DP[mask] = false;
    if (!reallyBad[mask])
      for (int i = 0; i < k; ++i)
        if (((mask >> i) & 1) && DP[mask ^ (1 << i)]) {
          DP[mask] = true;
          break;
        }
    if (DP[mask]) {
      int cur = 0;
      for (int i = 0; i < k; ++i)
        if ((mask >> i) & 1) cur += f[i];
      res = min(res, n - cur);
    }
  }
  printf("%d\n", res);
  return 0;
}
