#include <bits/stdc++.h>
using namespace std;
int mod = 1000000007;
template <class C>
void mini(C& a, C b) {
  a = min(a, b);
}
template <class C>
void maxi(C& a, C b) {
  a = max(a, b);
}
long long expN(long long b, long long exp) {
  if (exp == 0) return 1;
  long long res = expN(b, exp / 2);
  res *= res;
  if (exp % 2 == 1) res *= b;
  return res;
}
void a() {
  int n;
  long long I;
  cin >> n >> I;
  vector<int> audio(n);
  for (int i = 0; i < n; i++) cin >> audio[i];
  sort(audio.begin(), audio.end());
  long long lim = 8 * I / n;
  lim = expN(2, lim);
  int l = 0;
  int r = 0;
  int distintos = 1;
  int res = n;
  while (r < n and distintos <= lim) {
    r++;
    if (audio[r] != audio[r - 1]) distintos++;
  }
  mini(res, n - r + l);
  while (r < n) {
    l++;
    while (l < n and audio[l] == audio[l - 1]) l++;
    r++;
    while (r < n and audio[r] == audio[r - 1]) r++;
    mini(res, n - r + l);
  }
  cout << res << '\n';
}
struct segmentMax {
  segmentMax(int nn) {
    n = nn;
    tree = vector<int>(2 * n);
  }
  segmentMax(vector<int>& v) {
    n = v.size();
    tree = vector<int>(2 * n);
    for (int i = 0; i < n; i++) {
      tree[i + n] = v[i];
    }
    for (int i = n - 1; i >= 1; i--) {
      tree[i] = max(tree[2 * i], tree[2 * i + 1]);
    }
  }
  int maxr(int a, int b) {
    int res = -1;
    a += n;
    b += n;
    while (a <= b) {
      if (a % 2 == 1) maxi(res, tree[a++]);
      if (b % 2 == 0) maxi(res, tree[b--]);
      a /= 2;
      b /= 2;
    }
    return res;
  }
  void actualizar(int i, int x) {
    i += n;
    tree[i] = x;
    i /= 2;
    while (i >= 1) {
      tree[i] = max(tree[2 * i], tree[2 * i + 1]);
      i /= 2;
    }
  }
  int n;
  vector<int> tree;
};
void b() {
  int aux;
  int p, x;
  int n;
  cin >> n;
  vector<int> A(n + 1);
  for (int(i) = 1; i <= n; i++) cin >> A[i];
  int q;
  cin >> q;
  segmentMax tree(q);
  vector<int> ultimaAcutalizacion(n + 1, 0);
  int t = 0;
  while (q--) {
    cin >> aux;
    if (aux == 1) {
      cin >> p >> x;
      A[p] = x;
      ultimaAcutalizacion[p] = t;
    }
    if (aux == 2) {
      cin >> x;
      tree.actualizar(t, x);
    }
    t++;
  }
  for (int(i) = 1; i <= n; i++) {
    maxi(A[i], tree.maxr(ultimaAcutalizacion[i], t - 1));
  }
  for (int(i) = 1; i <= n; i++) cout << A[i] << ' ';
  cout << endl;
}
void c() {
  int n, m;
  cin >> n >> m;
  vector<pair<int, int> > aristas(m + 1);
  int u, v;
  for (int(i) = 1; i <= m; i++) {
    cin >> u >> v;
    aristas[i] = make_pair(u, v);
  }
  vector<int> matching;
  set<int> nodosQuemados;
  for (int(i) = 1; i <= m; i++) {
    u = aristas[i].first;
    v = aristas[i].second;
    if (nodosQuemados.count(u) == 0 and nodosQuemados.count(v) == 0) {
      nodosQuemados.insert(u);
      nodosQuemados.insert(v);
      matching.push_back(i);
    }
  }
  if (matching.size() >= n) {
    cout << "Matching" << '\n';
    for (int i = 0; i < n; i++) cout << matching[i] << ' ';
    cout << '\n';
  } else {
    int couteados = 0;
    cout << "IndSet\n";
    for (int(i) = 1; i <= 3 * n; i++) {
      if (nodosQuemados.count(i) == 0) {
        cout << i << ' ';
        couteados++;
      }
      if (couteados == n) break;
    }
    cout << '\n';
  }
}
void aa() {
  int n, m;
  cin >> n >> m;
  vector<string> respuestas;
  string aux;
  for (int i = 0; i < n; i++) {
    cin >> aux;
    respuestas.push_back(aux);
  }
  vector<int> puntajes(m);
  for (int i = 0; i < m; i++) cin >> puntajes[i];
  int res = 0;
  for (int i = 0; i < m; i++) {
    vector<int> apariciones(5);
    for (int k = 0; k < n; k++) {
      int r = (int)respuestas[k][i] - (int)'A';
      apariciones[r]++;
    }
    sort(apariciones.begin(), apariciones.end());
    res += apariciones[4] * puntajes[i];
  }
  cout << res << '\n';
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  aa();
  return 0;
}
