#include <bits/stdc++.h>
using namespace std;
const int INF = 1 << 30;
inline void read(int &x) {
  x = 0;
  char c = getchar();
  while (c >= '0' && c <= '9') {
    x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
  }
}
int n, m;
string s[25];
int a[25][25];
int cl[25][25];
int maxn[25][25];
int minn[25];
int l[25][25];
long long dp[1100000];
vector<int> v;
int main(void) {
  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 >> a[i][j];
  for (int j = 0; j < m; j++) {
    for (int i = 0; i < n; i++) {
      l[s[i][j] - 'a'][j] |= (1 << i);
      cl[s[i][j] - 'a'][j] += a[i][j];
      maxn[s[i][j] - 'a'][j] = max(maxn[s[i][j] - 'a'][j], a[i][j]);
      v.push_back(s[i][j] - 'a');
    }
  }
  sort(v.begin(), v.end());
  memset(minn, 127, sizeof(minn));
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) minn[i] = min(minn[i], a[i][j]);
  v.erase(unique(v.begin(), v.end()), v.end());
  for (int i = 0; i < (int)v.size(); i++) {
    for (int j = 0; j < m; j++) cl[v[i]][j] -= maxn[v[i]][j];
  }
  memset(dp, 127, sizeof(dp));
  dp[0] = 0;
  for (int mask = 0; mask < (1 << n); mask++) {
    for (int i = 0; i < n; i++)
      if ((mask & (1 << i)) == 0) {
        dp[mask | (1 << i)] = min(dp[mask | (1 << i)], dp[mask] + minn[i]);
        for (int j = 0; j < m; j++)
          dp[mask | l[s[i][j] - 'a'][j]] =
              min(dp[mask | l[s[i][j] - 'a'][j]],
                  (long long)dp[mask] + cl[s[i][j] - 'a'][j]);
      }
  }
  cout << dp[(1 << n) - 1];
  return 0;
}
