#include <bits/stdc++.h>
using namespace std;
const int MAXP = 18;
const int MAXN = 1000001;
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
int n, p;
string cad;
int freq[MAXP];
int val[1 << MAXP];
int vis[1 << MAXP];
vector<pair<int, int> > lista[1 << MAXP];
bool mat[MAXP][MAXP];
bool invalid[1 << MAXP];
bool marked[MAXP][MAXP][1 << MAXP];
int mapea(int i) { return cad[i] - 'a'; }
int dfs(int u) {
  if (vis[u]) return val[u];
  vis[u] = 1;
  int ans = 0;
  for (int j = 0; j < p; j++) {
    if (u & 1 << j) continue;
    int v = u | 1 << j;
    if (!invalid[v]) ans = max(ans, dfs(v) + freq[j]);
  }
  return val[u] = ans;
}
void compute(int a, int b) {
  int id = 0, last = -1, mask;
  while (id < n) {
    if (mapea(id) == b && last != -1 && mask) {
      lista[mask].push_back(pair<int, int>(a, b));
      mask = 0;
      last = -1;
    }
    if (mapea(id) == a) {
      last = id;
      mask = 0;
    }
    if (mapea(id) != a && mapea(id) != b) mask |= 1 << mapea(id);
    id++;
  }
}
void bfs(int mask, int a, int b) {
  queue<int> q;
  q.push(mask);
  invalid[mask] = 1;
  marked[a][b][mask] = 1;
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int i = 0; i < p; i++) {
      if (i == a || i == b) continue;
      int v = u | 1 << i;
      if (!marked[a][b][v]) {
        invalid[v] = 1;
        marked[a][b][v] = 1;
        q.push(v);
      }
    }
  }
  invalid[(1 << p) - 1] = 0;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> p;
  cin >> cad;
  for (int i = 0; i < n; i++) freq[mapea(i)]++;
  for (int i = 0; i < p; i++)
    for (int j = 0; j < p; j++) {
      cin >> mat[i][j];
      if (!mat[i][j]) compute(i, j);
    }
  for (int i = 0; i < 1 << p; i++)
    for (int j = 0; j < lista[i].size(); j++)
      bfs(i, lista[i][j].first, lista[i][j].second);
  cout << n - dfs(0) << '\n';
  return 0;
}
