#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC optimize("no-stack-protector")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("unroll-loops")
using namespace std;
using matrix = vector<vector<long long>>;
struct node {
  node *next[26];
  int id;
  node() {
    fill(next, next + 26, nullptr);
    id = -1;
  }
};
void add(node *&root, string &s, int id) {
  node *cur = root;
  for (int i = 0; i < s.length(); ++i) {
    if (!cur->next[s[i] - 'a']) {
      cur->next[s[i] - 'a'] = new node();
    }
    cur = cur->next[s[i] - 'a'];
  }
  cur->id = id;
}
int findid(node *&root, string &s) {
  node *cur = root;
  for (int i = 0; i < s.length(); ++i) {
    if (!cur->next[s[i] - 'a']) {
      return -1;
    }
    cur = cur->next[s[i] - 'a'];
  }
  return cur->id;
}
const int MAXN = 1e5 + 100;
string str[MAXN], revstr[MAXN];
bool pal[MAXN];
multiset<int> a[MAXN];
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  node *root = new node();
  int k, n, sz = 0;
  cin >> k >> n;
  for (int i = 0; i < k; ++i) {
    string s;
    int x;
    cin >> s >> x;
    int id = findid(root, s);
    if (id == -1) {
      str[sz] = s;
      revstr[sz] = str[sz];
      reverse((revstr[sz]).begin(), (revstr[sz]).end());
      pal[sz] = (str[sz] == revstr[sz]);
      add(root, str[sz], sz);
      id = sz;
      sz++;
    }
    a[id].insert(x);
  }
  vector<pair<int, int>> res;
  int ans = 0;
  for (int i = 0; i < sz; ++i) {
    if (pal[i]) {
      bool flag = false;
      while (a[i].size() > 1) {
        auto it = prev(a[i].end());
        if (*it >= 0 && *prev(it) >= 0) {
          ans += *it + *prev(it);
          a[i].erase(prev(a[i].end()));
          a[i].erase(prev(a[i].end()));
        } else if (*it > 0) {
          res.push_back({*it, max(0, *it + *prev(it))});
          flag = true;
          break;
        } else {
          break;
        }
      }
      if (a[i].size() > 0) {
        auto it = prev(a[i].end());
        if (!flag && *it > 0) {
          res.push_back({*it, 0});
        }
      }
    } else {
      int id = findid(root, revstr[i]);
      if (id == -1) {
        continue;
      }
      while (a[i].size() > 0 && a[id].size() > 0) {
        auto it1 = prev(a[i].end());
        auto it2 = prev(a[id].end());
        if (*it1 + *it2 >= 0) {
          ans += *it1 + *it2;
          a[i].erase(prev(a[i].end()));
          a[id].erase(prev(a[id].end()));
        } else {
          break;
        }
      }
    }
  }
  int sum = 0, mx = 0;
  for (pair<int, int> i : res) {
    sum += i.second;
  }
  for (pair<int, int> i : res) {
    mx = max(mx, i.first + sum - i.second);
  }
  cout << ans + mx;
}
