#include <bits/stdc++.h>
using namespace std;
map<string, vector<int> > prices;
bool cmp(int a, int b) { return a > b; }
bool isPalindrome(string s) {
  int st = 0, dr = s.size() - 1;
  while (st <= dr) {
    if (s[st] != s[dr]) {
      return 0;
    }
    st++;
    dr--;
  }
  return 1;
}
int main() {
  int n, k;
  cin >> n >> k;
  for (int i = 1; i <= n; ++i) {
    string aux;
    cin >> aux;
    int x;
    cin >> x;
    prices[aux].emplace_back(x);
  }
  int ans = 0, middleAdds = 0;
  int marginBeauty = 0;
  for (const auto it : prices) {
    string key = it.first;
    vector<int> values = it.second;
    sort(values.begin(), values.end(), cmp);
    if (isPalindrome(key)) {
      int pos = values.size();
      int i = 0;
      for (i = 0; i < values.size() - 1; i += 2) {
        if (values[i] + values[i + 1] < 0) {
          break;
        }
        ans += (values[i] + values[i + 1]);
        middleAdds = max(middleAdds, -values[i + 1]);
      }
      for (; i < values.size(); ++i) {
        middleAdds = max(middleAdds, values[i]);
      }
    } else {
      string reversedKey = key;
      reverse(reversedKey.begin(), reversedKey.end());
      if (prices[reversedKey].empty()) continue;
      vector<int> reversedKeyValues = prices[reversedKey];
      sort(reversedKeyValues.begin(), reversedKeyValues.end(), cmp);
      for (int i = 0; i < min(values.size(), reversedKeyValues.size()); ++i) {
        if (values[i] + reversedKeyValues[i] <= 0) {
          break;
        }
        marginBeauty += values[i] + reversedKeyValues[i];
      }
    }
  }
  printf("%d\n", ans + middleAdds + marginBeauty / 2);
  return 0;
}
