#include <bits/stdc++.h>
#pragma GCC optimize("O2")
using namespace std;
int n, m, dp[1 << 20], c[26][26];
int low[26][26], has[26][26];
int mx[26][26], group[26][26];
string board[20];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  memset(dp, 0x3f3f3f3f, sizeof(dp));
  memset(low, 0x3f3f3f3f, sizeof(low));
  memset(mx, 0, sizeof(mx));
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    cin >> board[i];
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> c[i][j];
      low[j][board[i][j] - 'a'] = min(low[j][board[i][j] - 'a'], i);
      mx[j][board[i][j] - 'a'] = max(mx[j][board[i][j] - 'a'], c[i][j]);
    }
    for (int j = 0; j < m; j++) {
      int t = low[j][board[i][j] - 'a'];
      has[j][t] |= (1 << i);
      group[j][t] += c[i][j];
    }
  }
  dp[0] = 0;
  for (int i = 0; i < m; i++) {
    for (register int mask = 0; mask < (1 << n); mask++) {
      for (int add = 0; add < n; add++) {
        int word = board[add][i] - 'a';
        int lo = low[i][board[add][i] - 'a'];
        dp[mask | (1 << add)] =
            min(dp[mask | (1 << add)], dp[mask] + c[add][i]);
        if (lo == add) {
          dp[mask | has[i][lo]] =
              min(dp[mask | has[i][lo]], dp[mask] + group[i][lo] - mx[i][word]);
        }
      }
    }
  }
  cout << dp[(1 << n) - 1];
  return 0;
}
