#include <bits/stdc++.h>
using namespace std;
const int MAXN = 21, INF = 1e8;
int N, M;
char str[MAXN][MAXN];
int a[MAXN][MAXN];
int dp[1 << MAXN];
void init() {
  scanf("%d%d", &N, &M);
  for (int i = 0; i < N; i++) scanf("%s", str[i]);
  for (int i = 0; i < N; i++)
    for (int j = 0; j < M; j++) scanf("%d", &a[i][j]);
}
void solve() {
  for (int mask = 1; mask < (1 << N); mask++) dp[mask] = INF;
  for (int i = 0; i < M; i++) {
    vector<int> t[26];
    for (int j = 0; j < N; j++) t[str[j][i] - 'a'].push_back(j);
    vector<pair<int, int> > v;
    for (int c = 0; c < 26; c++)
      if (t[c].size() > 0) {
        int mx = 0, sum = 0, mask = 0;
        for (auto &x : t[c]) {
          sum += a[x][i];
          mx = max(mx, a[x][i]);
          mask |= 1 << x;
        }
        v.push_back(pair<int, int>(mask, sum - mx));
      }
    for (int j = 0; j < N; j++) v.push_back(pair<int, int>(1 << j, a[j][i]));
    for (int mask = 0; mask < (1 << N); mask++)
      if (dp[mask] < INF) {
        for (auto &x : v) {
          int mm = mask | x.first;
          dp[mm] = min(dp[mm], dp[mask] + x.second);
        }
      }
  }
  printf("%d\n", dp[(1 << N) - 1]);
}
int main() {
  init();
  solve();
  return 0;
}
