#include <bits/stdc++.h>
using namespace std;
template <typename T, typename U>
inline void smin(T &a, const U &b) {
  if (a > b) a = b;
}
template <typename T, typename U>
inline void smax(T &a, const U &b) {
  if (a < b) a = b;
}
char s[100010];
int dp[17][17][(1 << 17)];
int ans[(1 << 17)];
vector<int> vec[17][17];
int nxt[100010][17];
int A[17][17];
int id[17];
int cnt[100010];
int PRE;
int arr[17];
int comp(int u, int v) { return nxt[PRE][u] < nxt[PRE][v]; }
int main() {
  int n, p;
  scanf("%d %d", &n, &p);
  scanf("%s", s);
  for (int i = 0; i < n; i++) cnt[s[i] - 'a']++;
  for (int i = 0; i < p; i++) {
    for (int j = 0; j < p; j++) {
      scanf("%d", &A[i][j]);
    }
  }
  for (int j = 0; j < p; j++) nxt[n - 1][j] = n;
  for (int i = n - 2; i >= 0; i--) {
    for (int j = 0; j < p; j++) nxt[i][j] = nxt[i + 1][j];
    nxt[i][s[i + 1] - 'a'] = i + 1;
  }
  for (int i = 0; i < n; i++) {
    PRE = i;
    for (int j = 0; j < p; j++) id[j] = j;
    sort(id, id + p, comp);
    int ST = 0;
    for (int j = 0; j < p; j++) {
      if (nxt[i][id[j]] == n) break;
      vec[s[i] - 'a'][id[j]].push_back(ST);
      ST ^= (1 << id[j]);
      if (id[j] == s[i] - 'a') break;
    }
  }
  for (int i = 0; i < p; i++)
    for (int j = 0; j < p; j++) {
      sort(vec[i][j].begin(), vec[i][j].end());
      vec[i][j].resize(unique(vec[i][j].begin(), vec[i][j].end()) -
                       vec[i][j].begin());
    }
  for (int i = 0; i < p; i++)
    for (int j = 0; j < p; j++) {
      for (int k = 0; k < (1 << p); k++)
        if (!(((k) >> (i)) & 1) and !(((k) >> (j)) & 1)) {
          for (int jj = 0; jj < p; jj++)
            if ((((k) >> (jj)) & 1) and dp[i][j][k ^ (1 << jj)]) {
              dp[i][j][k] = 1;
              break;
            }
          if (dp[i][j][k]) continue;
          int first = lower_bound(vec[i][j].begin(), vec[i][j].end(), k) -
                      vec[i][j].begin();
          if (first != vec[i][j].size() and k == vec[i][j][first]) {
            dp[i][j][k] = 1;
          }
        }
    }
  ans[(1 << p) - 1] = 1;
  for (int i = (1 << p) - 1; i >= 0; i--)
    if (ans[i]) {
      int nn = 0;
      for (int k = 0; k < p; k++)
        if ((((i) >> (k)) & 1)) arr[nn++] = k;
      for (int j = 0; j < nn; j++) {
        int first = ((1 << p) - 1) ^ i ^ (1 << arr[j]);
        int flag = 1;
        for (int ii = 0; ii < nn; ii++)
          for (int jj = 0; jj < nn; jj++)
            if (ii != j and jj != j and !A[arr[ii]][arr[jj]]) {
              if (dp[arr[ii]][arr[jj]][first] || dp[arr[jj]][arr[ii]][first]) {
                flag = 0;
                break;
              }
            }
        ans[i ^ (1 << arr[j])] = flag;
      }
    }
  int ss = n;
  for (int i = 0; i < (1 << p); i++)
    if (ans[i]) {
      int len = 0;
      for (int j = 0; j < p; j++)
        if ((((i) >> (j)) & 1)) len += cnt[j];
      smin(ss, len);
    }
  cout << ss << endl;
}
