#include <bits/stdc++.h>
using namespace std;
inline void readI(int *i) {
  register int t = 0;
  register char z = getchar();
  int znak = 1;
  if (z == '-') {
    znak = -1;
  }
  while ((z < '0') || ('9' < z)) {
    z = getchar();
    if (z == '-') {
      znak = -1;
    }
  }
  while (('0' <= z) && (z <= '9')) {
    t = (t << 3) + (t << 1) + z - '0';
    z = getchar();
  }
  *i = (t * znak);
}
inline void readUI(int *i) {
  register int t = 0;
  register char z = getchar();
  while ((z < '0') || ('9' < z)) {
    z = getchar();
  }
  while (('0' <= z) && (z <= '9')) {
    t = (t << 3) + (t << 1) + z - '0';
    z = getchar();
  }
  *i = t;
}
inline void readL(long long int *l) {
  register long long int t = 0;
  register char z = getchar();
  int znak = 1;
  if (z == '-') {
    znak *= -1;
  }
  while ((z < '0') || ('9' < z)) {
    z = getchar();
    if (z == '-') {
      znak = -1;
    }
  }
  while (('0' <= z) && (z <= '9')) {
    t = (t << 3) + (t << 1) + z - '0';
    z = getchar();
  }
  *l = (t * znak);
}
inline void readUL(long long int *l) {
  register long long int t = 0;
  register char z = getchar();
  while ((z < '0') || ('9' < z)) {
    z = getchar();
  }
  while (('0' <= z) && (z <= '9')) {
    t = (t << 3) + (t << 1) + z - '0';
    z = getchar();
  }
  *l = t;
}
inline void writeL(long long int l) {
  if (l == 0) {
    putchar(48);
  } else {
    if (l < 0) {
      l *= -1;
      putchar(45);
    }
    int _tab[21];
    int wsk = 0;
    while (l > 0) {
      ++wsk;
      _tab[wsk] = (l % 10) + 48;
      l /= 10;
    }
    for (int j = wsk; j >= 1; --j) {
      putchar(_tab[j]);
    }
  }
}
inline void writeS(string s) {
  int l = s.length();
  for (int i = 0; i < l; ++i) {
    putchar(s[i]);
  }
}
int n, p, a;
string s;
bitset<32> adj[32];
vector<int> pos[30];
bitset<((1 << 17) + 5)> acc, cur;
vector<int> masks;
int inf = (1e9) + 2137;
int dp[((1 << 17) + 5)];
int _(char c) { return (int)(c)-97; }
void forbid(int mask, int a, int b) {
  if (!cur[mask]) {
    return;
  }
  cur[mask] = false;
  for (int i = 0; i < p; ++i) {
    if (i == a || i == b) {
      continue;
    }
    if (mask & (1 << i)) {
      forbid(mask ^ (1 << i), a, b);
    }
  }
}
void mark(int a, int b) {
  cur.reset();
  cur.flip();
  int l = masks.size();
  for (int i = 0; i < l; ++i) {
    forbid(masks[i], a, b);
  }
  acc &= cur;
}
int solve(int mask, int len) {
  if (!acc[mask]) {
    return inf;
  }
  if (dp[mask] != inf) {
    return dp[mask];
  }
  dp[mask] = len;
  for (int i = 0; i < p; ++i) {
    if (mask & (1 << i)) {
      dp[mask] = min(dp[mask], solve(mask ^ (1 << i), len - pos[i].size()));
    }
  }
  return dp[mask];
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> p;
  cin >> s;
  for (int i = 0; i < (1 << p); ++i) {
    acc[i] = true;
    dp[i] = inf;
  }
  for (int i = 0; i < n; ++i) {
    pos[_(s[i])].emplace_back(i);
  }
  for (int i = 0; i < p; ++i) {
    for (int j = 0; j < p; ++j) {
      cin >> a;
      adj[i][j] = (a == 1);
    }
  }
  for (int i = 0; i < p; ++i) {
    if (pos[i].empty()) {
      continue;
    }
    for (int j = i + 1; j < p; ++j) {
      if (adj[i][j]) {
        continue;
      }
      if (pos[j].empty()) {
        continue;
      }
      masks.clear();
      int wi = 0, wj = 0;
      while (wi < pos[i].size() && wj < pos[j].size()) {
        if (pos[i][wi] < pos[j][wj]) {
          while (wi + 1 < pos[i].size() && pos[i][wi + 1] < pos[j][wj]) {
            ++wi;
          }
          int mask = 0;
          for (int k = pos[i][wi] + 1; k < pos[j][wj]; ++k) {
            mask |= (1 << _(s[k]));
          }
          mask ^= ((1 << p) - 1);
          masks.emplace_back(mask);
          ++wi;
        } else {
          while (wj + 1 < pos[j].size() && pos[j][wj + 1] < pos[i][wi]) {
            ++wj;
          }
          int mask = 0;
          for (int k = pos[j][wj] + 1; k < pos[i][wi]; ++k) {
            mask |= (1 << _(s[k]));
          }
          mask ^= ((1 << p) - 1);
          masks.emplace_back(mask);
          ++wj;
        }
      }
      mark(i, j);
    }
  }
  for (int i = 0; i < p; ++i) {
    if (adj[i][i]) {
      continue;
    }
    if (pos[i].empty()) {
      continue;
    }
    masks.clear();
    int l = pos[i].size();
    for (int j = 0; j < l - 1; ++j) {
      int mask = 0;
      for (int k = pos[i][j] + 1; k < pos[i][j + 1]; ++k) {
        mask |= (1 << _(s[k]));
      }
      mask ^= ((1 << p) - 1);
      masks.emplace_back(mask);
    }
    mark(i, i);
  }
  fprintf(stdout, "%d\n", solve((1 << p) - 1, n));
  return 0;
}
