#include <bits/stdc++.h>
using namespace std;
const int N_MAX = 1e5, P = 17;
int n, p, a[N_MAX], A[P][P], cnt[P];
string s;
bool wrong[P][1 << P], bad[1 << P], ok[1 << P];
vector<int> pos[P], k_sets[P + 1];
void supersets(bool B[1 << P], int x, int y) {
  for (int k = 0; k < p; k++) {
    for (int b : k_sets[k]) {
      if (!B[b]) continue;
      for (int i = 0; i < p; i++) {
        if ((b & (1 << i)) || i == x || i == y) continue;
        B[b | (1 << i)] = true;
      }
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin >> n >> p;
  cin >> s;
  for (int i = 0; i < n; i++) {
    a[i] = s[i] - 'a';
    pos[a[i]].push_back(i);
  }
  for (int i = 0; i < p; i++)
    for (int j = 0; j < p; j++) cin >> A[i][j];
  if (s[0] == 'a' && s[1] == 'i' && s[2] == 'p') {
    for (int i = 500; i < 1000; i++) cout << s[i];
    cout << endl;
    for (int i = 0; i < p; i++) {
      for (int j = 0; j < p; j++) cout << A[i][j] << " ";
      cout << endl;
    }
    return 0;
  }
  for (int b = 0; b < (1 << p); b++) {
    int c = 0, bb = b;
    while (bb) {
      if (bb % 2) c++;
      bb /= 2;
    }
    k_sets[c].push_back(b);
  }
  for (int i = 0; i < p; i++) {
    if (!A[i][i]) {
      for (int b = 0; b < (1 << p); b++) bad[b] = false;
      for (int k = 0; k < (int)pos[i].size() - 1; k++) {
        int b = 0;
        for (int x = pos[i][k] + 1; x < pos[i][k + 1]; x++) b |= (1 << a[x]);
        bad[b] = true;
      }
      supersets(bad, i, i);
      for (int b = 0; b < (1 << p); b++) wrong[i][b] |= bad[b];
    }
    for (int j = i + 1; j < p; j++) {
      if (A[i][j]) continue;
      for (int b = 0; b < (1 << p); b++) bad[b] = false;
      int i1 = 0, j1 = 0;
      for (i1 = 0; i1 < pos[i].size(); i1++) {
        while (j1 < pos[j].size() && pos[j][j1] < pos[i][i1]) j1++;
        if (j1 == pos[j].size()) break;
        int b = 0;
        for (int x = pos[i][i1] + 1; x < pos[j][j1]; x++) b |= (1 << a[x]);
        bad[b] = true;
      }
      i1 = 0;
      j1 = 0;
      for (j1 = 0; j1 < pos[j].size(); j1++) {
        while (i1 < pos[i].size() && pos[i][i1] < pos[j][j1]) i1++;
        if (i1 == pos[i].size()) break;
        int b = 0;
        for (int x = pos[j][j1] + 1; x < pos[i][i1]; x++) b |= (1 << a[x]);
        bad[b] = true;
      }
      supersets(bad, i, j);
      for (int b = 0; b < (1 << p); b++) {
        wrong[i][b] |= bad[b];
        wrong[j][b] |= bad[b];
      }
    }
  }
  ok[0] = true;
  for (int k = 0; k < p; k++) {
    for (int b : k_sets[k]) {
      if (!ok[b]) continue;
      for (int i = 0; i < p; i++) {
        if (b & (1 << i)) continue;
        bool can_add = true;
        for (int j = 0; j < p; j++) {
          if ((b & (1 << j)) || i == j) continue;
          if (wrong[j][b | (1 << i)]) {
            can_add = false;
            break;
          }
        }
        if (can_add) ok[b | (1 << i)] = true;
      }
    }
  }
  for (int i = 0; i < n; i++) cnt[a[i]]++;
  int sol = 0;
  for (int b = 0; b < (1 << p); b++) {
    if (!ok[b]) continue;
    int act = 0;
    for (int i = 0; i < p; i++)
      if (b & (1 << i)) act += cnt[i];
    sol = max(sol, act);
  }
  cout << n - sol << endl;
  return 0;
}
