#include <bits/stdc++.h>
using namespace std;
const int N = 100005;
int n, k;
char temp[N];
struct str {
  string str;
  int a, i;
  bool isPal;
  bool operator<(const struct str &second) const { return a < second.a; }
} a[N];
map<string, priority_queue<str>> occ;
bool taken[N];
vector<str> oneChar[27];
int main() {
  scanf("%d%d", &k, &n);
  for (int(i) = (1); (i) <= (int)(k); (i)++) {
    int x;
    scanf("%s%d", temp, &x);
    string t = string(temp);
    a[i] = {t, x, i, false};
    occ[t].push(a[i]);
    reverse(t.begin(), t.end());
    a[i].isPal = t == a[i].str;
  }
  long long ans = 0;
  sort(a + 1, a + k + 1);
  for (long long(i) = (k); (i) >= (1); --(i))
    if (!taken[a[i].i]) {
      string rev = a[i].str;
      reverse(rev.begin(), rev.end());
      priority_queue<str> &pq = occ[rev];
      while (!pq.empty() && (taken[pq.top().i] || pq.top().i == a[i].i))
        pq.pop();
      if (pq.empty()) continue;
      if (a[i].a + pq.top().a > 0) {
        ans += a[i].a + pq.top().a;
        taken[a[i].i] = taken[pq.top().i] = true;
        pq.pop();
      }
    }
  int add = 0;
  for (int(i) = (1); (i) <= (int)(k); (i)++)
    if (a[i].isPal) {
      if (!taken[a[i].i])
        add = max(add, a[i].a);
      else
        add = max(add, -a[i].a);
    }
  printf("%lld\n", ans + add);
  return 0;
}
