#include <bits/stdc++.h>
using namespace std;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
int dx8[] = {0, 0, 1, 1, 1, -1, -1, -1};
int dy8[] = {1, -1, -1, 0, 1, -1, 0, 1};
int kx8[] = {1, 1, 2, 2, -1, -1, -2, -2};
int ky8[] = {2, -2, 1, -1, 2, -2, 1, -1};
long long bigmod(long long a, long long b, long long c) {
  if (b == 0) return 1 % c;
  long long x = bigmod(a, b / 2, c);
  x = (x * x) % c;
  if (b % 2 == 1) x = (x * a) % c;
  return x;
}
long long poww(long long a, long long b) {
  if (b == 0) return 1;
  long long x = poww(a, b / 2);
  x = x * x;
  if (b % 2 == 1) x = (x * a);
  return x;
}
long long mod_inverse(long long a, long long mod) {
  return bigmod(a, mod - 2, mod);
}
const int M = 100005;
int Fpos[M][18], Bpos[M][18], p[18][18], vis[18][1 << 17], del[18][1 << 17],
    restricted[1 << 17], sz[18];
int n, k;
vector<int> vec[18];
string s;
long long dp[1 << 18];
long long dpcall(int mask) {
  long long &ret = dp[mask];
  if (~ret) return ret;
  ret = 0;
  for (int i = 0; i < k; i++) {
    if ((bool)((1 << i) & mask)) continue;
    if (restricted[mask | (1 << i)]) continue;
    ret = max(ret, sz[i] + dpcall(1 << i | mask));
  }
  return ret;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> k;
  cin >> s;
  s = "#" + s;
  for (int i = 0; i < k; i++) {
    for (int j = 0; j < k; j++) {
      cin >> p[i][j];
    }
  }
  for (int i = 1; i <= n; i++) {
    int x = s[i] - 'a';
    vec[x].push_back(i);
    sz[x]++;
  }
  for (int i = n; i >= 1; i--) {
    int x = s[i] - 'a';
    for (int j = 0; j < k; j++) {
      Fpos[i][j] = Fpos[i + 1][j];
    }
    Fpos[i][x] = i;
  }
  for (int i = 0; i < k; i++) {
    memset((vis), 0, sizeof(vis));
    memset((del), 0, sizeof(del));
    for (auto x : vec[i]) {
      for (int j = 0; j < k; j++) {
        if (p[i][j]) continue;
        if (Fpos[x + 1][j]) {
          int mask = 0;
          for (int l = 0; l < k; l++) {
            if (Fpos[x + 1][l] > x && Fpos[x + 1][l] < Fpos[x + 1][j]) {
              mask |= 1 << l;
              if (l == i) {
                mask = 0;
                break;
              }
            }
          }
          if (mask) vis[j][mask] = 1;
        }
      }
    }
    for (int j = 0; j < k; j++) {
      int rmask = (1 << i) | (1 << j);
      rmask = ((1 << k) - 1) ^ rmask;
      for (int mask = 0; mask < (1 << k); mask++) {
        if (!vis[j][mask] || del[j][mask]) continue;
        for (int nmask = mask; nmask < (1 << k); nmask = (nmask + 1) | mask) {
          del[j][nmask] = 1;
          restricted[nmask & rmask] = 1;
        }
      }
    }
  }
  memset((dp), -1, sizeof(dp));
  cout << n - dpcall(0) << endl;
  return 0;
}
