#include <bits/stdc++.h>
using namespace std;
const int nsz = 1e5, asz = 17, lgsz = 17, msksz = (1 << asz) - 1,
          inf = 0x3f3f3f3f;
bool g[asz + 5][asz + 5];
int n, m, full, lg[nsz + 5], a[nsz + 5], lst[asz + 5], nxt[nsz + 5],
    tmp[msksz + 5], ban[msksz + 5], dp[msksz + 5], ans = inf;
string s;
vector<int> pos[asz + 5];
struct sparse_table {
  int lg[nsz + 5], st[nsz + 5][lgsz + 5];
  void inline init(int a[]) {
    for (int i = 1; i <= n; ++i) {
      lg[i] = lg[i >> 1] + 1;
      st[i][0] = 1 << a[i];
    }
    for (int k = 1; k <= lgsz; ++k) {
      for (int u = 1; u <= n; ++u) {
        int p = u + (1 << (k - 1));
        if (u + (1 << k) - 1 > n || p > n) break;
        st[u][k] = st[p][k - 1] | st[u][k - 1];
      }
    }
  }
  int inline qry(int l, int r) {
    int k = lg[r - l + 1] - 1, len = 1 << k;
    return st[l][k] | st[r - len + 1][k];
  }
};
sparse_table st;
string inline bin(int S) {
  string s;
  for (int i = 0; i < m; ++i) {
    s += ((S >> i) & 1) + 48;
  }
  return s;
}
int main() {
  ios::sync_with_stdio(0);
  cin >> n >> m >> s;
  full = (1 << m) - 1;
  s = ' ' + s;
  for (int a = 0; a < m; ++a) {
    for (int b = 0; b < m; ++b) {
      cin >> g[a][b];
    }
  }
  fill(lst, lst + m, n + 1);
  for (int i = n; i >= 1; --i) {
    a[i] = s[i] - 'a';
    nxt[i] = lst[a[i]];
    lst[a[i]] = i;
  }
  for (int i = 1; i <= n; ++i) {
    pos[a[i]].push_back(i);
  }
  st.init(a);
  for (int c1 = 0; c1 < m; ++c1) {
    for (int c2 = 0; c2 < m; ++c2) {
      if (g[c1][c2] || !pos[c1].size() || !pos[c2].size()) continue;
      int i = 0;
      for (int j = 0; j < pos[c2].size(); ++j) {
        for (; i < pos[c1].size() && nxt[pos[c1][i]] < pos[c2][j]; ++i)
          ;
        if (pos[c1][i] >= pos[c2][j]) continue;
        int l = pos[c1][i], r = pos[c2][j], S = st.qry(l, r);
        S ^= (1 << a[l]) | (1 << a[r]);
        ++tmp[S];
        --tmp[S | (1 << c1)];
        --tmp[S | (1 << c2)];
        ++tmp[S | (1 << c1) | (1 << c2)];
      }
    }
  }
  for (int S = 0; S <= full; ++S) {
    for (int s = S; s; s = S & (s - 1)) {
      ban[S] += tmp[s];
    }
  }
  for (int i = 0; i < m; ++i) {
    lg[1 << i] = i;
  }
  memset(dp, inf, sizeof(dp));
  dp[0] = n;
  for (int S = 0; S <= full; ++S) {
    if (ban[S]) continue;
    int rS = full ^ S;
    ans = min(ans, dp[S]);
    for (int t = rS, d = t & -t; d; t -= d, d = t & -t) {
      int i = lg[d], nS = S ^ d;
      if (ban[nS]) continue;
      dp[nS] = min(dp[nS], dp[S] - (int)pos[i].size());
    }
  }
  cout << ans << '\n';
}
