#include <bits/stdc++.h>
const long long int INF = 1e9 + 999, MOD = 1e9 + 7, MAXN = 200000;
const long double EPS = 0.000001;
using namespace std;
bool palindrom(string s) {
  bool ok = true;
  for (long long int i = 0; i < (long long int)s.size(); i++) {
    if (s[i] != s[(long long int)s.size() - i - 1]) ok = false;
  }
  return ok;
}
string rev(string s) {
  string ans = "";
  for (long long int i = (long long int)s.size() - 1; i >= 0; i--) {
    ans += s[i];
  }
  return ans;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  long long int m, n, ans = 0;
  cin >> m >> n;
  map<string, long long int> sum;
  map<string, vector<long long int>> fg;
  map<string, long long int> nn;
  set<string> gf;
  for (long long int i = 0; i < m; i++) {
    string s;
    long long int k;
    cin >> s >> k;
    gf.insert(s);
    fg[s].push_back(k);
  }
  for (auto it = gf.begin(); it != gf.end(); it++) {
    string now = *it;
    sort(fg[now].rbegin(), fg[now].rend());
  }
  cout << "\n";
  map<string, long long int> used;
  for (auto it = gf.begin(); it != gf.end(); it++) {
    string now = *it;
    string rnow = rev(now);
    if (used[now] || used[rnow] || palindrom(now)) continue;
    used[now] = 1;
    used[rnow] = 1;
    long long int prib = 0;
    for (long long int i = 0;
         i < min((long long int)fg[now].size(), (long long int)fg[rnow].size());
         i++) {
      if (fg[now][i] + fg[rnow][i] <= 0) break;
      ans += fg[now][i] + fg[rnow][i];
    }
    ans += prib;
  }
  long long int max_dont_take = 0;
  for (auto it = gf.begin(); it != gf.end(); it++) {
    string now = *it;
    if (palindrom(now)) {
      if (fg[now][0] > 0 && (long long int)fg[now].size() == 1)
        max_dont_take = max(max_dont_take, fg[now][0]);
      for (long long int i = 1; i < ((long long int)fg[now].size() / 2) * 2;
           i += 2) {
        if (fg[now][i - 1] + fg[now][i] <= 0) {
          if (fg[now][i - 1] > 0) {
            max_dont_take = max(max_dont_take, fg[now][i - 1]);
          }
          break;
        }
        if (fg[now][i] < 0 && fg[now][i - 1] > 0) {
          max_dont_take = max(max_dont_take, -fg[now][i]);
        }
        ans += fg[now][i - 1] + fg[now][i];
      }
      if ((long long int)fg[now].size() % 2 == 1) {
        if (fg[now][(long long int)fg[now].size() - 1] > 0)
          max_dont_take =
              max(max_dont_take, fg[now][(long long int)fg[now].size() - 1]);
      }
    }
  }
  cout << ans + max_dont_take;
  return 0;
}
