#include <bits/stdc++.h>
class Tracker {
 private:
  int32_t* buffer;
  std::vector<int32_t> bits_;

 public:
  Tracker(std::vector<int32_t> bits) {
    bits_ = bits;
    buffer = new int32_t[1 << bits.size()];
    for (int32_t i = 0; i < (1 << bits.size()); i++) buffer[i] = 0;
  }
  void add_set(int32_t mask) {
    int32_t new_mask = 0;
    for (int32_t i = 0; i < bits_.size(); i++)
      if (mask & (1 << bits_[i])) new_mask |= 1 << i;
    buffer[(1 << bits_.size()) - new_mask - 1] = 1;
  }
  void finish() {
    int32_t N = bits_.size();
    int32_t* buf2 = new int32_t[1 << N];
    for (int i = 0; i < (1 << N); ++i) {
      buf2[i] = buffer[(1 << N) - i - 1];
    }
    for (int i = 0; i < N; ++i)
      for (int mask = 0; mask < (1 << N); ++mask) {
        if (mask & (1 << i)) buf2[mask] += buf2[mask ^ (1 << i)];
      }
    for (int32_t i = 0; i < (1 << N); i++) buffer[i] = buf2[(1 << N) - i - 1];
  }
  bool blocking(int32_t mask) {
    int32_t new_mask = 0;
    for (int32_t i = 0; i < bits_.size(); i++)
      if (mask & (1 << bits_[i])) new_mask |= 1 << i;
    return buffer[new_mask] == 0;
  }
};
int main() {
  int32_t n, p;
  std::cin >> n >> p;
  std::string str;
  std::cin >> str;
  bool** pass = new bool*[p];
  for (int32_t i = 0; i < p; i++) {
    pass[i] = new bool[p];
    for (int32_t j = 0; j < p; j++) {
      char ch;
      std::cin >> ch;
      pass[i][j] = ch == '1';
    }
  }
  int32_t num_chars[26];
  for (int32_t i = 0; i < 26; i++) num_chars[i] = 0;
  for (int32_t i = 0; i < n; i++) num_chars[str[i] - 'a']++;
  int32_t* pref_sums[26];
  for (int32_t i = 0; i < 26; i++) {
    pref_sums[i] = new int32_t[n + 1];
    pref_sums[i][0] = 0;
    for (int32_t j = 1; j <= n; j++)
      pref_sums[i][j] = pref_sums[i][j - 1] + (str[j - 1] - 'a' == i);
  }
  Tracker* trackers[17][17];
  for (int32_t i = 0; i < p; i++)
    for (int32_t j = i; j < p; j++) {
      std::vector<int32_t> bits;
      for (int32_t k = 0; k < p; k++)
        if (k != i && k != j) bits.push_back(k);
      trackers[i][j] = new Tracker(bits);
    }
  int32_t prev_letters[26];
  for (int32_t i = 0; i < 26; i++) prev_letters[i] = -1;
  for (int32_t i = 0; i < n; i++) {
    for (int32_t j = 0; j < p; j++) {
      if (prev_letters[j] != -1) {
        int32_t mask = 0;
        for (int32_t k = 0; k < p; k++)
          if (pref_sums[k][i] > pref_sums[k][prev_letters[j] + 1])
            mask |= 1 << k;
        trackers[std::min(j, str[i] - 'a')][std::max(j, str[i] - 'a')]->add_set(
            mask);
      }
    }
    prev_letters[str[i] - 'a'] = i;
  }
  for (int32_t i = 0; i < p; i++)
    for (int32_t j = i; j < p; j++) trackers[i][j]->finish();
  bool* correct = new bool[1 << p];
  correct[0] = true;
  for (int32_t i = 1; i < (1 << p); i++) {
    std::vector<int32_t> bits;
    for (int32_t j = 0; j < p; j++)
      if (i & (1 << j)) bits.push_back(j);
    correct[i] = true;
    for (int32_t j = 0; j < bits.size() && correct[i]; j++)
      for (int32_t k = j; k < bits.size(); k++) {
        if (pass[bits[j]][bits[k]]) continue;
        if (!trackers[bits[j]][bits[k]]->blocking(
                i ^ (j == k ? (1 << bits[j])
                            : ((1 << bits[j]) | (1 << bits[k]))))) {
          correct[i] = false;
          break;
        }
      }
  }
  int32_t* dp = new int32_t[1 << p];
  dp[0] = 0;
  for (int32_t i = 1; i < (1 << p); i++) {
    if (correct[i]) {
      dp[i] = 0;
      for (int32_t j = 0; j < p; j++)
        if (i & (1 << j)) dp[i] += num_chars[j];
    } else {
      dp[i] = n + 1;
      continue;
    }
    for (int32_t j = 0; j < p; j++)
      if (i & (1 << j)) {
        dp[i] = std::min(dp[i], dp[i ^ (1 << j)]);
      }
  }
  std::cout << dp[(1 << p) - 1];
  return 0;
}
