#include <bits/stdc++.h>
using namespace std;
multiset<int> S0[120000], S1[120000], S2[120000];
int tree[120000][30];
int q[120000];
char c[120000];
int i, j, m, n, o, p, s, t, v, sum_node;
inline int check() {
  for (int i = 1; i <= m; i++) {
    if (c[i] < c[m - i + 1]) return 1;
    if (c[i] > c[m - i + 1]) return -1;
  }
  return 0;
}
int main() {
  scanf("%d%d", &n, &m);
  for (i = 1; i <= n; i++) {
    scanf("%s%d", c + 1, &t);
    v = check();
    if (v == -1)
      for (j = 1; j <= m / 2; j++) swap(c[j], c[m - j + 1]);
    p = 0;
    for (j = 1; j <= m; j++) {
      if (!tree[p][c[j] - 97]) {
        sum_node++;
        tree[p][c[j] - 97] = sum_node;
      }
      p = tree[p][c[j] - 97];
    }
    if (v == 1) S1[p].insert(t);
    if (v == -1) S2[p].insert(t);
    if (v == 0) S0[p].insert(t);
  }
  for (i = 1; i <= sum_node; i++)
    while ((S1[i].size()) && (S2[i].size()) &&
           ((*--S1[i].end()) + (*--S2[i].end()) > 0)) {
      s = s + (*--S1[i].end()) + (*--S2[i].end());
      S1[i].erase(--S1[i].end()), S2[i].erase(--S2[i].end());
    }
  for (i = 1; i <= sum_node; i++) {
    while ((S0[i].size() > 1) && ((*--S0[i].end()) > 0) &&
           ((*-- --S0[i].end()) > 0)) {
      s = s + (*--S0[i].end()) + (*-- --S0[i].end());
      S0[i].erase(--S0[i].end()), S0[i].erase(--S0[i].end());
    }
    if ((S0[i].size() == 1) && ((*--S0[i].end()) > 0))
      s = s + (*--S0[i].end()), o++, q[o] = -(*--S0[i].end());
    if ((S0[i].size() > 1) && ((*--S0[i].end()) > 0))
      s = s + (*--S0[i].end()), o++,
      q[o] = max(-(*--S0[i].end()), (*-- --S0[i].end()));
  }
  sort(q + 1, q + o + 1);
  for (i = 2; i <= o; i++) s = s + q[i];
  printf("%d", s);
  return 0;
}
