#include <bits/stdc++.h>
using namespace std;
template <class T>
using v2d = vector<vector<T> >;
template <class T>
bool uin(T &a, T b) {
  return a > b ? (a = b, true) : false;
}
template <class T>
bool uax(T &a, T b) {
  return a < b ? (a = b, true) : false;
}
mt19937 rng(chrono::system_clock::now().time_since_epoch().count());
const int maxN = 1e5 + 10;
const int maxK = 17;
const int inf = 1e9;
int n, k, a[maxK][maxK], cnt[maxK], last[maxK], f[20][maxN], g[1 << maxK],
    dp[1 << maxK];
char s[maxN];
int query(int l, int r) {
  int lg = 31 - __builtin_clz(r - l + 1);
  return f[lg][l] | f[lg][r - (1 << lg) + 1];
}
void solve() {
  cin >> n >> k >> (s + 1);
  for (int i = 0; i < (int)(k); ++i) {
    for (int j = 0; j < (int)(k); ++j) {
      cin >> a[i][j];
    }
  }
  for (int i = 1; i <= (int)(n); ++i) {
    f[0][i] = 1 << (s[i] - 'a');
    cnt[s[i] - 'a']++;
  }
  for (int lg = 1; lg <= (int)(19); ++lg) {
    for (int i = 1; i <= (int)(n - (1 << lg) + 1); ++i) {
      f[lg][i] = f[lg - 1][i] | f[lg - 1][i + (1 << (lg - 1))];
    }
  }
  int t = (1 << k) - 1;
  for (int i = n; i; i--) {
    for (int j = 0; j < (int)(k); ++j) {
      if (last[j] != 0 && !a[s[i] - 'a'][j]) {
        int mask = query(i + 1, last[j] - 1);
        int u = 1 << (s[i] - 'a'), v = 1 << (s[last[j]] - 'a');
        g[t ^ mask]++;
        g[t ^ (mask | u)]--;
        g[t ^ (mask | v)]--;
        g[t ^ (mask | u | v)]++;
      }
    }
    last[s[i] - 'a'] = i;
  }
  for (int i = 0; i < (int)(k); ++i) {
    for (int j = 0; j < (int)(1 << k); ++j) {
      if (~j >> i & 1) {
        g[j] += g[j | (1 << i)];
      }
    }
  }
  for (int mask = 0; mask < (int)(1 << k); ++mask) {
    if (g[mask] != 0) {
      dp[mask] = -inf;
    } else {
      for (int i = 0; i < (int)(k); ++i) {
        if (mask >> i & 1) {
          uax(dp[mask], dp[mask ^ (1 << i)] + cnt[i]);
        }
      }
    }
  }
  cout << n - dp[t];
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int T = 1;
  while (T--) {
    solve();
  }
  return 0;
}
