#include <bits/stdc++.h>
using namespace std;
void debug_out() { cerr << endl; }
template <class T>
ostream& prnt(ostream& out, T v) {
  out << v.size() << '\n';
  for (auto e : v) out << e << ' ';
  return out;
}
template <class T>
ostream& operator<<(ostream& out, vector<T> v) {
  return prnt(out, v);
}
template <class T>
ostream& operator<<(ostream& out, set<T> v) {
  return prnt(out, v);
}
template <class T1, class T2>
ostream& operator<<(ostream& out, map<T1, T2> v) {
  return prnt(out, v);
}
template <class T1, class T2>
ostream& operator<<(ostream& out, pair<T1, T2> p) {
  return out << '(' << p.first << ' ' << p.second << ')';
}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << " " << H;
  debug_out(T...);
}
const long double PI = acos(-1);
int n, p, m[22][22], lst[100005][22], fr[22];
string s;
int uz[1 << 18], dp[1 << 18];
set<pair<int, int> > nogud;
int calc(int msk) {
  int ans = 0;
  for (int i = 0; i < p; i++) {
    if (msk & (1 << i)) {
      ans += fr[i];
    }
  }
  return ans;
}
int main() {
  ios::sync_with_stdio(false);
  cin >> n >> p;
  cin >> s;
  for (auto& it : s) {
    it -= 'a';
    fr[it]++;
  }
  for (int i = 0; i < p; i++) {
    for (int j = 0; j < p; j++) {
      cin >> m[i][j];
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < p; j++) lst[i][j] = lst[i - 1][j];
    lst[i][s[i - 1]] = i;
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < p; j++) {
      if (lst[i - 1][j] == 0) continue;
      if (lst[i - 1][j] < lst[i - 1][s[i - 1]]) continue;
      if (m[s[i - 1]][j]) continue;
      int msk1 = 0, msk2 = 0;
      msk1 |= (1 << s[i - 1]);
      msk2 |= (1 << s[i - 1]);
      msk1 |= (1 << j);
      msk2 |= (1 << j);
      for (int k = 0; k < p; k++) {
        if (lst[i - 1][k] > lst[i - 1][j]) {
          msk1 |= (1 << k);
        }
      }
      nogud.insert({msk1, msk2});
    }
  }
  int mx = 1 << p;
  for (auto [msk1, msk2] : nogud) {
    int msk3 = (msk1 ^ msk2) ^ (mx - 1);
    for (int i = (mx - 1) & msk3; i >= msk2; i = (i - 1) & msk3) {
      uz[i | msk2] = 1;
    }
  }
  dp[mx - 1] = 1;
  int ans = n;
  for (int i = mx - 2; i >= 0; i--) {
    if (uz[i]) continue;
    for (int k = 0; k < p; k++) {
      if (!(i & (1 << k))) {
        dp[i] |= dp[i ^ (1 << k)];
      }
    }
    if (dp[i]) ans = min(ans, calc(i));
  }
  cout << ans << '\n';
  return 0;
}
