#include <bits/stdc++.h>
using namespace std;
const int MAXN = 3e5 + 10;
const long long MOD = 1e9 + 9;
inline long long in() {
  long long x = 0, flag = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') flag = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9')
    x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar();
  return x * flag;
}
inline char incha() {
  char ch = getchar();
  while (ch < 'a' || ch > 'z') ch = getchar();
  return ch;
}
int n, m;
char ch[23][23];
int cost[23][23];
int getdif() {
  int ret = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      int cnt = 0;
      for (int k = 1; k <= n; k++) cnt += (ch[i][j] != ch[k][j]);
      if (cnt == n - 1) ret |= (1 << (i - 1));
    }
  }
  return ret;
}
int low0(int x) {
  for (int i = 1; i <= n; i++)
    if ((x & (1 << (i - 1))) == 0) return i;
  return 0;
}
struct Trans {
  int sta, cos;
} g[23][23][2];
int f[1 << 21];
int main() {
  n = in(), m = in();
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) ch[i][j] = incha();
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) cost[i][j] = in();
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      g[i][j][0] = (Trans){1 << (i - 1), cost[i][j]};
      int mx = 0, sum = 0, sta = 0;
      for (int k = 1; k <= n; k++)
        if (ch[i][j] == ch[k][j])
          sum += cost[k][j], mx = max(mx, cost[k][j]), sta |= (1 << (k - 1));
      g[i][j][1] = (Trans){getdif() | sta, sum - mx};
    }
  }
  memset(f, 0x3f, sizeof f);
  f[0] = 0;
  for (int i = 0; i < (1 << n); i++) {
    int pos = low0(i);
    for (int j = 1; j <= m; j++) {
      for (int k = 0; k <= 1; k++) {
        int nex = i | g[pos][j][k].sta;
        f[nex] = min(f[nex], f[i] + g[pos][j][k].cos);
      }
    }
  }
  cout << f[(1 << n) - 1] << endl;
  return 0;
}
