#include <bits/stdc++.h>
using namespace std;
template <class T, class L>
bool smax(T& x, L y) {
  return x < y ? (x = y, 1) : 0;
}
template <class T, class L>
bool smin(T& x, L y) {
  return x > y ? (x = y, 1) : 0;
}
const int maxn = 20;
int dp[1 << maxn], n, m, cost[maxn][maxn];
string s[maxn];
int gang[maxn][maxn], co[maxn][maxn];
int main() {
  ios::sync_with_stdio(0), cin.tie(0);
  memset(dp, 63, sizeof dp);
  cin >> n >> m;
  for (int i = 0; i < n; i++) cin >> s[i];
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) cin >> cost[i][j];
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) {
      int all = 0, big = 0;
      for (int k = 0; k < n; k++)
        if (s[i][j] == s[k][j])
          gang[i][j] |= 1 << k, all += cost[k][j], smax(big, cost[k][j]);
      co[i][j] = all - big;
    }
  dp[0] = 0;
  for (int mask = 1; mask < 1 << n; mask++) {
    int idx = __builtin_ctz(mask);
    for (int i = 0; i < m; i++)
      smin(dp[mask], min(cost[idx][i] + dp[mask ^ (1 << idx)],
                         co[idx][i] + dp[mask ^ (mask & gang[idx][i])]));
  }
  cout << dp[(1 << n) - 1] << '\n';
  return 0;
}
