#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
const int MAXN = 100010, MAXM = 200, MAXP = 18;
int n, p;
string s;
int pref[MAXP][MAXN];
bool good[1 << MAXP][MAXP][MAXP], god[1 << MAXP];
bool m[MAXP][MAXP];
vector<int> pos[MAXP];
int get(int p, int l, int r) {
  if (l > r) return 0;
  if (l == 0) return pref[p][r];
  return pref[p][r] - pref[p][l - 1];
}
inline int del(int mask, int pos) {
  if (mask & (1 << pos)) {
    return mask ^ (1 << pos);
  }
  return mask;
}
void rec(int mask, int a, int b, bool f) {
  if (m[a][b]) return;
  if (!good[mask][a][b]) return;
  if (!f) {
    good[mask][a][b] = 0;
    for (int i = 0; i < p; i++) {
      if (i != a && i != b && (mask & (1 << i))) rec(mask ^ (1 << i), a, b, f);
    }
    return;
  }
  int i = 0, j = 0;
  while (i < pos[a].size() && j < pos[b].size()) {
    if (pos[b][j] < pos[a][i]) {
      j++;
      continue;
    }
    if (get(a, pos[a][i] + 1, pos[b][j] - 1) != 0) {
      i++;
      continue;
    }
    if (a == b && i == j) {
      j++;
      continue;
    }
    bool ok = 0;
    int newmask = mask;
    for (int first = 0; first < p; first++) {
      if (first == a || first == b) continue;
      if (get(first, pos[a][i], pos[b][j]) && (mask & (1 << first))) {
        ok = 1;
        newmask = del(newmask, first);
      }
    }
    rec(newmask, a, b, 0);
    if (!ok) {
      good[mask][a][b] = 0;
      f = 0;
      for (int i = 0; i < p; i++) {
        if (i != a && i != b && (mask & (1 << i)))
          rec(mask ^ (1 << i), a, b, f);
      }
      return;
    }
    i++;
  }
}
bool check[1 << MAXP];
void zavodnik() {
  for (int i = (1 << p) - 1; i >= 0; i--) {
    check[i] = 1;
    string ss;
    for (char first : s) {
      if (i & (1 << (first - 'a'))) ss.push_back(first);
    }
    for (int j = 0; j < ((long long)((ss).size())) - 1; j++) {
      if (!m[ss[j] - 'a'][ss[j + 1] - 'a']) check[i] = 0;
    }
  }
}
int dp[1 << MAXP];
int32_t main() {
  ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  cin >> n >> p;
  cin >> s;
  for (int i = 0; i < p; i++)
    for (int j = 0; j < p; j++) cin >> m[i][j];
  pref[s[0] - 'a'][0] = 1;
  pos[s[0] - 'a'].push_back(0);
  for (int i = 1; i < s.size(); i++) {
    for (int j = 0; j < MAXP; j++) pref[j][i] += pref[j][i - 1];
    pref[s[i] - 'a'][i]++;
    pos[s[i] - 'a'].push_back(i);
  }
  for (int i = 0; i < (1 << MAXP); i++)
    for (int j = 0; j < p; j++)
      for (int k = 0; k < p; k++) good[i][j][k] = 1;
  for (int i = 0; i < (1 << MAXP); i++) dp[i] = 2000000000;
  dp[(1 << (p)) - 1] = s.size();
  for (int i = 0; i < p; i++)
    for (int j = 0; j < p; j++) rec((1 << (p)) - 1, i, j, 1);
  for (int i = 0; i < (1 << MAXP); i++) {
    god[i] = 1;
    for (int j = 0; j < p; j++)
      for (int k = 0; k < p; k++)
        if ((i & (1 << j)) && (i & (1 << k))) god[i] &= good[i][j][k];
  }
  int ans = 2000000000;
  for (int i = (1 << (p)) - 1; i >= 0; i--) {
    for (int j = 0; j < p; j++)
      if (i & (1 << j) && god[i ^ (1 << j)]) {
        dp[i ^ (1 << j)] =
            min(dp[i ^ (1 << j)], dp[i] - get(j, 0, s.size() - 1));
      }
    ans = min(ans, dp[i]);
  }
  cout << ans << '\n';
}
