#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
const int mod1 = 998244353;
#pragma GCC optimize("O2")
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
int rand(int l, int r) {
  uniform_int_distribution<int> uid(l, r);
  return uid(rng);
}
long long int pwr(long long int a, long long int b, long long int mod) {
  a %= mod;
  int ans = 1;
  while (b) {
    if (b & 1) ans = (ans * a) % mod;
    a = (a * a) % mod;
    b >>= 1;
  }
  return ans;
}
string to_string(string s) { return '"' + s + '"'; }
string to_string(const char* s) { return to_string((string)s); }
string to_string(bool b) { return (b ? "true" : "false"); }
template <typename A, typename B>
string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
template <typename A>
string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto& x : v) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}
void debug_out() { cerr << '\n'; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H);
  debug_out(T...);
}
const int N = 1e5 + 5;
const int NN = 18;
bool a[NN][NN];
int nxt[N][NN];
int c[NN];
bool dp[1 << 17][17][17];
bool vis[1 << 17][17][17];
bool good[1 << 17];
int n, p;
int ans;
bool dfs(int mask, int r, int s) {
  if (vis[mask][r][s]) return dp[mask][r][s];
  vis[mask][r][s] = 1;
  bool lol = dp[mask][r][s];
  for (int i = 0; i <= p - 1; i++) {
    if (i == r || i == s) continue;
    if (mask & (1 << i)) {
      lol |= dfs(mask ^ (1 << i), r, s);
    }
  }
  return dp[mask][r][s] = lol;
}
void dfs1(int mask, int val) {
  if (!good[mask]) return;
  good[mask] = 0;
  ans = min(ans, val);
  for (int i = 0; i <= p - 1; i++) {
    if (!(mask & (1 << i))) dfs1(mask ^ (1 << i), val - c[i]);
  }
}
void solve() {
  cin >> n >> p;
  ans = n;
  string s;
  cin >> s;
  s = '0' + s;
  for (int i = 1; i <= n; i++) {
    c[s[i] - 'a']++;
  }
  for (int i = 0; i <= p - 1; i++) {
    for (int j = 0; j <= p - 1; j++) {
      cin >> a[i][j];
    }
  }
  for (int i = 0; i <= p - 1; i++) {
    nxt[0][i] = n + 1;
  }
  for (int j = 0; j <= p - 1; j++) {
    int pt = 1;
    while (pt < n + 1 && s[pt] != char('a' + j)) pt++;
    for (int i = 1; i <= n; i++) {
      if (pt == i) pt++;
      while (pt < n + 1 && s[pt] != char('a' + j)) pt++;
      nxt[i][j] = pt;
    }
  }
  vector<pair<int, int> > temp;
  for (int i = 1; i <= n; i++) {
    temp.clear();
    for (int j = 0; j <= p - 1; j++) {
      temp.push_back({nxt[i][j], j});
    }
    sort(temp.begin(), temp.end());
    int m = 0;
    for (pair<int, int> x : temp) {
      if (x.first == n + 1) break;
      dp[m][s[i] - 'a'][x.second] = 1;
      if (x.second == s[i] - 'a') break;
      m ^= (1 << x.second);
    }
  }
  int tot = (1 << p) - 1;
  for (int i = 0; i <= p - 1; i++) {
    for (int j = 0; j <= p - 1; j++) {
      if (i == j) {
        int m = tot ^ (1 << i);
        dfs(m, i, j);
      } else {
        int m = (tot ^ (1 << i) ^ (1 << j));
        dfs(m, i, j);
      }
    }
  }
  for (int mask = 0; mask <= tot; mask++) {
    bool pos = 1;
    for (int i = 0; i <= p - 1; i++) {
      for (int j = 0; j <= p - 1; j++) {
        if (dp[mask][i][j] && !a[i][j]) {
          pos = 0;
          break;
        }
      }
    }
    good[mask] = pos;
  }
  dfs1(0, n);
  cout << ans;
}
signed main() {
  ios ::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  int t = 1;
  for (int tt = 1; tt <= t; tt++) {
    solve();
  }
  return 0;
}
