#include <bits/stdc++.h>
using namespace std;
template <class T>
int getbit(int i, T X) {
  return (X & (1 << (i - 1)));
}
template <class T>
T onbit(int i, T X) {
  return (X | (1 << (i - 1)));
}
template <class T>
T offbit(int i, T X) {
  return (X | (1 << (i - 1)) - (1 << (i - 1)));
}
template <class T>
T sqr(T x) {
  return (x * x);
}
template <class T>
T cube(T x) {
  return (x * x * x);
}
template <class T>
T gcd(T a, T b) {
  T r;
  while (b != 0) {
    r = a % b;
    a = b;
    b = r;
  }
  return a;
}
template <class T>
T lcm(T a, T b) {
  return a / gcd(a, b) * b;
}
int csx[4] = {0, 0, -1, 1};
int csy[4] = {-1, 1, 0, 0};
const int MOD = 1000000007;
const int maxn = 21;
const int infi = (int)(1e9);
int n, m, a[maxn + 5][maxn + 5];
string s[maxn + 5];
int dp[(1 << 20) + 5], sum[maxn + 5][30], maxx[maxn + 5][30],
    mask[maxn + 5][30];
void enter() {
  cin >> n >> m;
  for (typeof(n) i = 1; i <= n; i++) {
    cin >> s[i];
    s[i] = " " + s[i];
  }
  for (typeof(n) i = 1; i <= n; i++)
    for (typeof(m) j = 1; j <= m; j++) cin >> a[i][j];
}
void init() {
  memset(mask, 0, sizeof(mask));
  memset(maxx, -1, sizeof(maxx));
  memset(sum, 0, sizeof(sum));
  for (typeof(m) i = 1; i <= m; i++) {
    for (typeof(n) j = 1; j <= n; j++) {
      int c = s[j][i] - 'a';
      sum[i][c] += a[j][i];
      maxx[i][c] = max(maxx[i][c], a[j][i]);
      mask[i][c] = onbit(j, mask[i][c]);
    }
  }
}
void solve() {
  for (typeof((1 << n) - 1) i = 0; i <= (1 << n) - 1; i++) dp[i] = infi;
  dp[0] = 0;
  for (typeof(m) i = 1; i <= m; i++) {
    for (typeof((1 << n) - 1) X = 0; X <= (1 << n) - 1; X++) {
      for (typeof(n) j = 1; j <= n; j++) {
        int Y = onbit(j, X);
        dp[Y] = min(dp[Y], dp[X] + a[j][i]);
      }
      for (typeof(25) j = 0; j <= 25; j++) {
        int Y = X | mask[i][j];
        if (!mask[i][j]) continue;
        dp[Y] = min(dp[Y], dp[X] + sum[i][j] - maxx[i][j]);
      }
    }
  }
  cout << dp[(1 << n) - 1];
}
int main() {
  enter();
  init();
  solve();
  return 0;
}
