#include <bits/stdc++.h>
using namespace std;
template <class T>
bool ckmin(T& a, const T& b) {
  return b < a ? a = b, 1 : 0;
}
template <class T>
bool ckmax(T& a, const T& b) {
  return a < b ? a = b, 1 : 0;
}
const int MAX_N = 100010;
const int MAX_P = 17;
int n, p;
int arr[MAX_N];
bool canAdj[MAX_P][MAX_P];
bool vis[1 << MAX_P][MAX_P][MAX_P];
bool isGood[1 << MAX_P];
int freq[MAX_P];
int ans;
string second;
void cancel(int msk, int a, int b) {
  if (vis[msk][a][b]) return;
  vis[msk][a][b] = 1;
  isGood[msk] = 0;
  for (int i = 0; i < p; i++)
    if (msk & (1 << i)) {
      if (i == a || i == b) continue;
      cancel(msk ^ (1 << i), a, b);
    }
}
bool vis2[1 << MAX_P];
void dfs(int msk) {
  if (vis2[msk]) return;
  vis2[msk] = 1;
  int tot = 0;
  for (int i = 0; i < p; i++)
    if (msk & (1 << i)) {
      tot += freq[i];
    }
  ckmin(ans, tot);
  for (int i = 0; i < p; i++)
    if (msk & (1 << i)) {
      if (isGood[msk ^ (1 << i)]) dfs(msk ^ (1 << i));
    }
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> p;
  ans = n;
  cin >> second;
  for (int i = 0; i < n; i++) arr[i] = second[i] - 'a';
  for (int i = 0; i < n; i++) freq[arr[i]]++;
  for (int i = 0; i < p; i++)
    for (int j = 0; j < p; j++) cin >> canAdj[i][j];
  for (int i = 0; i < 1 << p; i++) isGood[i] = 1;
  for (int i = 0; i < p; i++)
    for (int j = 0; j < p; j++)
      if (!canAdj[i][j]) {
        int lasti = -1;
        bool flag = 0;
        for (int idx = 0; idx < n; idx++) {
          if (arr[idx] == j) {
            if (flag) {
              flag = 0;
              int full = (1 << p) - 1;
              int msk = full;
              for (int idx2 = lasti + 1; idx2 <= idx - 1; idx2++) {
                msk &= full ^ (1 << arr[idx2]);
              }
              cancel(msk, i, j);
            }
          }
          if (arr[idx] == i) {
            lasti = idx;
            flag = 1;
          }
        }
      }
  dfs((1 << p) - 1);
  return cout << ans << '\n', 0;
  ;
}
