#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void cmax(int& x, const int& y) { x = x > y ? x : y; }
void cmin(int& x, const int& y) { x = x < y ? x : y; }
template <class T>
istream& operator>>(istream& in, vector<T>& V) {
  for (auto& x : V) in >> x;
  return in;
}
template <class T>
ostream& operator<<(ostream& out, const vector<T>& V) {
  for (auto x : V) out << x << ' ';
  return out;
}
template <class T>
void sort(vector<T>& V) {
  sort(V.begin(), V.end());
}
template <class T>
void reverse(vector<T>& V) {
  reverse(V.begin(), V.end());
}
template <class T>
int SZ(const vector<T>& V) {
  return (int)V.size();
}
void debug() { cerr << "whxorz" << '\n'; }
const int M = 17;
const int S = 131072;
const int N = 100000 + 5;
int n, p;
int nxt[N][M];
int cnt[M];
int can[M][M];
int f[S], msk[S][M][M], g[S];
char str[N];
void solve(int s, int a, int b) {
  if (!msk[s][a][b]) return;
  msk[s][a][b] = f[s] = false;
  for (int i = 0; i < p; i++)
    if ((~s >> i & 1) && i != a && i != b) solve(s | (1 << i), a, b);
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> n >> p;
  cin >> str + 1;
  memset(f, true, sizeof(f));
  memset(msk, true, sizeof(msk));
  for (int i = 1; i <= n; i++) ++cnt[str[i] - 'a'];
  for (int j = 0; j < p; j++) nxt[n][j] = n + 1;
  for (int i = n; i >= 1; i--) {
    for (int j = 0; j < p; j++) nxt[i - 1][j] = nxt[i][j];
    nxt[i - 1][str[i] - 'a'] = i;
  }
  for (int i = 0; i < p; i++)
    for (int j = 0; j < p; j++) cin >> can[i][j];
  for (int i = 1; i <= n; i++)
    for (int j = 0; j < p; j++) {
      bool flag = true;
      if (can[str[i] - 'a'][j]) flag = false;
      if (nxt[i][j] == n + 1) flag = false;
      if (nxt[i][str[i] - 'a'] < nxt[i][j]) flag = false;
      if (flag) {
        int s = 0;
        for (int k = 0; k < p; k++)
          if (nxt[i][k] < nxt[i][j]) s |= 1 << k;
        solve(s, str[i] - 'a', j);
      }
    }
  g[0] = true;
  int up = 1 << p;
  for (int i = 0; i < up; i++)
    if (f[i] && g[i])
      for (int j = 0; j < p; j++)
        if ((~i >> j & 1) && f[i | (1 << j)]) g[i | (1 << j)] |= g[i];
  int res = n;
  for (int i = 0; i < up; i++) {
    if (!g[i]) continue;
    int c = 0;
    for (int j = 0; j < p; j++)
      if (~i >> j & 1) c += cnt[j];
    cmin(res, c);
  }
  cout << res << '\n';
  return 0;
}
