#include <bits/stdc++.h>
using namespace std;
mt19937 rng(static_cast<unsigned int>(
    chrono::steady_clock::now().time_since_epoch().count()));
template <typename num_t>
inline void add_mod(num_t& a, const long long& b, const int& m) {
  a = (a + b) % m;
  if (a < 0) a += m;
}
template <typename num_t>
inline bool update_max(num_t& a, const num_t& b) {
  return a < b ? a = b, true : false;
}
template <typename num_t>
inline bool update_min(num_t& a, const num_t& b) {
  return a > b ? a = b, true : false;
}
template <typename num_t>
num_t gcd(num_t lhs, num_t rhs) {
  return !lhs ? rhs : gcd(rhs % lhs, lhs);
}
template <typename num_t>
num_t pw(num_t n, num_t k, const num_t& mod) {
  if (k == -1) {
    return pw(n, mod - 2, mod);
  }
  num_t res = 1;
  for (; k > 0; k >>= 1) {
    if (k & 1) res = 1ll * res * n % mod;
    n = 1ll * n * n % mod;
  }
  return res;
}
const int inf = 1e9 + 7;
const long long ll_inf = 9ll * inf * inf + 7;
const int MAX_N = 5000 + 7;
int n, p;
string s;
vector<vector<int>> a;
vector<vector<int>> states[1 << 17];
int cnt[17];
bool dp[17][17][1 << 17];
int last[17];
bool can[1 << 17];
void solve() {
  cin >> n >> p;
  cin >> s;
  a.resize(p);
  for (int i = (0), _b = (p); i < _b; ++i) {
    a[i].resize(p);
    for (int j = (0), _b = (p); j < _b; ++j) cin >> a[i][j];
  }
  for (int i = n - 1; i >= 0; --i) {
    vector<pair<int, int>> arr;
    for (int j = (0), _b = (p); j < _b; ++j)
      if (last[j] != 0) arr.push_back({last[j], j});
    sort(arr.begin(), arr.end());
    int mask = 0;
    int cur = s[i] - 'a';
    for (auto p : arr) {
      dp[cur][p.second][mask] = 1;
      mask |= 1 << p.second;
    }
    last[cur] = i;
    cnt[cur]++;
  }
  for (int u = (0), _b = (p); u < _b; ++u)
    for (int v = (u), _b = (p); v < _b; ++v) {
      for (int mask = (0), _b = (1 << p); mask < _b; ++mask)
        if (dp[u][v][mask]) {
          for (int j = (0), _b = (p); j < _b; ++j)
            if (!(mask & (1 << j))) dp[u][v][mask | (1 << j)] = 1;
          dp[v][u][mask] = dp[u][v][mask];
        }
    }
  int best = n;
  for (int rm_mask = (0), _b = (1 << p); rm_mask < _b; ++rm_mask) {
    if (rm_mask == 0)
      can[rm_mask] = true;
    else {
      can[rm_mask] = false;
      for (int j = (0), _b = (p); j < _b; ++j)
        if (rm_mask & (1 << j)) can[rm_mask] |= can[rm_mask ^ (1 << j)];
    }
    bool& check = can[rm_mask];
    for (int u = (0), _b = (p); u < _b; ++u)
      if (check && !(rm_mask & (1 << u))) {
        for (int v = (u), _b = (p); v < _b; ++v)
          if (check && !(rm_mask & (1 << v))) {
            if (dp[u][v][rm_mask] == 1 && a[u][v] == 0) check = false;
          }
      }
    if (check) {
      int sum = 0;
      for (int j = (0), _b = (p); j < _b; ++j)
        if (!(rm_mask & (1 << j))) {
          sum += cnt[j];
        }
      update_min(best, sum);
    }
  }
  cout << best << '\n';
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  const bool multiple_test = false;
  int test = 1;
  if (multiple_test) cin >> test;
  for (int i = 0; i < test; ++i) {
    solve();
  }
}
