#include <bits/stdc++.h>
using namespace std;
char s[20 + 10];
vector<string> str;
int n, m;
int dp[(1 << 20)], a[20][20];
int newMask[20][20], cost[20][20];
int opt(int mask) {
  if (__builtin_popcount(mask) == n) return 0;
  int &state = dp[mask];
  if (state != -1) return state;
  state = 0x3f3f3f3f;
  int id;
  for (int i = 0; i < n; ++i)
    if (!(mask & (1 << i))) {
      id = i;
      break;
    }
  for (int j = 0; j < m; ++j) {
    state = min(state, cost[id][j] + opt(mask | newMask[id][j]));
    state = min(state, a[id][j] + opt(mask | (1 << id)));
  }
  return state;
}
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 0; i < n; ++i) scanf(" %s ", s), str.push_back(s);
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j) scanf("%d", &a[i][j]);
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j) {
      newMask[i][j] = 0;
      cost[i][j] = 0;
      int maxa = 0;
      for (int k = 0; k < n; ++k)
        if (str[i][j] == str[k][j]) {
          maxa = max(maxa, a[k][j]);
          cost[i][j] += a[k][j];
          newMask[i][j] |= (1 << k);
        }
      cost[i][j] -= maxa;
    }
  memset(dp, -1, sizeof(dp));
  printf("%d\n", opt(0));
  return 0;
}
