#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
char s[maxn];
string str[maxn];
map<string, int> dict;
set<int> tmps;
priority_queue<int> q[maxn], tmpq;
string Reverse(string s) {
  int len = int(s.length()) >> 1;
  for (int i = 0; i < len; ++i) {
    swap(s[i], s[s.length() - i - 1]);
  }
  return s;
}
int main() {
  int k, n, num = 0;
  scanf("%d%d", &k, &n);
  for (int i = 0, v; i < k; ++i) {
    scanf("%s%d", s, &v);
    if (!dict.count(s)) {
      ++num;
      str[num] = s;
      dict[s] = num;
    }
    int id = dict[s];
    q[id].push(v);
  }
  long long ans = 0;
  for (int i = 1; i <= num; ++i) {
    string s_rev = Reverse(str[i]);
    if (s_rev == str[i]) {
      while (q[i].size() >= 2) {
        int vx = q[i].top();
        q[i].pop();
        int vy = q[i].top();
        q[i].pop();
        if (vx + vy > 0) {
          ans += vx + vy;
          if (vy < 0) {
            tmps.insert(vy);
          }
        } else {
          q[i].push(vx);
          q[i].push(vy);
          if (vx > 0) {
            tmpq.push(vx);
          }
          break;
        }
      }
      if (q[i].size() == 1 && q[i].top() > 0) {
        tmpq.push(q[i].top());
      }
    } else if (dict.count(s_rev)) {
      int j = dict[s_rev];
      while (!q[i].empty() && !q[j].empty()) {
        if (q[i].top() + q[j].top() > 0) {
          ans += q[i].top() + q[j].top();
          q[i].pop(), q[j].pop();
        } else {
          break;
        }
      }
    }
  }
  long long tmp = ans;
  if (!tmps.empty()) {
    ans = tmp - *tmps.begin();
  }
  if (!tmpq.empty()) {
    ans = max(ans, tmp + tmpq.top());
  }
  printf("%lld\n", ans);
  return 0;
}
