#include <bits/stdc++.h>
long long gcd(long long x, long long y) {
  return y % x == 0 ? x : gcd(y % x, x);
}
template <class T>
T my_abs(T a) {
  if (a < 0) a = -a;
  return a;
}
const int maxn = 30 + 7, inf = 0x3f3f3f3f;
int dp[1 << 20];
int n, m, a[maxn][maxn], c[maxn][maxn], sv[maxn][maxn];
char str[maxn];
std::string s[maxn];
int main() {
  scanf("%d %d", &n, &m);
  std::memset(dp, 0x3f, sizeof(dp));
  for (int i = (int)(0); i <= (int)(n - 1); i++) scanf("%s", str), s[i] = str;
  for (int i = (int)(0); i <= (int)(n - 1); i++)
    for (int j = (int)(0); j <= (int)(m - 1); j++) scanf("%d", &a[i][j]);
  for (int i = (int)(0); i <= (int)(n - 1); i++) {
    for (int j = (int)(0); j <= (int)(m - 1); j++) {
      int curv = 0;
      for (int k = (int)(0); k <= (int)(n - 1); k++) {
        if (s[i][j] == s[k][j]) {
          sv[i][j] |= 1 << k;
          c[i][j] += a[k][j];
          curv = (curv > a[k][j] ? curv : a[k][j]);
        }
      }
      c[i][j] -= curv;
    }
  }
  dp[0] = 0;
  for (int i = (int)(1); i <= (int)((1 << n) - 1); i++) {
    int lowbit = -1;
    for (int j = (int)(0); j <= (int)(n - 1); j++) {
      if ((i >> j) & 1) {
        lowbit = j;
        break;
      }
    }
    for (int j = (int)(0); j <= (int)(m - 1); j++) {
      dp[i] = (dp[i] < dp[i & (i ^ sv[lowbit][j])] + c[lowbit][j]
                   ? dp[i]
                   : dp[i & (i ^ sv[lowbit][j])] + c[lowbit][j]);
      dp[i] = (dp[i] < dp[i ^ (1 << lowbit)] + a[lowbit][j]
                   ? dp[i]
                   : dp[i ^ (1 << lowbit)] + a[lowbit][j]);
    }
  }
  printf("%d\n", dp[(1 << n) - 1]);
  return 0;
}
