#include <bits/stdc++.h>
using namespace std;
int pre[100005][20];
int suf[100005][20];
int cnt[20];
int ok[1 << 17][17][17];
int grid[20][20];
int dp[1 << 17];
int OK(int first, int a, int b, int p) {
  if (ok[first][a][b] != -1) return ok[first][a][b];
  ok[first][a][b] = 1;
  for (int i = 0; i < p; i++) {
    if (i != a && i != b && (first & (1 << i)) == 0) {
      if (!OK(first ^ (1 << i), a, b, p)) {
        ok[first][a][b] = 0;
        return ok[first][a][b];
      }
    }
  }
  return ok[first][a][b];
}
int DP(int first, int p) {
  if (dp[first] != -1) return dp[first];
  dp[first] = 0;
  for (int i = 0; i < p; i++) {
    for (int j = 0; j < p; j++) {
      if ((first & (1 << i)) && (first & (1 << j)) && !OK(first, i, j, p)) {
        dp[first] = 0;
        return dp[first];
      }
    }
  }
  for (int i = 0; i < p; i++) {
    if ((first & (1 << i)) == 0) {
      if (DP(first ^ (1 << i), p)) {
        dp[first] = 1;
        return dp[first];
      }
    }
  }
  return dp[first];
}
int main() {
  int n, p;
  scanf("%d %d", &n, &p);
  char c[100005];
  scanf("%s", c + 1);
  for (int i = 1; c[i] != 0; i++) cnt[c[i] - 'a']++;
  memset(pre, -1, sizeof(pre));
  for (int i = 1; c[i] != 0; i++) {
    for (int j = 0; j < p; j++) pre[i][j] = pre[i - 1][j];
    pre[i][c[i] - 'a'] = i;
  }
  memset(suf, -1, sizeof(suf));
  for (int i = strlen(c + 1); i >= 1; i--) {
    for (int j = 0; j < p; j++) suf[i][j] = suf[i + 1][j];
    suf[i][c[i] - 'a'] = i;
  }
  for (int i = 0; i < p; i++) {
    for (int j = 0; j < p; j++) scanf("%d", &grid[i][j]);
  }
  memset(ok, -1, sizeof(ok));
  for (int i = 1; i <= n; i++) {
    vector<pair<int, int> > prefix, suffix;
    for (int j = 0; j < p; j++) {
      if (pre[i][j] != -1) prefix.push_back(make_pair((pre[i][j]), (j)));
      if (suf[i][j] != -1) suffix.push_back(make_pair((-suf[i][j]), (j)));
    }
    sort(prefix.begin(), prefix.end());
    reverse(prefix.begin(), prefix.end());
    sort(suffix.begin(), suffix.end());
    reverse(suffix.begin(), suffix.end());
    int first = (1 << p) - 1;
    first -= (1 << (c[i] - 'a'));
    for (int j = 1; j < prefix.size(); j++) {
      int temp = first;
      for (int k = 1; k < suffix.size(); k++) {
        if (!grid[prefix[j].second][suffix[k].second] &&
            (temp & (1 << suffix[k].second))) {
          ok[temp][prefix[j].second][suffix[k].second] = 0;
          ok[temp][suffix[k].second][prefix[j].second] = 0;
        }
        if (temp & (1 << suffix[k].second)) temp ^= (1 << suffix[k].second);
      }
      first -= (1 << prefix[j].second);
    }
  }
  memset(dp, -1, sizeof(dp));
  dp[(1 << p) - 1] = 1;
  int ans = n;
  for (int i = 0; i < (1 << p); i++) {
    if (DP(i, p)) {
      int tot = 0;
      for (int j = 0; j < p; j++) {
        if (i & (1 << j)) {
          tot += cnt[j];
        }
      }
      ans = min(ans, tot);
    }
  }
  printf("%d\n", ans);
}
