#include <bits/stdc++.h>
using namespace std;
int n, len;
string s[20];
int cost[21][21];
int c[(1 << 20) + 8];
int mask[21][26];
int sum[21][26];
vector<int> idx[21][26];
void set_min(int& a, int b) { a = min(a, b); }
int main() {
  cin >> n >> len;
  for (int i = 0; i < n; ++i) {
    cin >> s[i];
    for (int j = 0; j < len; ++j) {
      idx[j][s[i][j] - 'a'].push_back(i);
      mask[j][s[i][j] - 'a'] |= (1 << i);
    }
  }
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < len; ++j) {
      cin >> cost[i][j];
      sum[j][s[i][j] - 'a'] += cost[i][j];
    }
  map<int, int> choices;
  auto add_choice = [&](int mask, int cost) {
    if (choices.count(mask))
      set_min(choices[mask], cost);
    else
      choices[mask] = cost;
  };
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < len; ++j) {
      int c = s[i][j] - 'a';
      add_choice(mask[j][c], sum[j][c] - cost[i][j]);
      add_choice(1 << i, cost[i][j]);
    }
  for (int i = 0; i < (1 << n) + 8; ++i) c[i] = 987654321;
  c[0] = 0;
  for (int handled = 0; handled < (1 << n) - 1; ++handled) {
    for (const auto& mask_cost : choices) {
      set_min(c[handled | mask_cost.first], c[handled] + mask_cost.second);
    }
  }
  printf("%d\n", c[(1 << n) - 1]);
}
