#include <bits/stdc++.h>
using namespace std;
const int inf = 2000000005;
const int maxt = (1 << 20) + 5;
int all[maxt], dp[2][maxt];
int best[30], a[30][30];
int mask[30][30], cost[30][30];
char str[30][30];
int n, m;
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++) scanf("%s", str[i]), best[i] = inf;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      scanf("%d", &a[i][j]), best[i] = min(best[i], a[i][j]);
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      bool ok = true;
      for (int k = 0; k < n; k++)
        if (k != i && str[i][j] == str[k][j]) ok = false;
      if (ok) best[i] = 0;
    }
  }
  for (int j = 0; j < m; j++) {
    for (int c = 0; c < 26; c++) {
      mask[j][c] = 0;
      cost[j][c] = 0;
      int maxc = 0, cnt = 0;
      for (int i = 0; i < n; i++)
        if (str[i][j] - 'a' == c) {
          mask[j][c] |= 1 << i;
          cost[j][c] += a[i][j];
          maxc = max(maxc, a[i][j]);
          cnt++;
        }
      cost[j][c] -= maxc;
      if (cnt < 2) mask[j][c] = -1;
    }
  }
  for (int i = 0; i < 1 << n; i++) dp[0][i] = dp[1][i] = inf;
  int nw = 0, ls = 1;
  dp[nw][0] = 0;
  for (int j = 0; j < m; j++)
    for (int c = 0; c < 26; c++)
      if (mask[j][c] != -1) {
        swap(nw, ls);
        memcpy(dp[nw], dp[ls], sizeof dp[ls]);
        for (int i = 0; i < 1 << n; i++) {
          dp[nw][i | mask[j][c]] =
              min(dp[nw][i | mask[j][c]], dp[ls][i] + cost[j][c]);
        }
      }
  for (int i = 0; i < 1 << n; i++) {
    all[i] = 0;
    for (int j = 0; j < n; j++)
      if ((i >> j) & 1)
        ;
      else
        all[i] += best[j];
  }
  int ans = inf;
  for (int i = 0; i < 1 << n; i++) ans = min(ans, all[i] + dp[nw][i]);
  printf("%d\n", ans);
  return 0;
}
