#include <bits/stdc++.h>
using namespace std;
bool isPalindromic(string &s) {
  int n = (int)s.size();
  for (int i = 0; i < n / 2; ++i)
    if (s[i] != s[n - i - 1]) return false;
  return true;
}
string S[100099];
map<string, vector<pair<int, int>>> sp;
int A[100099], p[100099];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int K, N;
  cin >> K >> N;
  vector<tuple<int, string>> u(K);
  for (int(i) = (0); (i) < (int)(K); ++(i)) {
    cin >> S[i] >> A[i];
    u[i] = make_tuple(A[i], S[i]);
  }
  sort((u).begin(), (u).end(), greater<tuple<int, string>>());
  for (int(i) = (0); (i) < (int)(K); ++(i)) {
    tie(A[i], S[i]) = u[i];
    sp[S[i]].push_back(make_pair(A[i], i));
  }
  for (auto &(q) : (sp)) sort((q.second).begin(), (q.second).end());
  memset((p), (-1), sizeof(p));
  int sm = 0, ans = 0;
  for (int(i) = (0); (i) < (int)(K); ++(i))
    if (p[i] == -1) {
      string t = S[i];
      int a = A[i];
      reverse((t).begin(), (t).end());
      auto &v = sp[t];
      p[i] = -2;
      while ((int)(v).size() && p[v.back().second] != -1) v.pop_back();
      if ((int)(v).size()) {
        int j = sp[t].back().second, b = A[j];
        if (a + b > 0) {
          sm += a + b;
          p[i] = j;
          p[j] = i;
        }
      }
    }
  ans = sm;
  for (int(i) = (0); (i) < (int)(K); ++(i)) {
    if (isPalindromic(S[i]) && A[i] > 0) {
      if (p[i] < 0) {
        (ans) = max((ans), (sm + A[i]));
      } else {
        int j = p[i];
        (ans) = max((ans), (sm - A[j]));
      }
    }
  }
  cout << ans << endl;
}
