#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<int> v);
void print_array(int* array, int start, int end);
int n, m, a[30][30], c[30][30], col[30][30], memo[1200000];
string s[30];
int solve(int mask) {
  if (memo[mask] != -1)
    return memo[mask];
  else if (mask == 0)
    return 0;
  else {
    int low = 0;
    for (int i = (0), _b = (n); i < _b; i++) {
      if (mask & (1 << i)) {
        low = i;
        break;
      }
    }
    int best = 999999999;
    for (int i = (0), _b = (m); i < _b; i++) {
      best = min(best, a[low][i] + solve(mask - (1 << low)));
      best = min(best, c[low][i] + solve(mask ^ (mask & col[low][i])));
    }
    return memo[mask] = best;
  }
}
int main() {
  cin >> n >> m;
  for (int i = (0), _b = (n); i < _b; i++) cin >> s[i];
  for (int i = (0), _b = (n); i < _b; i++)
    for (int j = (0), _b = (m); j < _b; j++) cin >> a[i][j];
  memset(col, 0, sizeof col);
  memset(c, 0, sizeof c);
  for (int i = (0), _b = (n); i < _b; i++)
    for (int j = (0), _b = (m); j < _b; j++) {
      int maxi = 0;
      for (int k = (0), _b = (n); k < _b; k++) {
        if (s[i][j] == s[k][j]) {
          maxi = max(maxi, a[k][j]);
          col[i][j] += (1 << k);
          c[i][j] += a[k][j];
        }
      }
      c[i][j] -= maxi;
    }
  memset(memo, -1, sizeof memo);
  printf("%d\n", solve((1 << n) - 1));
  return 0;
}
void print_array(int* array, int start, int end) {
  printf("[");
  for (int i = (start), _b = (end); i < _b; i++) {
    printf("%d ", array[i]);
  }
  printf("]");
  printf("\n");
}
void print_vector(vector<int> v) {
  printf("[");
  for (int i = (0), _b = (v.size()); i < _b; i++) {
    printf("%d ", v[i]);
  }
  printf("]");
  printf("\n");
}
