#include <bits/stdc++.h>
using namespace std;
template <class T>
inline bool rd(T &ret) {
  char c;
  int sgn;
  if (c = getchar(), c == EOF) return 0;
  while (c != '-' && (c < '0' || c > '9')) c = getchar();
  sgn = (c == '-') ? -1 : 1;
  ret = (c == '-') ? 0 : (c - '0');
  while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
  ret *= sgn;
  return 1;
}
template <class T>
inline void pt(T x) {
  if (x < 0) {
    putchar('-');
    x = -x;
  }
  if (x > 9) pt(x / 10);
  putchar(x % 10 + '0');
}
const int inf = 1e9;
const int N = 21;
int n, m;
char s[N][N];
int a[N][N];
int dp[1 << N];
int bit[N][N], cost[N][N];
int main() {
  rd(n);
  rd(m);
  for (int i = 0; i < n; i++) scanf("%s", s[i]);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) rd(a[i][j]);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) {
      int ans = 0, maxn = -inf;
      for (int k = 0; k < n; k++)
        if (s[i][j] == s[k][j]) {
          ans += a[k][j];
          maxn = max(maxn, a[k][j]);
          bit[i][j] |= 1 << k;
        }
      ans -= maxn;
      cost[i][j] = ans;
    }
  for (int i = 1; i < (1 << n); i++) dp[i] = inf;
  dp[0] = 0;
  for (int i = 0; i < (1 << n); i++) {
    for (int j = 0; j < n; j++)
      if ((i & (1 << j)) == 0) {
        for (int k = 0; k < m; k++) {
          dp[i | (1 << j)] = min(dp[i | (1 << j)], dp[i] + a[j][k]);
          dp[i | bit[j][k]] = min(dp[i | bit[j][k]], dp[i] + cost[j][k]);
        }
      }
  }
  pt(dp[(1 << n) - 1]);
  return 0;
}
