#include <bits/stdc++.h>
using namespace std;
const int MAX_COUNT = 21;
string words[MAX_COUNT];
int prices[MAX_COUNT][MAX_COUNT];
int toChange[MAX_COUNT][MAX_COUNT];
int bits[MAX_COUNT][MAX_COUNT];
int d[1 << MAX_COUNT];
int main() {
  int rows, cols;
  scanf("%d%d", &rows, &cols);
  for (int i = 0; i < rows; i++) cin >> words[i];
  for (int i = 0; i < rows; i++)
    for (int j = 0; j < cols; j++) scanf("%d", &prices[i][j]);
  for (int i = 0; i < rows; i++)
    for (int j = 0; j < cols; j++) {
      char cur = words[i][j];
      int mxprice = prices[i][j];
      for (int u = 0; u < rows; u++)
        if (words[u][j] == cur) {
          toChange[i][j] += prices[u][j];
          bits[i][j] |= (1 << u);
          mxprice = max(mxprice, prices[u][j]);
        }
      toChange[i][j] -= mxprice;
    }
  for (int i = 0; i < 1 << rows; i++) d[i + 1] = 1000000000;
  for (int mask = 1; mask < (1 << rows); mask++) {
    int fRow = 0;
    for (int u = 0; u < rows; u++)
      if (mask & (1 << u)) {
        fRow = u;
        break;
      }
    for (int j = 0; j < cols; j++) {
      d[mask] =
          min(d[mask], d[mask & (mask ^ bits[fRow][j])] + toChange[fRow][j]);
      d[mask] = min(d[mask], d[mask & (mask ^ (1 << fRow))] + prices[fRow][j]);
    }
  }
  cout << d[(1 << rows) - 1] << endl;
  cin.get();
  cin.get();
  return 0;
}
