#include<bits/stdc++.h>
#define endl "\n"
using namespace std;
const int MAXN = 1e3+5;
const int MOD = 1e9+7;
const int INF = 2e9;
map< string,vector<int> > UD;
map< string, bool > used;
vector< string > arr;
int main(){
    int N = 0, M = 0, s_part = -INF;
    long long RESULT = 0;
    scanf("%i%i",&N,&M);
    string curS = "";

    for(int i=1, curI = 0;i<=N;i++){
        cin >> curS;
        scanf("%i",&curI);

        if(UD[curS].empty()) arr.push_back(curS);
        UD[curS].push_back(curI);
    }

    for(int i=0;i<arr.size();i++)
        sort(UD[arr[i]].begin(),UD[arr[i]].end());

    string rev = "";
    for(int i=0;i<arr.size();i++){
        if(!UD[arr[i]].empty()){
            for(int j=M-1;j>=0;j--)
                    rev.push_back(arr[i][j]);

            while(!used[arr[i]]){
                int S = UD[arr[i]].size();
                if(S == 0) break;
                if(rev == arr[i]){
                    if(S > 1){
                        int L = UD[arr[i]][S-1], R = UD[arr[i]][S-2];

                        if(R < 0){
                            break;
                        }
                        else{
                            RESULT += L + R;
                            UD[arr[i]].pop_back();
                            UD[arr[i]].pop_back();
                        }

                    }
                    else{
                        s_part = max(s_part,UD[arr[i]].back());
                        used[arr[i]] = true;
                    }
                }
                else{
                    int F = UD[rev].size();
                    if(F){
                        int L = UD[rev][F-1], R = UD[arr[i]][S-1];
                        if(L + R > 0){
                            RESULT += L + R;
                            UD[rev].pop_back();
                            UD[arr[i]].pop_back();
                        }
                        else used[arr[i]] = true;
                    }
                    else used[arr[i]] = true;
                }
            }
            rev.clear();
        }
    }

    for(int i=0;i<arr.size();i++){
        if(!UD[arr[i]].empty()){
            for(int j=M-1;j>=0;j--)
                rev.push_back(arr[i][j]);
            while(!used[arr[i]]){
                int L = UD[arr[i]].size();
                if(L == 0) break;
                if(arr[i] == rev){
                    if(L > 1){
                        int F = UD[arr[i]][L-1], S = UD[arr[i]][L-2];
                        if(F - s_part > F - S){
                            s_part = F;
                            UD[arr[i]].pop_back();
                        }
                        else{
                            RESULT += F + S;
                            UD[arr[i]].pop_back();
                            UD[arr[i]].pop_back();
                        }
                    }
                    else used[arr[i]] = true;
                }
            }
            rev.clear();
        }
    }

    if(s_part < 0) printf("%I64d",RESULT);
    else printf("%I64d",RESULT + s_part);
    return 0;
}


#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false);
    int n,k;
    cin >> n >> k;
    set<pair<pair<string,int>,int>,greater<pair<pair<string,int>,int> > > d;
    for(int i =0;i<n;i++){
        string a;
        int b;
        cin >> a >> b;
        d.insert({{a,b},i});
    }
    long long ans = 0;
    int mx = 0;
    auto i = d.begin();
    while(i!=d.end()) {
        string a = i->first.first;
        string ra = a;
        int be = i->first.second;
        int ind = i->second;
        reverse(ra.begin(),ra.end());
        auto x = d.lower_bound({{ra,INT_MAX},INT_MAX});
        if(x==d.end()) {
            i++;
            continue;
        }
        int ind2 = x->second;
        if(ind2 == ind) x++;
        if(x==d.end()) {
            i++;
            continue;
        }
        string a2 = x->first.first;
        int be2 = x->first.second;
        ind2 = x->second;
        if(ind!=ind2 && ra==a2) {
            if(be+be2 >0) {
                ans+=be+be2;
                if(a==ra  && be <0) mx = max(-be,mx);
                if(a==ra && be2 <0) mx = max(-be2,mx);
                d.erase({{a2,be2},ind2});
                i = d.erase(i);
             }
             else i++;
        }
        else i++;
    }
    for(auto i =d.begin();i!=d.end();i++){
        string a = i->first.first;
        int be = i->first.second;
        string b = a;
        reverse(b.begin(),b.end());
        if(a==b) mx = max(mx,be);
    }
    ans+=mx;
    cout << ans;
    return 0;
}


#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int main()
{
    ios_base::sync_with_stdio(false);
    int n,k;
    cin >> n >> k;
    set<pair<pair<string,int>,int>,greater<pair<pair<string,int>,int> > > d;
    for(int i =0;i<n;i++){
        string a;
        int b;
        cin >> a >> b;
        d.insert({{a,b},i});
    }
    long long ans = 0;
    auto i = d.begin();
    while(i!=d.end()) {
        string a = i->first.first;
        string ra = a;
        int be = i->first.second;
        int ind = i->second;
        reverse(ra.begin(),ra.end());
        auto x = d.lower_bound({{ra,INT_MAX},INT_MAX});
        if(x==d.end()) {
            i++;
            continue;
        }
        int ind2 = x->second;
        if(ind2 == ind) x++;
        if(x==d.end()) {
            i++;
            continue;
        }
        string a2 = x->first.first;
        int be2 = x->first.second;
        ind2 = x->second;
        if(ind!=ind2 && ra==a2) {
            if(be+be2 >0) {
                ans+=be+be2;
                d.erase({{a2,be2},ind2});
                i = d.erase(i);
             }
             else i++;
        }
        else i++;
    }
    int mx = 0;
    for(auto i =d.begin();i!=d.end();i++){
        string a = i->first.first;
        int be = i->first.second;
        string b = a;
        reverse(b.begin(),b.end());
        if(a==b) mx = max(mx,be);
    }
    ans+=mx;
    cout << ans;
    return 0;
}


#include<bits/stdc++.h>
#define pb push_back
//#define mp make_pair
#define ll long long
#define mod 1e9+7
#define tt (*it).second
using namespace std;

int main() {
    int n, k;
    cin>>k>>n;

    map<string, vector<int> > ori, rev, same;

    for(int i = 0; i < k; i++)
    {
        string s;
        int b;
        cin>>s>>b;

        string st = s; reverse(st.begin(), st.end());
        if(st == s)
            same[st].pb(b);
        else
        {
            if(ori[s].size() > 0)
            {
                ori[s].push_back(b);
                //cout<<"a";
            }
            else if(ori[st].size() > 0)
                rev[s].pb(b); //cout<<"b"; }
            else
                ori[s].pb(b); //cout<<"c"; }
        }
    }

    for(auto it = ori.begin(); it != ori.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());
    }

    for(auto it = rev.begin(); it != rev.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());\
    }

    int tb = 0;

    for(auto it = same.begin(); it != same.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());
    }

//    for(auto it = ori.begin(); it != ori.end(); it++)
//        cout<<(*it).second.size()<<" ";

    for(auto it = ori.begin(); it != ori.end(); it++)
    {
        string s = (*it).first;
        reverse(s.begin(), s.end());

        vector<int> t1 = (*it).second, t2 = rev[s];
        int i = 0;

        while(i < t1.size() && i < t2.size() && t1[i] + t2[i] > 0)
        {
            tb += t1[i] + t2[i];
           // cout<<t1[i]<<" "<<t2[i];
            i++;
        }
//        cout<<(*it).first<<" ";
    }
    //cout<<tb<<" ";

    for(auto it = same.begin(); it != same.end(); it++)
    {
        int i = 0;
        while(i < tt.size() && tt[i] >= 0)
            i++;
        int j = tt.size()-1;

        while(i < tt.size() && i < j)
        {
            swap(tt[i], tt[j]);
            i++; j--;
        }
    }

    vector<int> vec[same.size()]; int st = 0;

    for(auto it = same.begin(); it != same.end(); it++, st++)
    {
        vector<int> t = (*it).second;
        int i = 0, j = t.size() - 1;
        int sum = 0;

        while(i < j && t[i] + t[j] > 0)
        {
            sum += t[i] + t[j];
            i++; j--;
        }

        while(i+1 <= j && t[i] + t[i+1] > 0)
        {
            sum += t[i] + t[i+1]; i += 2;
        }

        vec[st].push_back(sum);
        //cout<<sum<<" ";

        for(i = 0, j = t.size() - 1; i < t.size() && (t[i] + t[j]> 0) && i != j; i++, j--)
            vec[st].pb(sum - t[j]);

        for(; i+1 <= j && t[i] + t[i+1] > 0; i += 2);

        if(i < t.size() && t[i] > 0)
            vec[st].pb(sum + t[i]);
    }

    int sum = 0;
    for(int i = 0; i < same.size(); i++)
        sum += vec[i][0];

    int tot = 0;

    for(int i = 0 ; i < same.size(); i++)
    {
        for(int j = 0; j < vec[i].size(); j++)
        {
            tot = max(tot, sum - vec[i][0] + vec[i][j]);
            cout<<vec[i][j]<<" ";
        }
    }
    cout<<tb+tot;

}


#include<bits/stdc++.h>
#define pb push_back
//#define mp make_pair
#define ll long long
#define mod 1e9+7
#define tt (*it).second
using namespace std;

int main() {
    int n, k;
    cin>>k>>n;

    map<string, vector<int> > ori, rev, same;

    for(int i = 0; i < k; i++)
    {
        string s;
        int b;
        cin>>s>>b;

        string st = s; reverse(st.begin(), st.end());
        if(st == s)
            same[st].pb(b);
        else
        {
            if(ori[s].size() > 0)
            {
                ori[s].push_back(b);
                //cout<<"a";
            }
            else if(ori[st].size() > 0)
                rev[s].pb(b); //cout<<"b"; }
            else
                ori[s].pb(b); //cout<<"c"; }
        }
    }

    for(auto it = ori.begin(); it != ori.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());
    }

    for(auto it = rev.begin(); it != rev.end(); it++)
        sort(((*it).second).begin(), ((*it).second).end());

    int tb = 0;

    for(auto it = same.begin(); it != same.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());
    }

//    for(auto it = ori.begin(); it != ori.end(); it++)
//        cout<<(*it).second.size()<<" ";

    for(auto it = ori.begin(); it != ori.end(); it++)
    {
        string s = (*it).first;
        reverse(s.begin(), s.end());

        vector<int> t1 = (*it).second, t2 = rev[s];
        int i = 0;

        while(i < t1.size() && i < t2.size() && t1[i] + t2[i] > 0)
        {
            tb += t1[i] + t2[i];
           // cout<<t1[i]<<" "<<t2[i];
            i++;
        }
//        cout<<(*it).first<<" ";
    }
    //cout<<tb<<" ";
    for(auto it = same.begin(); it != same.end(); it++)
    {
        int i = 0;
        while(tt[i] >= 0)
            i++;
        int j = tt.size()-1;

        while(i < j)
        {
            swap(tt[i], tt[j]);
            i++; j--;
        }
    }

    vector<int> vec[same.size()]; int st = 0;

    for(auto it = same.begin(); it != same.end(); it++, st++)
    {
        vector<int> t = (*it).second;
        int i = 0, j = t.size() - 1;
        int sum = 0;

        while(i < j && t[i] + t[j] > 0)
        {
            sum += t[i] + t[j];
            i++; j--;
        }
        vec[st].push_back(sum);
        //cout<<sum<<" ";
        for(i = 0, j = t.size() - 1; i < t.size() && (t[i] > 0); i++, j--)
        {
            if(i == j || t[i] + t[j] <= 0)
                vec[st].pb(sum + t[i]);
            else if(t[i] + t[j] > 0)
                vec[st].pb(sum - t[j]);
        }
    }

    int sum = 0;
    for(int i = 0; i < same.size(); i++)
        sum += vec[i][0];

    int tot = 0;

    for(int i = 0 ; i < same.size(); i++)
    {
        for(int j = 0; j < vec[i].size(); j++)
            tot = max(tot, sum - vec[i][0] + vec[i][j]);
    }
    cout<<tb+tot;
}


#include<bits/stdc++.h>
#define pb push_back
//#define mp make_pair
#define ll long long
#define mod 1e9+7
#define tt (*it).second
using namespace std;

int main() {
    int n, k;
    cin>>k>>n;

    map<string, vector<int> > ori, rev, same;

    for(int i = 0; i < k; i++)
    {
        string s;
        int b;
        cin>>s>>b;

        string st = s; reverse(st.begin(), st.end());
        if(st == s)
            same[st].pb(b);
        else
        {
            if(ori[s].size() > 0)
            {
                ori[s].push_back(b);
                //cout<<"a";
            }
            else if(ori[st].size() > 0)
                rev[s].pb(b); //cout<<"b"; }
            else
                ori[s].pb(b); //cout<<"c"; }
        }
    }

    for(auto it = ori.begin(); it != ori.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());
    }

    for(auto it = rev.begin(); it != rev.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());\
    }

    int tb = 0;

    for(auto it = same.begin(); it != same.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());
    }

//    for(auto it = ori.begin(); it != ori.end(); it++)
//        cout<<(*it).second.size()<<" ";

    for(auto it = ori.begin(); it != ori.end(); it++)
    {
        string s = (*it).first;
        reverse(s.begin(), s.end());

        vector<int> t1 = (*it).second, t2 = rev[s];
        int i = 0;

        while(i < t1.size() && i < t2.size() && t1[i] + t2[i] > 0)
        {
            tb += t1[i] + t2[i];
           // cout<<t1[i]<<" "<<t2[i];
            i++;
        }
//        cout<<(*it).first<<" ";
    }
    //cout<<tb<<" ";

    for(auto it = same.begin(); it != same.end(); it++)
    {
        int i = 0;
        while(i < tt.size() && tt[i] >= 0)
            i++;
        int j = tt.size()-1;

        while(i < tt.size() && i < j)
        {
            swap(tt[i], tt[j]);
            i++; j--;
        }
    }

    vector<int> vec[same.size()]; int st = 0;

    for(auto it = same.begin(); it != same.end(); it++, st++)
    {
        vector<int> t = (*it).second;
        int i = 0, j = t.size() - 1;
        int sum = 0;

        while(i < j && t[i] + t[j] > 0)
        {
            sum += t[i] + t[j];
            i++; j--;
        }

        while(i+1 <= j && t[i] + t[i+1] > 0)
        {
            sum += t[i] + t[i+1]; i += 2;
        }

        vec[st].push_back(sum);
        //cout<<sum<<" ";

        for(i = 0, j = t.size() - 1; i < t.size() && (t[i] + t[j]> 0) && i != j; i++, j--)
            vec[st].pb(sum - t[j]);

        for(; i+1 <= j && t[i] + t[i+1] > 0; i += 2);

        if(i < t.size() && t[i] > 0)
            vec[st].pb(sum + t[i]);
    }

    int sum = 0;
    for(int i = 0; i < same.size(); i++)
        sum += vec[i][0];

    int tot = 0;

    for(int i = 0 ; i < same.size(); i++)
    {
        for(int j = 0; j < vec[i].size(); j++)
        {
            tot = max(tot, sum - vec[i][0] + vec[i][j]);
            //cout<<vec[i][j]<<" ";
        }
    }
    cout<<tb+tot;

}


#include<bits/stdc++.h>
#define pb push_back
//#define mp make_pair
#define ll long long
#define mod 1e9+7
#define tt (*it).second
using namespace std;

int main() {
    int n, k;
    cin>>k>>n;

    map<string, vector<int> > ori, rev, same;

    for(int i = 0; i < k; i++)
    {
        string s;
        int b;
        cin>>s>>b;

        string st = s; reverse(st.begin(), st.end());
        if(st == s)
            same[st].pb(b);
        else
        {
            if(ori[s].size() > 0)
            {
                ori[s].push_back(b);
                //cout<<"a";
            }
            else if(ori[st].size() > 0)
                rev[s].pb(b); //cout<<"b"; }
            else
                ori[s].pb(b); //cout<<"c"; }
        }
    }

    for(auto it = ori.begin(); it != ori.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());
    }

    for(auto it = rev.begin(); it != rev.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());\
    }

    int tb = 0;

    for(auto it = same.begin(); it != same.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());
    }

//    for(auto it = ori.begin(); it != ori.end(); it++)
//        cout<<(*it).second.size()<<" ";

    for(auto it = ori.begin(); it != ori.end(); it++)
    {
        string s = (*it).first;
        reverse(s.begin(), s.end());

        vector<int> t1 = (*it).second, t2 = rev[s];
        int i = 0;

        while(i < t1.size() && i < t2.size() && t1[i] + t2[i] > 0)
        {
            tb += t1[i] + t2[i];
           // cout<<t1[i]<<" "<<t2[i];
            i++;
        }
//        cout<<(*it).first<<" ";
    }
    //cout<<tb<<" ";

    for(auto it = same.begin(); it != same.end(); it++)
    {
        int i = 0;
        while(i < tt.size() && tt[i] >= 0)
            i++;
        int j = tt.size()-1;

        while(i < tt.size() && i < j)
        {
            swap(tt[i], tt[j]);
            i++; j--;
        }
    }

    vector<int> vec[same.size()]; int st = 0;

    for(auto it = same.begin(); it != same.end(); it++, st++)
    {
        vector<int> t = (*it).second;
        int i = 0, j = t.size() - 1;
        int sum = 0;

        while(i < j && t[i] + t[j] > 0)
        {
            sum += t[i] + t[j];
            i++; j--;
        }

        while(i+1 < tt.size() && t[i] + t[i+1] > 0)
        {
            sum += t[i] + t[i+1]; i += 2;
        }

        vec[st].push_back(sum);
        //cout<<sum<<" ";
        for(i = 0, j = t.size() - 1; i < t.size() && (t[i] + t[j]> 0); i++, j--)
            vec[st].pb(sum - t[j]);

        for(; i+1 < t.size() && t[i] + t[i+1] > 0; i += 2);

        if(i < t.size() && t[i] > 0)
            vec[st].pb(sum + t[i]);
    }

    int sum = 0;
    for(int i = 0; i < same.size(); i++)
        sum += vec[i][0];

    int tot = 0;

    for(int i = 0 ; i < same.size(); i++)
    {
        for(int j = 0; j < vec[i].size(); j++)
            tot = max(tot, sum - vec[i][0] + vec[i][j]);
    }
    cout<<tb+tot;

}


#include<bits/stdc++.h>
#define pb push_back
//#define mp make_pair
#define ll long long
#define mod 1e9+7
#define tt (*it).second
using namespace std;

int main() {
    int n, k;
    cin>>k>>n;

    map<string, vector<int> > ori, rev, same;

    for(int i = 0; i < k; i++)
    {
        string s;
        int b;
        cin>>s>>b;

        string st = s; reverse(st.begin(), st.end());
        if(st == s)
            same[st].pb(b);
        else
        {
            if(ori[s].size() > 0)
            {
                ori[s].push_back(b);
                //cout<<"a";
            }
            else if(ori[st].size() > 0)
                rev[s].pb(b); //cout<<"b"; }
            else
                ori[s].pb(b); //cout<<"c"; }
        }
    }

    for(auto it = ori.begin(); it != ori.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());
    }

    for(auto it = rev.begin(); it != rev.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());\
    }

    int tb = 0;

    for(auto it = same.begin(); it != same.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());
    }

//    for(auto it = ori.begin(); it != ori.end(); it++)
//        cout<<(*it).second.size()<<" ";

    for(auto it = ori.begin(); it != ori.end(); it++)
    {
        string s = (*it).first;
        reverse(s.begin(), s.end());

        vector<int> t1 = (*it).second, t2 = rev[s];
        int i = 0;

        while(i < t1.size() && i < t2.size() && t1[i] + t2[i] > 0)
        {
            tb += t1[i] + t2[i];
           // cout<<t1[i]<<" "<<t2[i];
            i++;
        }
//        cout<<(*it).first<<" ";
    }
    //cout<<tb<<" ";

    for(auto it = same.begin(); it != same.end(); it++)
    {
        int i = 0;
        while(i < tt.size() && tt[i] >= 0)
            i++;
        int j = tt.size()-1;

        while(i < tt.size() && i < j)
        {
            swap(tt[i], tt[j]);
            i++; j--;
        }
    }

    vector<int> vec[same.size()]; int st = 0;

    for(auto it = same.begin(); it != same.end(); it++, st++)
    {
        vector<int> t = (*it).second;
        int i = 0, j = t.size() - 1;
        int sum = 0;

        while(i+1 < t.size() && t[i] > 0 && t[i+1] >= 0)
        {
            tb += t[i] + t[i+1]; i+=2;
        }

        if(i < t.size()&& i != j && t[i] + t[j] > 0)
            vec[st].push_back(t[i] + t[j]);
        else
            vec[st].pb(0);

        if(i < t.size()&& t[i] > 0)
            vec[st].pb(t[i]);
    }

    int sum = 0;

    for(int i = 0; i < same.size(); i++)
    {
        sum += vec[i][0];
        //cout<<vec[i][0]<<" "<<vec[i][1]<<" "<<vec[i].size()<<"\n";

    }
    int tot = sum;
    for(int i = 0; i < same.size() ; i++)
    {
        if(vec[i].size() > 1)
            tot = max(tot, sum - vec[i][0] + vec[i][1]);
    }

    cout<<tb+tot;

}


#include<bits/stdc++.h>
#define pb push_back
//#define mp make_pair
#define ll long long
#define mod 1e9+7
#define tt (*it).second
using namespace std;

int main() {
    int n, k;
    cin>>k>>n;

    map<string, vector<int> > ori, rev, same;

    for(int i = 0; i < k; i++)
    {
        string s;
        int b;
        cin>>s>>b;

        string st = s; reverse(st.begin(), st.end());
        if(st == s)
            same[st].pb(b);
        else
        {
            if(ori[s].size() > 0)
            {
                ori[s].push_back(b);
                //cout<<"a";
            }
            else if(ori[st].size() > 0)
                rev[s].pb(b); //cout<<"b"; }
            else
                ori[s].pb(b); //cout<<"c"; }
        }
    }

    for(auto it = ori.begin(); it != ori.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());
    }

    for(auto it = rev.begin(); it != rev.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());\
    }

    int tb = 0;

    for(auto it = same.begin(); it != same.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());
    }

//    for(auto it = ori.begin(); it != ori.end(); it++)
//        cout<<(*it).second.size()<<" ";

    for(auto it = ori.begin(); it != ori.end(); it++)
    {
        string s = (*it).first;
        reverse(s.begin(), s.end());

        vector<int> t1 = (*it).second, t2 = rev[s];
        int i = 0;

        while(i < t1.size() && i < t2.size() && t1[i] + t2[i] > 0)
        {
            tb += t1[i] + t2[i];
           // cout<<t1[i]<<" "<<t2[i];
            i++;
        }
//        cout<<(*it).first<<" ";
    }
    //cout<<tb<<" ";

    for(auto it = same.begin(); it != same.end(); it++)
    {
        int i = 0;
        while(i < tt.size() && tt[i] >= 0)
            i++;
        int j = tt.size()-1;

        while(i < tt.size() && i < j)
        {
            swap(tt[i], tt[j]);
            i++; j--;
        }
    }

    vector<int> vec[same.size()]; int st = 0;

    for(auto it = same.begin(); it != same.end(); it++, st++)
    {
        vector<int> t = (*it).second;
        int i = 0, j = t.size() - 1;
        int sum = 0;

        while(i+1 < t.size() && t[i] > 0 && t[i+1] >= 0)
        {
            tb += t[i] + t[i+1]; i+=2;
        }

        if(i < t.size()&& i != j && t[i] + t[j] > 0)
            vec[st].push_back(t[i] + t[j]);
        else
            vec[st].pb(0);

        if(i < t.size()&& t[i] > 0)
            vec[st].pb(t[i]);
    }

    int sum = 0, tot = 0;

    for(int i = 0; i < same.size(); i++)
    {
        sum += vec[i][0];
    //    cout<<vec[i][0]<<" "<<vec[i][1]<<"\n";
    }

    for(int i = 0; i < same.size() && vec[i].size() > 1; i++)
        tot = max(tot, sum - vec[i][0] + vec[i][1]);

    cout<<tb+tot;

}


#include<bits/stdc++.h>
#define pb push_back
//#define mp make_pair
#define ll long long
#define mod 1e9+7
#define tt (*it).second
using namespace std;

int main() {
    int n, k;
    cin>>k>>n;

    map<string, vector<int> > ori, rev, same;

    for(int i = 0; i < k; i++)
    {
        string s;
        int b;
        cin>>s>>b;

        string st = s; reverse(st.begin(), st.end());
        if(st == s)
            same[st].pb(b);
        else
        {
            if(ori[s].size() > 0)
            {
                ori[s].push_back(b);
                //cout<<"a";
            }
            else if(ori[st].size() > 0)
                rev[s].pb(b); //cout<<"b"; }
            else
                ori[s].pb(b); //cout<<"c"; }
        }
    }

    for(auto it = ori.begin(); it != ori.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());
    }

    for(auto it = rev.begin(); it != rev.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());\
    }

    int tb = 0;

    for(auto it = same.begin(); it != same.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());
    }

//    for(auto it = ori.begin(); it != ori.end(); it++)
//        cout<<(*it).second.size()<<" ";

    for(auto it = ori.begin(); it != ori.end(); it++)
    {
        string s = (*it).first;
        reverse(s.begin(), s.end());

        vector<int> t1 = (*it).second, t2 = rev[s];
        int i = 0;

        while(i < t1.size() && i < t2.size() && t1[i] + t2[i] > 0)
        {
            tb += t1[i] + t2[i];
           // cout<<t1[i]<<" "<<t2[i];
            i++;
        }
//        cout<<(*it).first<<" ";
    }
    //cout<<tb<<" ";

    for(auto it = same.begin(); it != same.end(); it++)
    {
        int i = 0;
        while(i < tt.size() && tt[i] >= 0)
            i++;
        int j = tt.size()-1;

        while(i < tt.size() && i < j)
        {
            swap(tt[i], tt[j]);
            i++; j--;
        }
    }

    vector<int> vec[same.size()]; int st = 0;

    for(auto it = same.begin(); it != same.end(); it++, st++)
    {
        vector<int> t = (*it).second;
        int i = 0, j = t.size() - 1;
        int sum = 0;

        while(i+1 < t.size() && t[i] > 0 && t[i+1] >= 0)
        {
            tb += t[i] + t[i+1]; i+=2;
        }

        if(i < t.size()&& i != j && t[i] + t[j] > 0)
            vec[st].push_back(t[i] + t[j]);
        else
            vec[st].pb(0);

        if(i < t.size()&& t[i] > 0)
            vec[st].pb(t[i]);
    }

    int sum = 0;

    for(int i = 0; i < same.size(); i++)
    {
        sum += vec[i][0];
    //    cout<<vec[i][0]<<" "<<vec[i][1]<<"\n";
    }
    int tot = sum;
    for(int i = 0; i < same.size() && vec[i].size() > 1; i++)
        tot = max(tot, sum - vec[i][0] + vec[i][1]);

    cout<<tb+tot;

}


#include<bits/stdc++.h>
#define pb push_back
//#define mp make_pair
#define ll long long
#define mod 1e9+7
#define tt (*it).second
using namespace std;

int main() {
    int n, k;
    cin>>k>>n;

    map<string, vector<int> > ori, rev, same;

    for(int i = 0; i < k; i++)
    {
        string s;
        int b;
        cin>>s>>b;

        string st = s; reverse(st.begin(), st.end());
        if(st == s)
            same[st].pb(b);
        else
        {
            if(ori[s].size() > 0)
            {
                ori[s].push_back(b);
                //cout<<"a";
            }
            else if(ori[st].size() > 0)
                rev[s].pb(b); //cout<<"b"; }
            else
                ori[s].pb(b); //cout<<"c"; }
        }
    }

    for(auto it = ori.begin(); it != ori.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());
    }

    for(auto it = rev.begin(); it != rev.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());\
    }

    int tb = 0;

    for(auto it = same.begin(); it != same.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());
    }

//    for(auto it = ori.begin(); it != ori.end(); it++)
//        cout<<(*it).second.size()<<" ";

    for(auto it = ori.begin(); it != ori.end(); it++)
    {
        string s = (*it).first;
        reverse(s.begin(), s.end());

        vector<int> t1 = (*it).second, t2 = rev[s];
        int i = 0;

        while(i < t1.size() && i < t2.size() && t1[i] + t2[i] > 0)
        {
            tb += t1[i] + t2[i];
           // cout<<t1[i]<<" "<<t2[i];
            i++;
        }
//        cout<<(*it).first<<" ";
    }
    //cout<<tb<<" ";
    for(auto it = same.begin(); it != same.end(); it++)
    {
        int i = 0;
        while(tt[i] >= 0)
            i++;
        int j = tt.size()-1;

        while(i < j)
        {
            swap(tt[i], tt[j]);
            i++; j--;
        }
    }

    vector<int> vec[same.size()]; int st = 0;

    for(auto it = same.begin(); it != same.end(); it++, st++)
    {
        vector<int> t = (*it).second;
        int i = 0, j = t.size() - 1;
        int sum = 0;

        while(i < j && t[i] + t[j] > 0)
        {
            sum += t[i] + t[j];
            i++; j--;
        }
        vec[st].push_back(sum);
        //cout<<sum<<" ";
        for(i = 0, j = t.size() - 1; i < t.size() && (t[i] > 0); i++, j--)
        {
            if(i == j || t[i] + t[j] <= 0)
                vec[st].pb(sum + t[i]);
            else if(t[i] + t[j] > 0)
                vec[st].pb(sum - t[j]);
        }
    }

    int sum = 0;
    for(int i = 0; i < same.size(); i++)
        sum += vec[i][0];

    int tot = 0;

    for(int i = 0 ; i < same.size(); i++)
    {
        for(int j = 0; j < vec[i].size(); j++)
            tot = max(tot, sum - vec[i][0] + vec[i][j]);
    }
    cout<<tb+tot;
}


#include<bits/stdc++.h>
#define pb push_back
//#define mp make_pair
#define ll long long
#define mod 1e9+7
#define tt (*it).second
using namespace std;

int main() {
    int n, k;
    cin>>k>>n;

    map<string, vector<int> > ori, rev, same;

    for(int i = 0; i < k; i++)
    {
        string s;
        int b;
        cin>>s>>b;

        string st = s; reverse(st.begin(), st.end());
        if(st == s)
            same[st].pb(b);
        else
        {
            if(ori[s].size() > 0)
            {
                ori[s].push_back(b);
                //cout<<"a";
            }
            else if(ori[st].size() > 0)
                rev[s].pb(b); //cout<<"b"; }
            else
                ori[s].pb(b); //cout<<"c"; }
        }
    }

    for(auto it = ori.begin(); it != ori.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());
    }

    for(auto it = rev.begin(); it != rev.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());\
    }

    int tb = 0;

    for(auto it = same.begin(); it != same.end(); it++)
    {
        sort(((*it).second).begin(), ((*it).second).end());
        reverse(((*it).second).begin(), ((*it).second).end());
    }

//    for(auto it = ori.begin(); it != ori.end(); it++)
//        cout<<(*it).second.size()<<" ";

    for(auto it = ori.begin(); it != ori.end(); it++)
    {
        string s = (*it).first;
        reverse(s.begin(), s.end());

        vector<int> t1 = (*it).second, t2 = rev[s];
        int i = 0;

        while(i < t1.size() && i < t2.size() && t1[i] + t2[i] > 0)
        {
            tb += t1[i] + t2[i];
           // cout<<t1[i]<<" "<<t2[i];
            i++;
        }
//        cout<<(*it).first<<" ";
    }
    //cout<<tb<<" ";

    for(auto it = same.begin(); it != same.end(); it++)
    {
        int i = 0;
        while(i < tt.size() && tt[i] >= 0)
            i++;
        int j = tt.size()-1;

        while(i < tt.size() && i < j)
        {
            swap(tt[i], tt[j]);
            i++; j--;
        }
    }

    vector<int> vec[same.size()]; int st = 0;

    for(auto it = same.begin(); it != same.end(); it++, st++)
    {
        vector<int> t = (*it).second;
        int i = 0, j = t.size() - 1;
        int sum = 0;

        while(i+1 < t.size() && t[i] > 0 && t[i+1] > 0)
        {
            tb += t[i] + t[i+1]; i+=2;
        }

        if(i < t.size()&& i != j && t[i] + t[j] > 0)
            vec[st].push_back(t[i] + t[j]);
        else
            vec[st].pb(0);

        if(i < t.size()&& t[i] > 0)
            vec[st].pb(t[i]);
    }

    int sum = 0, tot = 0;

    for(int i = 0; i < same.size(); i++)
    {
        sum += vec[i][0];
    //    cout<<vec[i][0]<<" "<<vec[i][1]<<"\n";
    }

    for(int i = 0; i < same.size() && vec[i].size() > 1; i++)
        tot = max(tot, sum - vec[i][0] + vec[i][1]);

    cout<<tb+tot;

}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <string>
#include <time.h>

#define SQR(_x) ((_x)*(_x))
#define NL printf("\n")
#define LL long long
#define DB double
#define PB push_back
#define INF 1<<30
#define LB lower_bound
#define UB upper_bound
#define F front
#define PQ priority_queue

using namespace std;
string temp;
string rev;
int n,k,cc;
long long ans=0;
vector<int> v[100100];
vector< pair<int,int> >par;
struct data
{
	string str;
	int p;
}in[100100],real[100100];

bool cmp (data a, data b)
{

	if(a.str==b.str)
		return a.p<b.p;
	return a.str<b.str;
}
int find(int n)
{
	int l=1,r=cc+1,mid;
	int p;

	while(l<=r)
	{

		mid = (l+r)/2;

		if(rev<real[mid].str)
		{
			r=mid-1;
		}
		if(rev>real[mid].str)
		{
			l=mid+1;
		}
		if(rev==real[mid].str)
		{

			int c1,c2;
			if(n==mid)
			{

				c1=v[n].size()-1;
				c2=v[n].size()-2;
				while(c1>=0 and c2>=0)
				{
					if(v[n][c1]+v[n][c2]>0)
					{

						ans+=v[n][c1]+v[n][c2];
						par.PB(make_pair(v[n][c1],v[n][c2]));
						c1-=2;
						c2-=2;
						if(not v[n].empty()) v[n].pop_back();
						if(not v[n].empty()) v[n].pop_back();
					}
					else break;
				}
			}
			else
			 {

				c1=v[n].size()-1;
				c2=v[mid].size()-1;
				//  printf("%d %d == %s %s\n",n,mid,rev,real[mid].str);
				// printf("%d %d == %d %d\n",c1,c2,v[n][c1],v[mid][c2]);
				while(not v[n].empty() and not v[mid].empty())
				{

					if(v[n][c1]+v[mid][c2]>0)
					{
						ans+=v[n][c1]+v[mid][c2];
						c1--;
						c2--;
						v[n].pop_back();
						v[mid].pop_back();
					}
					else break;
				}
			}
			break;
		}
	}

}
int main()
{
	int p;

	cin >> k >> n;
	for(int i=1;i<=k;i++)
	{
		cin >> in[i].str;
		cin >> in[i].p;
	}
	sort(in+1,in+k+1,cmp);
	for(int i=0;i<k;i++)
	{

		if(in[i].str!=in[i+1].str and i!=k)
		{

			v[++cc].PB(in[i+1].p);
			real[cc].str=in[i+1].str;
		}
		else
		{
			v[cc].PB(in[i+1].p);
		}
	}
	// for(int i=1;i<=cc;i++)
	// {
	// 	cout << "** " << real[i].str << ' ';
	// 	for(int j=0;j<v[i].size();j++)
	// 	{
	// 		printf("%d ",v[i][j]);
	// 	}
	// 	NL;
	// }
	for(int i=1;i<=cc;i++)
	{
		// printf("**** %s\n",real[i].str);
		int c=0;
		rev=real[i].str;
		reverse(rev.begin(),rev.end());
		// c = strcmp(rev,real[i].str);
		// cout << " === " << rev;
		if(rev==real[i].str) real[i].p=1;
		find(i);
	}
	int maxx1=0,sum_maxx=0,maxx2=0;
	for(int i=1;i<=cc;i++)
	{
		for(int j=0;j<v[i].size();j++)
		{
			if(real[i].p==1)
			{
				if(v[i][j]>maxx1)
					maxx1=v[i][j];
			}
		}
	}

	for(int i=0;i<par.size();i++)
	{
		if(par[i].first>par[i].first+par[i].second)
		{
			maxx2=par[i].first;
			sum_maxx=par[i].first+par[i].second;
		}
	}
	if(ans+maxx1>ans-sum_maxx+maxx2 and ans+maxx1 > 0)
	{
		cout << ans+maxx1;
	}
	else if(ans-sum_maxx+maxx2 > 0)
	{
		cout << ans-sum_maxx+maxx2;
	}
	else cout << '0';
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <string>
#include <time.h>

#define SQR(_x) ((_x)*(_x))
#define NL printf("\n")
#define LL long long
#define DB double
#define PB push_back
#define INF 1<<30
#define LB lower_bound
#define UB upper_bound
#define F front
#define PQ priority_queue

using namespace std;
string temp;
string rev;
int n,k,cc;
long long ans=0;
vector<int> v[100100];
vector< pair<int,int> >par;
struct data
{
	string str;
	int p;
}in[100100],real[100100];

bool cmp (data a, data b)
{

	if(a.str==b.str)
		return a.p<b.p;
	return a.str<b.str;
}
int find(int n)
{
	int l=1,r=cc+1,mid;
	int p;

	while(l<=r)
	{

		mid = (l+r)/2;

		if(rev<real[mid].str)
		{
			r=mid-1;
		}
		if(rev>real[mid].str)
		{
			l=mid+1;
		}
		if(rev==real[mid].str)
		{

			int c1,c2;
			if(n==mid)
			{

				c1=v[n].size()-1;
				c2=v[n].size()-2;
				while(c1>=0 and c2>=0)
				{
					if(v[n][c1]+v[n][c2]>0)
					{

						ans+=v[n][c1]+v[n][c2];
						par.PB(make_pair(v[n][c1],v[n][c2]));
						c1-=2;
						c2-=2;
						if(not v[n].empty()) v[n].pop_back();
						if(not v[n].empty()) v[n].pop_back();
					}
					else break;
				}
			}
			else
			 {

				c1=v[n].size()-1;
				c2=v[mid].size()-1;
				//  printf("%d %d == %s %s\n",n,mid,rev,real[mid].str);
				// printf("%d %d == %d %d\n",c1,c2,v[n][c1],v[mid][c2]);
				while(not v[n].empty() and not v[mid].empty())
				{

					if(v[n][c1]+v[mid][c2]>0)
					{
						ans+=v[n][c1]+v[mid][c2];
						c1--;
						c2--;
						v[n].pop_back();
						v[mid].pop_back();
					}
					else break;
				}
			}
			break;
		}
	}

}
int main()
{
	int p;

	cin >> k >> n;
	for(int i=1;i<=k;i++)
	{
		cin >> in[i].str;
		cin >> in[i].p;
	}
	sort(in+1,in+k+1,cmp);
	for(int i=0;i<k;i++)
	{

		if(in[i].str!=in[i+1].str and i!=k)
		{

			v[++cc].PB(in[i+1].p);
			real[cc].str=in[i+1].str;
		}
		else
		{
			v[cc].PB(in[i+1].p);
		}
	}
	// for(int i=1;i<=cc;i++)
	// {
	// 	cout << "** " << real[i].str << ' ';
	// 	for(int j=0;j<v[i].size();j++)
	// 	{
	// 		printf("%d ",v[i][j]);
	// 	}
	// 	NL;
	// }
	for(int i=1;i<=cc;i++)
	{
		// printf("**** %s\n",real[i].str);
		int c=0;
		rev=real[i].str;
		reverse(rev.begin(),rev.end());
		// c = strcmp(rev,real[i].str);
		// cout << " === " << rev;
		if(rev==real[i].str) real[i].p=1;
		find(i);
	}
	int maxx1=0,sum_maxx=0,maxx2=0;
	for(int i=1;i<=cc;i++)
	{
		for(int j=0;j<v[i].size();j++)
		{
			if(real[i].p==1)
			{
				if(v[i][j]>maxx1)
					maxx1=v[i][j];
			}
		}
	}

	for(int i=0;i<par.size();i++)
	{
		if(par[i].first>par[i].first+par[i].second)
		{
			maxx2=par[i].first;
			sum_maxx=par[i].first+par[i].second;
		}
	}
	if(ans+maxx1>ans-sum_maxx+maxx2 and ans+maxx1 > 0)
	{
		cout << ans+maxx1;
	}
	else if(ans+maxx1<ans-sum_maxx+maxx2 and ans-sum_maxx+maxx2 > 0)
	{
		cout << ans-sum_maxx+maxx2;
	}
	else cout << '0';
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <string>
#include <time.h>

#define SQR(_x) ((_x)*(_x))
#define NL printf("\n")
#define LL long long
#define DB double
#define PB push_back
#define INF 1<<30
#define LB lower_bound
#define UB upper_bound
#define F front
#define PQ priority_queue

using namespace std;
string temp;
string rev;
int n,k,cc;
long long ans=0;
vector<int> v[100100];
vector< pair<int,int> >par;
struct data
{
	string str;
	int p;
}in[100100],real[100100];

bool cmp (data a, data b)
{

	if(a.str==b.str)
		return a.p<b.p;
	return a.str<b.str;
}
int find(int n)
{
	int l=1,r=cc+1,mid;
	int p;

	while(l<=r)
	{

		mid = (l+r)/2;

		if(rev<real[mid].str)
		{
			r=mid-1;
		}
		if(rev>real[mid].str)
		{
			l=mid+1;
		}
		if(rev==real[mid].str)
		{

			int c1,c2;
			if(n==mid)
			{

				c1=v[n].size()-1;
				c2=v[n].size()-2;
				while(c1>=0 and c2>=0)
				{
					if(v[n][c1]+v[n][c2]>0)
					{

						ans+=v[n][c1]+v[n][c2];
						par.PB(make_pair(v[n][c1],v[n][c2]));
						c1-=2;
						c2-=2;
						if(not v[n].empty()) v[n].pop_back();
						if(not v[n].empty()) v[n].pop_back();
					}
					else break;
				}
			}
			else
			 {

				c1=v[n].size()-1;
				c2=v[mid].size()-1;
				//  printf("%d %d == %s %s\n",n,mid,rev,real[mid].str);
				// printf("%d %d == %d %d\n",c1,c2,v[n][c1],v[mid][c2]);
				while(not v[n].empty() and not v[mid].empty())
				{

					if(v[n][c1]+v[mid][c2]>0)
					{
						ans+=v[n][c1]+v[mid][c2];
						c1--;
						c2--;
						v[n].pop_back();
						v[mid].pop_back();
					}
					else break;
				}
			}
			break;
		}
	}
	return 0;
}
int main()
{
	int p;

	cin >> k >> n;
	for(int i=1;i<=k;i++)
	{
		cin >> in[i].str;
		cin >> in[i].p;
	}
	sort(in+1,in+k+1,cmp);
	for(int i=0;i<k;i++)
	{
		if(in[i].str!=in[i+1].str and i!=k)
		{
			v[++cc].PB(in[i+1].p);
			real[cc].str=in[i+1].str;
		}
		else
		{
			v[cc].PB(in[i+1].p);
		}
	}
	// for(int i=1;i<=cc;i++)
	// {
	// 	cout << "** " << real[i].str << ' ';
	// 	for(int j=0;j<v[i].size();j++)
	// 	{
	// 		printf("%d ",v[i][j]);
	// 	}
	// 	NL;
	// }
	for(int i=1;i<=cc;i++)
	{
		// printf("**** %s\n",real[i].str);
		int c=0;
		rev=real[i].str;
		reverse(rev.begin(),rev.end());
		// c = strcmp(rev,real[i].str);
		// cout << " === " << rev;
		if(rev==real[i].str) real[i].p=1;
		find(i);
	}
	int maxx1=0,sum_maxx=0,maxx2=0;
	for(int i=1;i<=cc;i++)
	{
		for(int j=0;j<v[i].size();j++)
		{
			if(real[i].p==1)
			{
				if(v[i][j]>maxx1)
					maxx1=v[i][j];
			}
		}
	}
	int t_maxx=0;
	for(int i=0;i<par.size();i++)
	{
		if(par[i].first>par[i].first+par[i].second and -par[i].second > maxx2-sum_maxx)
		{
			maxx2=par[i].first;
			sum_maxx=par[i].first+par[i].second;
		}
	}
	if(ans+maxx1>ans-sum_maxx+maxx2 and ans+maxx1 > 0)
	{
		t_maxx = maxx1;
	}
	else if(ans-sum_maxx+maxx2 > 0)
	{
		t_maxx = maxx2-sum_maxx;
	}
	if(ans+t_maxx > 0) cout << ans+t_maxx;
	else cout << '0';
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <string>
#include <time.h>

#define SQR(_x) ((_x)*(_x))
#define NL printf("\n")
#define LL long long
#define DB double
#define PB push_back
#define INF 1<<30
#define LB lower_bound
#define UB upper_bound
#define F front
#define PQ priority_queue

using namespace std;
char rev[100100],temp[100100];
int n,k,cc;
int ans=0;
vector<int> v[100100];
struct data
{
	char str[1001];
	int p;
}in[1001],real[1001];

bool cmp (data a, data b)
{
	int p = strcmp(a.str,b.str);
	if(p==0)
		return a.p<b.p;
	else if(p<0)
		return 1;
	return 0;
}
int find(int n)
{
	int l=1,r=cc+1,mid;
	int p;

	while(l<r)
	{
		// printf("%d %d\n",l,r);
		mid = (l+r)/2;
		p = strcmp(rev,real[mid].str);

		if(p<0)
		{
			r=mid-1;
		}
		if(p>0)
		{
			l=mid+1;
		}
		if(p==0)
		{

			int c1,c2;
			if(n==mid)
			{
				// printf("==== %s %s\n",real[n].str,rev);
				c1=v[n].size()-1;
				c2=v[n].size()-2;
				while(c1>=0 and c2>=0)
				{
					if(v[n][c1]+v[n][c2]>0)
					{

						ans+=v[n][c1]+v[n][c2];
						c1-=2;
						c2-=2;
						if(not v[n].empty()) v[n].pop_back();
						if(not v[n].empty()) v[n].pop_back();
					}
					else break;
				}
			}
			else
			{
				c1=v[n].size()-1;
				c2=v[mid].size()-1;
				while(not v[n].empty() and not v[mid].empty())
				{
					if(v[n][c1]+v[mid][c2]>0)
					{
						ans+=v[n][c1]+v[mid][c2];
						c1--;
						c2--;
						v[n].pop_back();
						v[mid].pop_back();
					}
					else break;
				}
			}
			break;
		}
	}

}
int main()
{
	int p;

	cin >> k >> n;
	for(int i=1;i<=k;i++)
	{
		scanf("%s",in[i].str);
		cin >> in[i].p;
	}
	sort(in+1,in+k+1,cmp);
	for(int i=0;i<k;i++)
	{
		p=strcmp(in[i].str,in[i+1].str);
		if(p!=0 and i!=k)
		{

			v[++cc].PB(in[i+1].p);
			strcpy(real[cc].str,in[i+1].str);
		}
		else
		{
			v[cc].PB(in[i+1].p);
		}
	}
	// for(int i=1;i<=cc;i++)
	// {
	// 	cout << real[i].str;
	// 	for(int j=0;j<v[i].size();j++)
	// 	{
	// 		printf("%d ",v[i][j]);
	// 	}
	// 	NL;
	// }
	for(int i=1;i<=cc;i++)
	{
		// printf("**** %s\n",real[i].str);
		int c=0;
		strcpy(temp,real[i].str);
		for(int j=n-1;j>=0;j--)
		{
			rev[c++]=temp[j];
		}
		c = strcmp(rev,real[i].str);

		if(c==0) real[i].p=1;
		find(i);
	}
	int maxx=0;
	for(int i=1;i<=cc;i++)
	{
		for(int j=0;j<v[i].size();j++)
		{
			if(real[i].p==1)
			{
				if(v[i][j]>maxx)
					maxx=v[i][j];
			}
		}
	}
	if(ans+maxx > 0) cout << ans+maxx;
	else cout << '0';
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <string>
#include <time.h>

#define SQR(_x) ((_x)*(_x))
#define NL printf("\n")
#define LL long long
#define DB double
#define PB push_back
#define INF 1<<30
#define LB lower_bound
#define UB upper_bound
#define F front
#define PQ priority_queue

using namespace std;
string temp;
string rev;
int n,k,cc;
long long ans=0;
vector<int> v[100100];
vector< pair<int,int> >par;
struct data
{
	string str;
	int p;
}in[100100],real[100100];

bool cmp (data a, data b)
{

	if(a.str==b.str)
		return a.p<b.p;
	return a.str<b.str;
}
int find(int n)
{
	int l=1,r=cc+1,mid;
	int p;

	while(l<=r)
	{

		mid = (l+r)/2;

		if(rev<real[mid].str)
		{
			r=mid-1;
		}
		if(rev>real[mid].str)
		{
			l=mid+1;
		}
		if(rev==real[mid].str)
		{

			int c1,c2;
			if(n==mid)
			{

				c1=v[n].size()-1;
				c2=v[n].size()-2;
				while(c1>=0 and c2>=0)
				{
					if(v[n][c1]+v[n][c2]>0)
					{

						ans+=v[n][c1]+v[n][c2];
						par.PB(make_pair(v[n][c1],v[n][c2]));
						c1-=2;
						c2-=2;
						if(not v[n].empty()) v[n].pop_back();
						if(not v[n].empty()) v[n].pop_back();
					}
					else break;
				}
			}
			else
			 {

				c1=v[n].size()-1;
				c2=v[mid].size()-1;
				//  printf("%d %d == %s %s\n",n,mid,rev,real[mid].str);
				// printf("%d %d == %d %d\n",c1,c2,v[n][c1],v[mid][c2]);
				while(not v[n].empty() and not v[mid].empty())
				{

					if(v[n][c1]+v[mid][c2]>0)
					{
						ans+=v[n][c1]+v[mid][c2];
						c1--;
						c2--;
						v[n].pop_back();
						v[mid].pop_back();
					}
					else break;
				}
			}
			break;
		}
	}

}
int main()
{
	int p;

	cin >> k >> n;
	for(int i=1;i<=k;i++)
	{
		cin >> in[i].str;
		cin >> in[i].p;
	}
	sort(in+1,in+k+1,cmp);
	for(int i=0;i<k;i++)
	{

		if(in[i].str!=in[i+1].str and i!=k)
		{

			v[++cc].PB(in[i+1].p);
			real[cc].str=in[i+1].str;
		}
		else
		{
			v[cc].PB(in[i+1].p);
		}
	}
	// for(int i=1;i<=cc;i++)
	// {
	// 	cout << "** " << real[i].str << ' ';
	// 	for(int j=0;j<v[i].size();j++)
	// 	{
	// 		printf("%d ",v[i][j]);
	// 	}
	// 	NL;
	// }
	for(int i=1;i<=cc;i++)
	{
		// printf("**** %s\n",real[i].str);
		int c=0;
		rev=real[i].str;
		reverse(rev.begin(),rev.end());
		// c = strcmp(rev,real[i].str);
		// cout << " === " << rev;
		if(rev==real[i].str) real[i].p=1;
		find(i);
	}
	int maxx1=0,sum_maxx=0,maxx2=0;
	for(int i=1;i<=cc;i++)
	{
		for(int j=0;j<v[i].size();j++)
		{
			if(real[i].p==1)
			{
				if(v[i][j]>maxx1)
					maxx1=v[i][j];
			}
		}
	}
	int t_maxx=0;
	for(int i=0;i<par.size();i++)
	{
		if(par[i].first>par[i].first+par[i].second)
		{
			maxx2=par[i].first;
			sum_maxx=par[i].first+par[i].second;
		}
	}
	if(ans+maxx1>ans-sum_maxx+maxx2 and ans+maxx1 > 0)
	{
		t_maxx = maxx1;
	}
	else if(ans-sum_maxx+maxx2 > 0)
	{
		t_maxx = maxx2-sum_maxx;
	}
	if(ans+t_maxx > 0) cout << ans+t_maxx;
	else cout << '0';
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <string>
#include <time.h>

#define SQR(_x) ((_x)*(_x))
#define NL printf("\n")
#define LL long long
#define DB double
#define PB push_back
#define INF 1<<30
#define LB lower_bound
#define UB upper_bound
#define F front
#define PQ priority_queue

using namespace std;
char rev[100100],temp[100100];
int n,k,cc;
int ans=0;
vector<int> v[100100];
struct data
{
	char str[1001];
	int p;
}in[1001],real[1001];

bool cmp (data a, data b)
{
	int p = strcmp(a.str,b.str);
	if(p==0)
		return a.p<b.p;
	else if(p<0)
		return 1;
	return 0;
}
int find(int n)
{
	int l=1,r=cc+1,mid;
	int p;

	while(l<=r)
	{

		mid = (l+r)/2;
		p = strcmp(rev,real[mid].str);

		if(p<0)
		{
			r=mid-1;
		}
		if(p>0)
		{
			l=mid+1;
		}
		if(p==0)
		{

			int c1,c2;
			if(n==mid)
			{

				c1=v[n].size()-1;
				c2=v[n].size()-2;
				while(c1>=0 and c2>=0)
				{
					if(v[n][c1]+v[n][c2]>0)
					{

						ans+=v[n][c1]+v[n][c2];
						c1-=2;
						c2-=2;
						if(not v[n].empty()) v[n].pop_back();
						if(not v[n].empty()) v[n].pop_back();
					}
					else break;
				}
			}
			else
			 {

				c1=v[n].size()-1;
				c2=v[mid].size()-1;
				//  printf("%d %d == %s %s\n",n,mid,rev,real[mid].str);
				// printf("%d %d == %d %d\n",c1,c2,v[n][c1],v[mid][c2]);
				while(not v[n].empty() and not v[mid].empty())
				{

					if(v[n][c1]+v[mid][c2]>0)
					{
						ans+=v[n][c1]+v[mid][c2];
						c1--;
						c2--;
						v[n].pop_back();
						v[mid].pop_back();
					}
					else break;
				}
			}
			break;
		}
	}

}
int main()
{
	int p;

	cin >> k >> n;
	for(int i=1;i<=k;i++)
	{
		scanf("%s",in[i].str);
		cin >> in[i].p;
	}
	sort(in+1,in+k+1,cmp);
	for(int i=0;i<k;i++)
	{
		p=strcmp(in[i].str,in[i+1].str);
		if(p!=0 and i!=k)
		{

			v[++cc].PB(in[i+1].p);
			strcpy(real[cc].str,in[i+1].str);
		}
		else
		{
			v[cc].PB(in[i+1].p);
		}
	}
	// for(int i=1;i<=cc;i++)
	// {
	// 	cout << "** " << real[i].str << ' ';
	// 	for(int j=0;j<v[i].size();j++)
	// 	{
	// 		printf("%d ",v[i][j]);
	// 	}
	// 	NL;
	// }
	for(int i=1;i<=cc;i++)
	{
		// printf("**** %s\n",real[i].str);
		int c=0;
		strcpy(temp,real[i].str);
		for(int j=n-1;j>=0;j--)
		{
			rev[c++]=temp[j];
		}
		c = strcmp(rev,real[i].str);

		if(c==0) real[i].p=1;
		find(i);
	}
	int maxx=0;
	for(int i=1;i<=cc;i++)
	{
		for(int j=0;j<v[i].size();j++)
		{
			if(real[i].p==1)
			{

				if(v[i][j]>maxx)
					maxx=v[i][j];
			}
		}
	}
	if(ans+maxx > 0) cout << ans+maxx;
	else cout << '0';
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <string>
#include <time.h>

#define SQR(_x) ((_x)*(_x))
#define NL printf("\n")
#define LL long long
#define DB double
#define PB push_back
#define INF 1<<30
#define LB lower_bound
#define UB upper_bound
#define F front
#define PQ priority_queue

using namespace std;
string temp;
string rev;
int n,k,cc;
long long ans=0;
vector<int> v[100100];
vector< pair<int,int> >par;
struct data
{
	string str;
	int p;
}in[100100],real[100100];

bool cmp (data a, data b)
{

	if(a.str==b.str)
		return a.p<b.p;
	return a.str<b.str;
}
int find(int n)
{
	int l=1,r=cc+1,mid;
	int p;

	while(l<=r)
	{

		mid = (l+r)/2;

		if(rev<real[mid].str)
		{
			r=mid-1;
		}
		if(rev>real[mid].str)
		{
			l=mid+1;
		}
		if(rev==real[mid].str)
		{

			int c1,c2;
			if(n==mid)
			{

				c1=v[n].size()-1;
				c2=v[n].size()-2;
				while(c1>=0 and c2>=0)
				{
					if(v[n][c1]+v[n][c2]>0)
					{

						ans+=v[n][c1]+v[n][c2];
						par.PB(make_pair(v[n][c1],v[n][c2]));
						c1-=2;
						c2-=2;
						if(not v[n].empty()) v[n].pop_back();
						if(not v[n].empty()) v[n].pop_back();
					}
					else break;
				}
			}
			else
			 {

				c1=v[n].size()-1;
				c2=v[mid].size()-1;
				//  printf("%d %d == %s %s\n",n,mid,rev,real[mid].str);
				// printf("%d %d == %d %d\n",c1,c2,v[n][c1],v[mid][c2]);
				while(not v[n].empty() and not v[mid].empty())
				{

					if(v[n][c1]+v[mid][c2]>0)
					{
						ans+=v[n][c1]+v[mid][c2];
						c1--;
						c2--;
						v[n].pop_back();
						v[mid].pop_back();
					}
					else break;
				}
			}
			break;
		}
	}
	return 0;
}
int main()
{
	int p;

	cin >> k >> n;
	for(int i=1;i<=k;i++)
	{
		cin >> in[i].str;
		cin >> in[i].p;
	}
	sort(in+1,in+k+1,cmp);
	for(int i=0;i<k;i++)
	{
		if(in[i].str!=in[i+1].str and i!=k)
		{
			v[++cc].PB(in[i+1].p);
			real[cc].str=in[i+1].str;
		}
		else
		{
			v[cc].PB(in[i+1].p);
		}
	}
	// for(int i=1;i<=cc;i++)
	// {
	// 	cout << "** " << real[i].str << ' ';
	// 	for(int j=0;j<v[i].size();j++)
	// 	{
	// 		printf("%d ",v[i][j]);
	// 	}
	// 	NL;
	// }
	for(int i=1;i<=cc;i++)
	{
		// printf("**** %s\n",real[i].str);
		int c=0;
		rev=real[i].str;
		reverse(rev.begin(),rev.end());
		// c = strcmp(rev,real[i].str);
		// cout << " === " << rev;
		if(rev==real[i].str) real[i].p=1;
		find(i);
	}
	int maxx1=0,sum_maxx=0,maxx2=0;
	for(int i=1;i<=cc;i++)
	{
		for(int j=0;j<v[i].size();j++)
		{
			if(real[i].p==1)
			{
				if(v[i][j]>maxx1)
					maxx1=v[i][j];
			}
		}
	}
	int t_maxx=0;
	for(int i=0;i<par.size();i++)
	{
		if(par[i].first>par[i].first+par[i].second and par[i].first > maxx2)
		{
			maxx2=par[i].first;
			sum_maxx=par[i].first+par[i].second;
		}
	}
	if(ans+maxx1>ans-sum_maxx+maxx2 and ans+maxx1 > 0)
	{
		t_maxx = maxx1;
	}
	else if(ans-sum_maxx+maxx2 > 0)
	{
		t_maxx = maxx2-sum_maxx;
	}
	if(ans+t_maxx > 0) cout << ans+t_maxx;
	else cout << '0';
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <string>
#include <time.h>

#define SQR(_x) ((_x)*(_x))
#define NL printf("\n")
#define LL long long
#define DB double
#define PB push_back
#define INF 1<<30
#define LB lower_bound
#define UB upper_bound
#define F front
#define PQ priority_queue

using namespace std;
char rev[100100],temp[100100];
int n,k,cc;
int ans=0;
vector<int> v[100100];
struct data
{
	char str[100100];
	int p;
}in[1010],real[1010];

bool cmp (data a, data b)
{
	int p = strcmp(a.str,b.str);
	if(p==0)
		return a.p<b.p;
	else if(p<0)
		return 1;
	return 0;
}
int find(int n)
{
	int l=1,r=cc+1,mid;
	int p;

	while(l<=r)
	{

		mid = (l+r)/2;
		p = strcmp(rev,real[mid].str);

		if(p<0)
		{
			r=mid-1;
		}
		if(p>0)
		{
			l=mid+1;
		}
		if(p==0)
		{

			int c1,c2;
			if(n==mid)
			{

				c1=v[n].size()-1;
				c2=v[n].size()-2;
				while(c1>=0 and c2>=0)
				{
					if(v[n][c1]+v[n][c2]>0)
					{

						ans+=v[n][c1]+v[n][c2];
						c1-=2;
						c2-=2;
						if(not v[n].empty()) v[n].pop_back();
						if(not v[n].empty()) v[n].pop_back();
					}
					else break;
				}
			}
			else
			 {

				c1=v[n].size()-1;
				c2=v[mid].size()-1;
				//  printf("%d %d == %s %s\n",n,mid,rev,real[mid].str);
				// printf("%d %d == %d %d\n",c1,c2,v[n][c1],v[mid][c2]);
				while(not v[n].empty() and not v[mid].empty())
				{

					if(v[n][c1]+v[mid][c2]>0)
					{
						ans+=v[n][c1]+v[mid][c2];
						c1--;
						c2--;
						v[n].pop_back();
						v[mid].pop_back();
					}
					else break;
				}
			}
			break;
		}
	}

}
int main()
{
	int p;

	cin >> k >> n;
	for(int i=1;i<=k;i++)
	{
		scanf("%s",in[i].str);
		cin >> in[i].p;
	}
	sort(in+1,in+k+1,cmp);
	for(int i=0;i<k;i++)
	{
		p=strcmp(in[i].str,in[i+1].str);
		if(p!=0 and i!=k)
		{

			v[++cc].PB(in[i+1].p);
			strcpy(real[cc].str,in[i+1].str);
		}
		else
		{
			v[cc].PB(in[i+1].p);
		}
	}
	// for(int i=1;i<=cc;i++)
	// {
	// 	cout << "** " << real[i].str << ' ';
	// 	for(int j=0;j<v[i].size();j++)
	// 	{
	// 		printf("%d ",v[i][j]);
	// 	}
	// 	NL;
	// }
	for(int i=1;i<=cc;i++)
	{
		// printf("**** %s\n",real[i].str);
		int c=0;
		strcpy(temp,real[i].str);
		for(int j=n-1;j>=0;j--)
		{
			rev[c++]=temp[j];
		}
		c = strcmp(rev,real[i].str);

		if(c==0) real[i].p=1;
		find(i);
	}
	int maxx=0;
	for(int i=1;i<=cc;i++)
	{
		for(int j=0;j<v[i].size();j++)
		{
			if(real[i].p==1)
			{

				if(v[i][j]>maxx)
					maxx=v[i][j];
			}
		}
	}
	if(ans+maxx > 0) cout << ans+maxx;
	else cout << '0';
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <string>
#include <time.h>

#define SQR(_x) ((_x)*(_x))
#define NL printf("\n")
#define LL long long
#define DB double
#define PB push_back
#define INF 1<<30
#define LB lower_bound
#define UB upper_bound
#define F front
#define PQ priority_queue

using namespace std;
string temp;
string rev;
int n,k,cc;
long long ans=0;
vector<int> v[100100];
struct data
{
	string str;
	int p;
}in[100100],real[100100];

bool cmp (data a, data b)
{

	if(a.str==b.str)
		return a.p<b.p;
	return a.str<b.str;
}
int find(int n)
{
	int l=1,r=cc+1,mid;
	int p;

	while(l<=r)
	{

		mid = (l+r)/2;

		if(rev<real[mid].str)
		{
			r=mid-1;
		}
		if(rev>real[mid].str)
		{
			l=mid+1;
		}
		if(rev==real[mid].str)
		{

			int c1,c2;
			if(n==mid)
			{

				c1=v[n].size()-1;
				c2=v[n].size()-2;
				while(c1>=0 and c2>=0)
				{
					if(v[n][c1]+v[n][c2]>0)
					{

						ans+=v[n][c1]+v[n][c2];
						c1-=2;
						c2-=2;
						if(not v[n].empty()) v[n].pop_back();
						if(not v[n].empty()) v[n].pop_back();
					}
					else break;
				}
			}
			else
			 {

				c1=v[n].size()-1;
				c2=v[mid].size()-1;
				//  printf("%d %d == %s %s\n",n,mid,rev,real[mid].str);
				// printf("%d %d == %d %d\n",c1,c2,v[n][c1],v[mid][c2]);
				while(not v[n].empty() and not v[mid].empty())
				{

					if(v[n][c1]+v[mid][c2]>0)
					{
						ans+=v[n][c1]+v[mid][c2];
						c1--;
						c2--;
						v[n].pop_back();
						v[mid].pop_back();
					}
					else break;
				}
			}
			break;
		}
	}

}
int main()
{
	int p;

	cin >> k >> n;
	for(int i=1;i<=k;i++)
	{
		cin >> in[i].str;
		cin >> in[i].p;
	}
	sort(in+1,in+k+1,cmp);
	for(int i=0;i<k;i++)
	{

		if(in[i].str!=in[i+1].str and i!=k)
		{

			v[++cc].PB(in[i+1].p);
			real[cc].str=in[i+1].str;
		}
		else
		{
			v[cc].PB(in[i+1].p);
		}
	}
	// for(int i=1;i<=cc;i++)
	// {
	// 	cout << "** " << real[i].str << ' ';
	// 	for(int j=0;j<v[i].size();j++)
	// 	{
	// 		printf("%d ",v[i][j]);
	// 	}
	// 	NL;
	// }
	for(int i=1;i<=cc;i++)
	{
		// printf("**** %s\n",real[i].str);
		int c=0;
		rev=real[i].str;
		reverse(rev.begin(),rev.end());
		// c = strcmp(rev,real[i].str);
		// cout << " === " << rev;
		if(rev==real[i].str) real[i].p=1;
		find(i);
	}
	int maxx=0;
	for(int i=1;i<=cc;i++)
	{
		for(int j=0;j<v[i].size();j++)
		{
			if(real[i].p==1)
			{

				if(v[i][j]>maxx)
					maxx=v[i][j];
			}
		}
	}
	if(ans+maxx > 0) cout << ans+maxx;
	else cout << '0';
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <string>
#include <time.h>

#define SQR(_x) ((_x)*(_x))
#define NL printf("\n")
#define LL long long
#define DB double
#define PB push_back
#define INF 1<<30
#define LB lower_bound
#define UB upper_bound
#define F front
#define PQ priority_queue

using namespace std;
char rev[100100],temp[100100];
int n,k,cc;
int ans=0;
vector<int> v[100100];
struct data
{
	char str[100100];
	int p;
}in[10010],real[10010];

bool cmp (data a, data b)
{
	int p = strcmp(a.str,b.str);
	if(p==0)
		return a.p<b.p;
	else if(p<0)
		return 1;
	return 0;
}
int find(int n)
{
	int l=1,r=cc+1,mid;
	int p;

	while(l<=r)
	{

		mid = (l+r)/2;
		p = strcmp(rev,real[mid].str);

		if(p<0)
		{
			r=mid-1;
		}
		if(p>0)
		{
			l=mid+1;
		}
		if(p==0)
		{

			int c1,c2;
			if(n==mid)
			{

				c1=v[n].size()-1;
				c2=v[n].size()-2;
				while(c1>=0 and c2>=0)
				{
					if(v[n][c1]+v[n][c2]>0)
					{

						ans+=v[n][c1]+v[n][c2];
						c1-=2;
						c2-=2;
						if(not v[n].empty()) v[n].pop_back();
						if(not v[n].empty()) v[n].pop_back();
					}
					else break;
				}
			}
			else
			 {

				c1=v[n].size()-1;
				c2=v[mid].size()-1;
				//  printf("%d %d == %s %s\n",n,mid,rev,real[mid].str);
				// printf("%d %d == %d %d\n",c1,c2,v[n][c1],v[mid][c2]);
				while(not v[n].empty() and not v[mid].empty())
				{

					if(v[n][c1]+v[mid][c2]>0)
					{
						ans+=v[n][c1]+v[mid][c2];
						c1--;
						c2--;
						v[n].pop_back();
						v[mid].pop_back();
					}
					else break;
				}
			}
			break;
		}
	}

}
int main()
{
	int p;

	cin >> k >> n;
	for(int i=1;i<=k;i++)
	{
		scanf("%s",in[i].str);
		cin >> in[i].p;
	}
	sort(in+1,in+k+1,cmp);
	for(int i=0;i<k;i++)
	{
		p=strcmp(in[i].str,in[i+1].str);
		if(p!=0 and i!=k)
		{

			v[++cc].PB(in[i+1].p);
			strcpy(real[cc].str,in[i+1].str);
		}
		else
		{
			v[cc].PB(in[i+1].p);
		}
	}
	// for(int i=1;i<=cc;i++)
	// {
	// 	cout << "** " << real[i].str << ' ';
	// 	for(int j=0;j<v[i].size();j++)
	// 	{
	// 		printf("%d ",v[i][j]);
	// 	}
	// 	NL;
	// }
	for(int i=1;i<=cc;i++)
	{
		// printf("**** %s\n",real[i].str);
		int c=0;
		strcpy(temp,real[i].str);
		for(int j=n-1;j>=0;j--)
		{
			rev[c++]=temp[j];
		}
		c = strcmp(rev,real[i].str);

		if(c==0) real[i].p=1;
		find(i);
	}
	int maxx=0;
	for(int i=1;i<=cc;i++)
	{
		for(int j=0;j<v[i].size();j++)
		{
			if(real[i].p==1)
			{

				if(v[i][j]>maxx)
					maxx=v[i][j];
			}
		}
	}
	if(ans+maxx > 0) cout << ans+maxx;
	else cout << '0';
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <string>
#include <time.h>

#define SQR(_x) ((_x)*(_x))
#define NL printf("\n")
#define LL long long
#define DB double
#define PB push_back
#define INF 1<<30
#define LB lower_bound
#define UB upper_bound
#define F front
#define PQ priority_queue

using namespace std;
string temp;
string rev;
int n,k,cc;
long long ans=0;
vector<int> v[100100];
struct data
{
	string str;
	int p;
}in[100100],real[100100];

bool cmp (data a, data b)
{

	if(a.str==b.str)
		return a.p<b.p;
	return a.str<b.str;
}
int find(int n)
{
	int l=1,r=cc+1,mid;
	int p;

	while(l<=r)
	{

		mid = (l+r)/2;

		if(rev<real[mid].str)
		{
			r=mid-1;
		}
		if(rev>real[mid].str)
		{
			l=mid+1;
		}
		if(rev==real[mid].str)
		{

			int c1,c2;
			if(n==mid)
			{

				c1=v[n].size()-1;
				c2=v[n].size()-2;
				while(c1>=0 and c2>=0)
				{
					if(v[n][c1]+v[n][c2]>0 and v[n][c1]<v[n][c1]+v[n][c2])
					{

						ans+=v[n][c1]+v[n][c2];
						c1-=2;
						c2-=2;
						if(not v[n].empty()) v[n].pop_back();
						if(not v[n].empty()) v[n].pop_back();
					}
					else break;
				}
			}
			else
			 {

				c1=v[n].size()-1;
				c2=v[mid].size()-1;
				//  printf("%d %d == %s %s\n",n,mid,rev,real[mid].str);
				// printf("%d %d == %d %d\n",c1,c2,v[n][c1],v[mid][c2]);
				while(not v[n].empty() and not v[mid].empty())
				{

					if(v[n][c1]+v[mid][c2]>0)
					{
						ans+=v[n][c1]+v[mid][c2];
						c1--;
						c2--;
						v[n].pop_back();
						v[mid].pop_back();
					}
					else break;
				}
			}
			break;
		}
	}

}
int main()
{
	int p;

	cin >> k >> n;
	for(int i=1;i<=k;i++)
	{
		cin >> in[i].str;
		cin >> in[i].p;
	}
	sort(in+1,in+k+1,cmp);
	for(int i=0;i<k;i++)
	{

		if(in[i].str!=in[i+1].str and i!=k)
		{

			v[++cc].PB(in[i+1].p);
			real[cc].str=in[i+1].str;
		}
		else
		{
			v[cc].PB(in[i+1].p);
		}
	}
	// for(int i=1;i<=cc;i++)
	// {
	// 	cout << "** " << real[i].str << ' ';
	// 	for(int j=0;j<v[i].size();j++)
	// 	{
	// 		printf("%d ",v[i][j]);
	// 	}
	// 	NL;
	// }
	for(int i=1;i<=cc;i++)
	{
		// printf("**** %s\n",real[i].str);
		int c=0;
		rev=real[i].str;
		reverse(rev.begin(),rev.end());
		// c = strcmp(rev,real[i].str);
		// cout << " === " << rev;
		if(rev==real[i].str) real[i].p=1;
		find(i);
	}
	int maxx=0;
	for(int i=1;i<=cc;i++)
	{
		for(int j=0;j<v[i].size();j++)
		{
			if(real[i].p==1)
			{
				if(v[i][j]>maxx)
					maxx=v[i][j];
			}
		}
	}
	if(ans+maxx > 0) cout << ans+maxx;
	else cout << '0';
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <string>
#include <time.h>

#define SQR(_x) ((_x)*(_x))
#define NL printf("\n")
#define LL long long
#define DB double
#define PB push_back
#define INF 1<<30
#define LB lower_bound
#define UB upper_bound
#define F front
#define PQ priority_queue

using namespace std;
char rev[100100],temp[100100];
int n,k,cc;
int ans=0;
vector<int> v[100100];
struct data
{
	char str[1100];
	int p;
}in[100100],real[100100];

bool cmp (data a, data b)
{
	int p = strcmp(a.str,b.str);
	if(p==0)
		return a.p<b.p;
	else if(p<0)
		return 1;
	return 0;
}
int find(int n)
{
	int l=1,r=cc+1,mid;
	int p;

	while(l<=r)
	{

		mid = (l+r)/2;
		p = strcmp(rev,real[mid].str);

		if(p<0)
		{
			r=mid-1;
		}
		if(p>0)
		{
			l=mid+1;
		}
		if(p==0)
		{

			int c1,c2;
			if(n==mid)
			{

				c1=v[n].size()-1;
				c2=v[n].size()-2;
				while(c1>=0 and c2>=0)
				{
					if(v[n][c1]+v[n][c2]>0)
					{

						ans+=v[n][c1]+v[n][c2];
						c1-=2;
						c2-=2;
						if(not v[n].empty()) v[n].pop_back();
						if(not v[n].empty()) v[n].pop_back();
					}
					else break;
				}
			}
			else
			 {

				c1=v[n].size()-1;
				c2=v[mid].size()-1;
				//  printf("%d %d == %s %s\n",n,mid,rev,real[mid].str);
				// printf("%d %d == %d %d\n",c1,c2,v[n][c1],v[mid][c2]);
				while(not v[n].empty() and not v[mid].empty())
				{

					if(v[n][c1]+v[mid][c2]>0)
					{
						ans+=v[n][c1]+v[mid][c2];
						c1--;
						c2--;
						v[n].pop_back();
						v[mid].pop_back();
					}
					else break;
				}
			}
			break;
		}
	}

}
int main()
{
	int p;

	cin >> k >> n;
	for(int i=1;i<=k;i++)
	{
		scanf("%s",in[i].str);
		cin >> in[i].p;
	}
	sort(in+1,in+k+1,cmp);
	for(int i=0;i<k;i++)
	{
		p=strcmp(in[i].str,in[i+1].str);
		if(p!=0 and i!=k)
		{

			v[++cc].PB(in[i+1].p);
			strcpy(real[cc].str,in[i+1].str);
		}
		else
		{
			v[cc].PB(in[i+1].p);
		}
	}
	// for(int i=1;i<=cc;i++)
	// {
	// 	cout << "** " << real[i].str << ' ';
	// 	for(int j=0;j<v[i].size();j++)
	// 	{
	// 		printf("%d ",v[i][j]);
	// 	}
	// 	NL;
	// }
	for(int i=1;i<=cc;i++)
	{
		// printf("**** %s\n",real[i].str);
		int c=0;
		strcpy(temp,real[i].str);
		for(int j=n-1;j>=0;j--)
		{
			rev[c++]=temp[j];
		}
		c = strcmp(rev,real[i].str);

		if(c==0) real[i].p=1;
		find(i);
	}
	int maxx=0;
	for(int i=1;i<=cc;i++)
	{
		for(int j=0;j<v[i].size();j++)
		{
			if(real[i].p==1)
			{

				if(v[i][j]>maxx)
					maxx=v[i][j];
			}
		}
	}
	if(ans+maxx > 0) cout << ans+maxx;
	else cout << '0';
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <initializer_list>
#include <functional>
#include <unordered_set>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair <int, int> par;
typedef pair <ll, ll> parll;
int const INF = 1e9 + 7;
ll const LLINF = 1e18 + 7;
ld const eps = 1e-8;
ld const PI = acos(-1);
ll const p_hash = 257;
ll const mod = 1e9 + 9;
bool operator == (par const& a, par const& b) {
	return (a.first == b.first && a.second == b.second);
}
par operator + (par const& a, par const& b) {
	return{ a.first + b.first, a.second + b.second };
}
par operator - (par const& a, par const& b) {
	return{ a.first - b.first, a.second - b.second };
}

inline ll h(string & a) {
	ll res = a[0];
	for (int i = 1; i < a.size(); i++) {
		res *= p_hash;
		res %= mod;
		res += a[i];
		res %= mod;
	}
	return res;
}

inline bool pal(string & a) {
	for (int i = 0; i < a.size() / 2; i++) {
		if (a[i] != a[a.size() - 1 - i]) return false;
	}
	return true;
}

map <ll, vector <int> > str;
map <ll, string> byhash;
map <ll, ll> rev;
map <ll, int> adv;
map <ll, bool> done;

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	ll n, k;
	cin >> k >> n;
	for (int i = 0; i < k; i++) {
		string s; int a;
		cin >> s >> a;
		ll hs = h(s);
		byhash[hs] = s;
		str[hs].push_back(a);
		reverse(s.begin(), s.end());
		rev[hs] = h(s);

	}
	for (auto i = str.begin(); i != str.end(); i++) {
		sort(i->second.begin(), i->second.end());
		reverse(i->second.begin(), i->second.end());
	}
	ll tot = 0;
	int mid = 0;
	for (auto i = str.begin(); i != str.end(); i++) {
		if (done[i->first]) continue;
		int a = 0, b = 0;
		if (!pal(byhash[i->first])) {
			done[i->first] = true;
			done[rev[i->first]] = true;
			vector <int> & v1 = i->second, v2 = str[rev[i->first]];
			while (a < v1.size() && b < v2.size()) {
				if (v1[a] + v2[b] > 0) {
					tot += v1[a] + v2[b];
					if (v1[a] > 0 && v2[b] > 0) adv[i->first] = max(v1[a], v2[b]) - (v1[a] + v2[b]); else adv[i->first] = 0;
					a++;
					b++;
				} else break;
			}
		} else {
			done[i->first] = true;
			vector <int> & v = i->second;
			int a = 0;
			for (; a < v.size(); a += 2) {
				if (a != v.size() - 1 && v[a] + v[a + 1] > 0) {
					tot += v[a] + v[a + 1];
					if (v1[a] > 0 && v2[b] > 0) adv[i->first] = max(v[a], v[a + 1]) - (v[a] + v[a + 1]); else adv[i->first] = 0;
				}
			}
			if (v.size() % 2 && mid < v.back()) mid = v.back();
		}
	}
	ll ans = tot + mid;
	for (auto i = str.begin(); i != str.end(); i++) ans = max(ans, tot + adv[i->first]);
	cout << ans;
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <initializer_list>
#include <functional>
#include <unordered_set>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair <int, int> par;
typedef pair <ll, ll> parll;
int const INF = 1e9 + 7;
ll const LLINF = 1e18 + 7;
ld const eps = 1e-8;
ld const PI = acos(-1);
ll const p_hash = 257;
ll const mod = 1e9 + 9;
bool operator == (par const& a, par const& b) {
	return (a.first == b.first && a.second == b.second);
}
par operator + (par const& a, par const& b) {
	return{ a.first + b.first, a.second + b.second };
}
par operator - (par const& a, par const& b) {
	return{ a.first - b.first, a.second - b.second };
}

inline ll h(string & a) {
	ll res = a[0];
	for (int i = 1; i < a.size(); i++) {
		res *= p_hash;
		res %= mod;
		res += a[i];
		res %= mod;
	}
	return res;
}

inline bool pal(string & a) {
	for (int i = 0; i < a.size() / 2; i++) {
		if (a[i] != a[a.size() - 1 - i]) return false;
	}
	return true;
}

map <ll, vector <int> > str;
map <ll, string> byhash;
map <ll, ll> rev;
//map <ll, int> adv;
map <ll, bool> done;

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	ll n, k;
	cin >> k >> n;
	for (int i = 0; i < k; i++) {
		string s; int a;
		cin >> s >> a;
		ll hs = h(s);
		byhash[hs] = s;
		str[hs].push_back(a);
		reverse(s.begin(), s.end());
		rev[hs] = h(s);
	}
	for (auto i = str.begin(); i != str.end(); i++) {
		sort(i->second.begin(), i->second.end());
		reverse(i->second.begin(), i->second.end());
	}
	ll tot = 0;
	int mid = 0;
	for (auto i = str.begin(); i != str.end(); i++) {
		if (done[i->first]) continue;
		int a = 0, b = 0;
		if (!pal(byhash[i->first])) {
			done[i->first] = true;
			done[rev[i->first]] = true;
			vector <int> & v1 = i->second, v2 = str[rev[i->first]];
			while (a < v1.size() && b < v2.size()) {
				if (v1[a] + v2[b] > 0) {
					tot += v1[a] + v2[b];
					a++;
					b++;
				} else break;
			}
		} else {
			done[i->first] = true;
			vector <int> & v = i->second;
			int a = 0;
			for (; a < v.size(); a += 2) {
				if (a == v.size() - 1) {
					mid = max(mid, v.back());
					break;
				}
				if (v[a] + v[a + 1] > 0) {
				    if (v[a + 1] < 0) mid = max(mid, v[a + 1]);
					tot += v[a] + v[a + 1];
				}
		    }
		}
	}
	ll ans = tot + mid;
//	for (auto i = str.begin(); i != str.end(); i++) ans = max(ans, tot + adv[i->first]);
	cout << ans;
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <initializer_list>
#include <functional>
#include <unordered_set>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair <int, int> par;
typedef pair <ll, ll> parll;
int const INF = 1e9 + 7;
ll const LLINF = 1e18 + 7;
ld const eps = 1e-8;
ld const PI = acos(-1);
ll const p_hash = 257;
ll const mod = 1e9 + 9;
bool operator == (par const& a, par const& b) {
	return (a.first == b.first && a.second == b.second);
}
par operator + (par const& a, par const& b) {
	return{ a.first + b.first, a.second + b.second };
}
par operator - (par const& a, par const& b) {
	return{ a.first - b.first, a.second - b.second };
}

inline ll h(string & a) {
	ll res = a[0];
	for (int i = 1; i < a.size(); i++) {
		res *= p_hash;
		res %= mod;
		res += a[i];
		res %= mod;
	}
	return res;
}

inline bool pal(string & a) {
	for (int i = 0; i < a.size() / 2; i++) {
		if (a[i] != a[a.size() - 1 - i]) return false;
	}
	return true;
}

map <ll, vector <int> > str;
map <ll, string> byhash;
map <ll, ll> rev;
map <ll, bool> done;

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	ll n, k;
	cin >> k >> n;
	for (int i = 0; i < k; i++) {
		string s; int a;
		cin >> s >> a;
		ll hs = h(s);
		byhash[hs] = s;
		str[hs].push_back(a);
		reverse(s.begin(), s.end());
		rev[hs] = h(s);
	}
	for (auto i = str.begin(); i != str.end(); i++) {
		sort(i->second.begin(), i->second.end());
		reverse(i->second.begin(), i->second.end());
	}
	ll tot = 0; int mid = 0;
	for (auto i = str.begin(); i != str.end(); i++) {
		if (done[i->first]) continue;
		int a = 0, b = 0;
		if (!pal(byhash[i->first])) {
			done[i->first] = true;
			done[rev[i->first]] = true;
			vector <int> & v1 = i->second, v2 = str[rev[i->first]];
			while (a < v1.size() && b < v2.size()) {
				if (v1[a] + v2[b] > 0) {
					tot += v1[a] + v2[b];
					a++;
					b++;
				} else break;
			}
		} else {
			done[i->first] = true;
			vector <int> & v = i->second;
			int a = 0;
			for (; a < v.size(); a += 2) {
				if (a + 1 == v.size()) {
					mid = max(mid, v.back());
					break;
				} else if (v[a] + v[a + 1] > 0) {
					tot += v[a] + v[a + 1];
					mid = max(mid, -v[a + 1]);
				}
			}
		}
	}
	cout << tot + mid;
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <initializer_list>
#include <functional>
#include <unordered_set>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair <int, int> par;
typedef pair <ll, ll> parll;
int const INF = 1e9 + 7;
ll const LLINF = 1e18 + 7;
ld const eps = 1e-8;
ld const PI = acos(-1);
ll const p_hash = 257;
ll const mod = 1e9 + 9;
bool operator == (par const& a, par const& b) {
	return (a.first == b.first && a.second == b.second);
}
par operator + (par const& a, par const& b) {
	return{ a.first + b.first, a.second + b.second };
}
par operator - (par const& a, par const& b) {
	return{ a.first - b.first, a.second - b.second };
}

inline ll h(string & a) {
	ll res = a[0];
	for (int i = 1; i < a.size(); i++) {
		res *= p_hash;
		res %= mod;
		res += a[i];
		res %= mod;
	}
	return res;
}

inline bool pal(string & a) {
	for (int i = 0; i < a.size() / 2; i++) {
		if (a[i] != a[a.size() - 1 - i]) return false;
	}
	return true;
}

map <ll, vector <int> > str;
map <ll, string> byhash;
map <ll, ll> rev;
map <ll, int> adv;
map <ll, bool> done;

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	ll n, k;
	cin >> k >> n;
	for (int i = 0; i < k; i++) {
		string s; int a;
		cin >> s >> a;
		ll hs = h(s);
		byhash[hs] = s;
		str[hs].push_back(a);
		reverse(s.begin(), s.end());
		rev[hs] = h(s);

	}
	for (auto i = str.begin(); i != str.end(); i++) {
		sort(i->second.begin(), i->second.end());
		reverse(i->second.begin(), i->second.end());
	}
	ll tot = 0;
	int mid = 0;
	for (auto i = str.begin(); i != str.end(); i++) {
		if (done[i->first]) continue;
		int a = 0, b = 0;
		if (!pal(byhash[i->first])) {
			done[i->first] = true;
			done[rev[i->first]] = true;
			vector <int> & v1 = i->second, v2 = str[rev[i->first]];
			while (a < v1.size() && b < v2.size()) {
				if (v1[a] + v2[b] > 0) {
					tot += v1[a] + v2[b];
					adv[i->first] = max(v1[a], v2[b]) - (v1[a] + v2[b]);
					a++;
					b++;
				} else break;
			}
		} else {
			done[i->first] = true;
			vector <int> & v = i->second;
			int a = 0;
			for (; a < v.size(); a += 2) {
				if (a != v.size() - 1 && v[a] + v[a + 1] > 0) {
					tot += v[a] + v[a + 1];
					adv[i->first] = max(v[a], v[a + 1]) - (v[a] + v[a + 1]);
				}
			}
			if (v.size() % 2 && mid < v.back()) mid = v.back();
		}
	}
	ll ans = tot + mid;
	for (auto i = str.begin(); i != str.end(); i++) ans = max(ans, tot + adv[i->first]);
	cout << ans;
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <initializer_list>
#include <functional>
#include <unordered_set>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair <int, int> par;
typedef pair <ll, ll> parll;
int const INF = 1e9 + 7;
ll const LLINF = 1e18 + 7;
ld const eps = 1e-8;
ld const PI = acos(-1);
ll const p_hash = 257;
ll const mod = 1e9 + 9;
bool operator == (par const& a, par const& b) {
	return (a.first == b.first && a.second == b.second);
}
par operator + (par const& a, par const& b) {
	return{ a.first + b.first, a.second + b.second };
}
par operator - (par const& a, par const& b) {
	return{ a.first - b.first, a.second - b.second };
}

inline ll h(string & a) {
	ll res = a[0];
	for (int i = 1; i < a.size(); i++) {
		res *= p_hash;
		res %= mod;
		res += a[i];
		res %= mod;
	}
	return res;
}

inline bool pal(string & a) {
	for (int i = 0; i < a.size() / 2; i++) {
		if (a[i] != a[a.size() - 1 - i]) return false;
	}
	return true;
}

map <ll, vector <int> > str;
map <ll, string> byhash;
map <ll, ll> rev;
map <ll, bool> done;

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	ll n, k;
	cin >> k >> n;
	for (int i = 0; i < k; i++) {
		string s; int a;
		cin >> s >> a;
		ll hs = h(s);
		byhash[hs] = s;
		str[hs].push_back(a);
		reverse(s.begin(), s.end());
		rev[hs] = h(s);
	}
	for (auto i = str.begin(); i != str.end(); i++) {
		sort(i->second.begin(), i->second.end());
		reverse(i->second.begin(), i->second.end());
	}
	ll tot = 0; int mid = 0;
	for (auto i = str.begin(); i != str.end(); i++) {
		if (done[i->first]) continue;
		int a = 0, b = 0;
		if (!pal(byhash[i->first])) {
			done[i->first] = true;
			done[rev[i->first]] = true;
			vector <int> & v1 = i->second, v2 = str[rev[i->first]];
			while (a < v1.size() && b < v2.size()) {
				if (v1[a] + v2[b] > 0) {
					tot += v1[a] + v2[b];
					a++;
					b++;
				} else break;
			}
		} else {
			done[i->first] = true;
			vector <int> & v = i->second;
			int a = 0;
			while (a < v.size() - 1) {
				if (v[a] + v[a + 1] > 0) {
					tot += v[a] + v[a + 1];
					mid = max(mid, -v[a + 1]);
				} else {
					mid = max(mid, v[a]);
					break;
				}
				a += 2;
			}
			if (a == v.size() - 1) mid = max(mid, v[a]);
		}
	}
	cout << tot + mid;
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <initializer_list>
#include <functional>
#include <unordered_set>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair <int, int> par;
typedef pair <ll, ll> parll;
int const INF = 1e9 + 7;
ll const LLINF = 1e18 + 7;
ld const eps = 1e-8;
ld const PI = acos(-1);
ll const p_hash = 257;
ll const mod = 1e9 + 9;
bool operator == (par const& a, par const& b) {
	return (a.first == b.first && a.second == b.second);
}
par operator + (par const& a, par const& b) {
	return{ a.first + b.first, a.second + b.second };
}
par operator - (par const& a, par const& b) {
	return{ a.first - b.first, a.second - b.second };
}

inline ll h(string & a) {
	ll res = a[0];
	for (int i = 1; i < a.size(); i++) {
		res *= p_hash;
		res %= mod;
		res += a[i];
		res %= mod;
	}
	return res;
}

inline bool pal(string & a) {
	for (int i = 0; i < a.size() / 2; i++) {
		if (a[i] != a[a.size() - 1 - i]) return false;
	}
	return true;
}

map <ll, vector <int> > str;
map <ll, string> byhash;
map <ll, ll> rev;
map <ll, int> adv;
map <ll, bool> done;

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	ll n, k;
	cin >> k >> n;
	for (int i = 0; i < k; i++) {
		string s; int a;
		cin >> s >> a;
		ll hs = h(s);
		byhash[hs] = s;
		str[hs].push_back(a);
		reverse(s.begin(), s.end());
		rev[hs] = h(s);
	}
	for (auto i = str.begin(); i != str.end(); i++) {
		sort(i->second.begin(), i->second.end());
		reverse(i->second.begin(), i->second.end());
	}
	ll tot = 0;
	int mid = 0;
	for (auto i = str.begin(); i != str.end(); i++) {
		if (done[i->first]) continue;
		int a = 0, b = 0;
		if (!pal(byhash[i->first])) {
			done[i->first] = true;
			done[rev[i->first]] = true;
			vector <int> & v1 = i->second, v2 = str[rev[i->first]];
			while (a < v1.size() && b < v2.size()) {
				if (v1[a] + v2[b] > 0) {
					tot += v1[a] + v2[b];
					a++;
					b++;
				} else break;
			}
		} else {
			done[i->first] = true;
			vector <int> & v = i->second;
			int a = 0;
			for (; a < v.size(); a += 2) {
				if (a == v.size() - 1) {
					mid = max(mid, v.back());
					break;
				}
				if (v[a] + v[a + 1] > 0) {
					adv[i->first] = max(adv[i->first], max(v[a], v[a + 1]) - (v[a] + v[a + 1]));
					tot += v[a] + v[a + 1];
				} else {
					mid = max(mid, v.back());
					break;
				}
			}
		}
	}
	ll ans = tot + mid;
	for (auto i = str.begin(); i != str.end(); i++) ans = max(ans, tot + adv[i->first]);
	cout << ans;
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <initializer_list>
#include <functional>
#include <unordered_set>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair <int, int> par;
typedef pair <ll, ll> parll;
int const INF = 1e9 + 7;
ll const LLINF = 1e18 + 7;
ld const eps = 1e-8;
ld const PI = acos(-1);
ll const p_hash = 257;
ll const mod = 1e9 + 9;
bool operator == (par const& a, par const& b) {
	return (a.first == b.first && a.second == b.second);
}
par operator + (par const& a, par const& b) {
	return{ a.first + b.first, a.second + b.second };
}
par operator - (par const& a, par const& b) {
	return{ a.first - b.first, a.second - b.second };
}

inline ll h(string & a) {
	ll res = a[0];
	for (int i = 1; i < a.size(); i++) {
		res *= p_hash;
		res %= mod;
		res += a[i];
		res %= mod;
	}
	return res;
}

inline bool pal(string & a) {
	for (int i = 0; i < a.size() / 2; i++) {
		if (a[i] != a[a.size() - 1 - i]) return false;
	}
	return true;
}

map <ll, vector <int> > str;
map <ll, string> byhash;
map <ll, ll> rev;
map <ll, bool> done;

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	ll n, k;
	cin >> k >> n;
	for (int i = 0; i < k; i++) {
		string s; int a;
		cin >> s >> a;
		ll hs = h(s);
		byhash[hs] = s;
		str[hs].push_back(a);
		reverse(s.begin(), s.end());
		rev[hs] = h(s);
	}
	for (auto i = str.begin(); i != str.end(); i++) {
		sort(i->second.begin(), i->second.end());
		reverse(i->second.begin(), i->second.end());
	}
	ll tot = 0; int mid = 0;
	for (auto i = str.begin(); i != str.end(); i++) {
		if (done[i->first]) continue;
		int a = 0, b = 0;
		if (!pal(byhash[i->first])) {
			done[i->first] = true;
			done[rev[i->first]] = true;
			vector <int> & v1 = i->second, v2 = str[rev[i->first]];
			while (a < v1.size() && b < v2.size()) {
				if (v1[a] + v2[b] > 0) {
					tot += v1[a] + v2[b];
					a++;
					b++;
				} else break;
			}
		} else {
			done[i->first] = true;
			vector <int> & v = i->second;
			int a = 0;
			while (a < v.size() - 1) {
				if (v[a] + v[a + 1] > 0) {
					tot += v[a] + v[a + 1];
					mid = max(mid, -v[a + 1]);
				} else {
					mid = max(mid, v[a]);
					break;
				}
			}
			if (a == v.size() - 1) mid = max(mid, v[a]);
		}
	}
	cout << tot + mid;
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <initializer_list>
#include <functional>
#include <unordered_set>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair <int, int> par;
typedef pair <ll, ll> parll;
int const INF = 1e9 + 7;
ll const LLINF = 1e18 + 7;
ld const eps = 1e-8;
ld const PI = acos(-1);
ll const p_hash = 257;
ll const mod = 1e9 + 9;
bool operator == (par const& a, par const& b) {
	return (a.first == b.first && a.second == b.second);
}
par operator + (par const& a, par const& b) {
	return{ a.first + b.first, a.second + b.second };
}
par operator - (par const& a, par const& b) {
	return{ a.first - b.first, a.second - b.second };
}

inline ll h(string & a) {
	ll res = a[0];
	for (int i = 1; i < a.size(); i++) {
		res *= p_hash;
		res %= mod;
		res += a[i];
		res %= mod;
	}
	return res;
}

inline bool pal(string & a) {
	for (int i = 0; i < a.size() / 2; i++) {
		if (a[i] != a[a.size() - 1 - i]) return false;
	}
	return true;
}

map <ll, vector <int> > str;
map <ll, string> byhash;
map <ll, ll> rev;
map <ll, int> adv;
map <ll, bool> done;

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	ll n, k;
	cin >> k >> n;
	for (int i = 0; i < k; i++) {
		string s; int a;
		cin >> s >> a;
		ll hs = h(s);
		byhash[hs] = s;
		str[hs].push_back(a);
		reverse(s.begin(), s.end());
		rev[hs] = h(s);

	}
	for (auto i = str.begin(); i != str.end(); i++) {
		sort(i->second.begin(), i->second.end());
		reverse(i->second.begin(), i->second.end());
	}
	ll tot = 0;
	int mid = 0;
	for (auto i = str.begin(); i != str.end(); i++) {
		if (done[i->first]) continue;
		int a = 0, b = 0;
		if (!pal(byhash[i->first])) {
			done[i->first] = true;
			done[rev[i->first]] = true;
			vector <int> & v1 = i->second, v2 = str[rev[i->first]];
			while (a < v1.size() && b < v2.size()) {
				if (v1[a] + v2[b] > 0) {
					tot += v1[a] + v2[b];
					if (v1[a] > 0 && v2[b] > 0) adv[i->first] = max(v1[a], v2[b]) - (v1[a] + v2[b]); else adv[i->first] = 0;
					a++;
					b++;
				} else break;
			}
		} else {
			done[i->first] = true;
			vector <int> & v = i->second;
			int a = 0;
			for (; a < v.size(); a += 2) {
				if (a != v.size() - 1 && v[a] + v[a + 1] > 0) {
					tot += v[a] + v[a + 1];
					if (v[a] > 0 && v[a + 1] > 0) adv[i->first] = max(v[a], v[a + 1]) - (v[a] + v[a + 1]); else adv[i->first] = 0;
				}
			}
			if (v.size() % 2 && mid < v.back()) mid = v.back();
		}
	}
	ll ans = tot + mid;
	for (auto i = str.begin(); i != str.end(); i++) ans = max(ans, tot + adv[i->first]);
	cout << ans;
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <initializer_list>
#include <functional>
#include <unordered_set>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair <int, int> par;
typedef pair <ll, ll> parll;
int const INF = 1e9 + 7;
ll const LLINF = 1e18 + 7;
ld const eps = 1e-8;
ld const PI = acos(-1);
ll const p_hash = 257;
ll const mod = 1e9 + 9;
bool operator == (par const& a, par const& b) {
	return (a.first == b.first && a.second == b.second);
}
par operator + (par const& a, par const& b) {
	return{ a.first + b.first, a.second + b.second };
}
par operator - (par const& a, par const& b) {
	return{ a.first - b.first, a.second - b.second };
}

inline ll h(string & a) {
	ll res = a[0];
	for (int i = 1; i < a.size(); i++) {
		res *= p_hash;
		res %= mod;
		res += a[i];
		res %= mod;
	}
	return res;
}

inline bool pal(string & a) {
	for (int i = 0; i < a.size() / 2; i++) {
		if (a[i] != a[a.size() - 1 - i]) return false;
	}
	return true;
}

map <ll, vector <int> > str;
map <ll, string> byhash;
map <ll, ll> rev;
map <ll, int> adv;
map <ll, bool> done;

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	ll n, k;
	cin >> k >> n;
	for (int i = 0; i < k; i++) {
		string s; int a;
		cin >> s >> a;
		ll hs = h(s);
		byhash[hs] = s;
		str[hs].push_back(a);
		reverse(s.begin(), s.end());
		rev[hs] = h(s);

	}
	for (auto i = str.begin(); i != str.end(); i++) {
		sort(i->second.begin(), i->second.end());
		reverse(i->second.begin(), i->second.end());
	}
	ll tot = 0;
	int mid = 0;
	for (auto i = str.begin(); i != str.end(); i++) {
		if (done[i->first]) continue;
		int a = 0, b = 0;
		if (!pal(byhash[i->first])) {
			done[i->first] = true;
			done[rev[i->first]] = true;
			vector <int> & v1 = i->second, v2 = str[rev[i->first]];
			while (a < v1.size() && b < v2.size()) {
				if (v1[a] + v2[b] > 0) {
					tot += v1[a] + v2[b];
					if (v1[a] > 0 && v2[b] > 0) adv[i->first] = max(v1[a], v2[b]) - (v1[a] + v2[b]); else adv[i->first] = 0;
					a++;
					b++;
				} else break;
			}
		} else {
			done[i->first] = true;
			vector <int> & v = i->second;
			int a = 0;
			for (; a < v.size(); a += 2) {
				if (a != v.size() - 1 && v[a] + v[a + 1] > 0) {
					tot += v[a] + v[a + 1];
					adv[i->first] = max(v[a], v[a + 1]) - (v[a] + v[a + 1]);
				}
			}
			if (v.size() % 2 && mid < v.back()) mid = v.back();
		}
	}
	ll ans = tot + mid;
	for (auto i = str.begin(); i != str.end(); i++) ans = max(ans, tot + adv[i->first]);
	cout << ans;
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <initializer_list>
#include <functional>
#include <unordered_set>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair <int, int> par;
typedef pair <ll, ll> parll;
int const INF = 1e9 + 7;
ll const LLINF = 1e18 + 7;
ld const eps = 1e-8;
ld const PI = acos(-1);
ll const p_hash = 257;
ll const mod = 1e9 + 9;
bool operator == (par const& a, par const& b) {
	return (a.first == b.first && a.second == b.second);
}
par operator + (par const& a, par const& b) {
	return{ a.first + b.first, a.second + b.second };
}
par operator - (par const& a, par const& b) {
	return{ a.first - b.first, a.second - b.second };
}

inline ll h(string & a) {
	ll res = a[0];
	for (int i = 1; i < a.size(); i++) {
		res *= p_hash;
		res %= mod;
		res += a[i];
		res %= mod;
	}
	return res;
}

inline bool pal(string & a) {
	for (int i = 0; i < a.size() / 2; i++) {
		if (a[i] != a[a.size() - 1 - i]) return false;
	}
	return true;
}

map <ll, vector <int> > str;
map <ll, string> byhash;
map <ll, ll> rev;
map <ll, int> adv;
map <ll, bool> done;

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	ll n, k;
	cin >> k >> n;
	for (int i = 0; i < k; i++) {
		string s; int a;
		cin >> s >> a;
		ll hs = h(s);
		byhash[hs] = s;
		str[hs].push_back(a);
		reverse(s.begin(), s.end());
		rev[hs] = h(s);
	}
	for (auto i = str.begin(); i != str.end(); i++) {
		sort(i->second.begin(), i->second.end());
		reverse(i->second.begin(), i->second.end());
	}
	ll tot = 0;
	int mid = 0;
	for (auto i = str.begin(); i != str.end(); i++) {
		if (done[i->first]) continue;
		int a = 0, b = 0;
		if (!pal(byhash[i->first])) {
			done[i->first] = true;
			done[rev[i->first]] = true;
			vector <int> & v1 = i->second, v2 = str[rev[i->first]];
			while (a < v1.size() && b < v2.size()) {
				if (v1[a] + v2[b] > 0) {
					tot += v1[a] + v2[b];
					//adv[i->first] = max(adv[i->first], max(v1[a], v2[b]) - (v1[a] + v2[b]));
					a++;
					b++;
				} else break;
			}
		} else {
			done[i->first] = true;
			vector <int> & v = i->second;
			int a = 0;
			for (; a < v.size(); a += 2) {
				if (a == v.size() - 1) {
					mid = max(mid, v.back());
					break;
				}
				adv[i->first] = max(adv[i->first], max(v[a], v[a + 1]) - (v[a] + v[a + 1]));
				if (v[a] + v[a + 1] > 0) {
					tot += v[a] + v[a + 1];
				}
			}
		}
	}
	ll ans = tot + mid;
	for (auto i = str.begin(); i != str.end(); i++) ans = max(ans, tot + adv[i->first]);
	cout << ans;
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <initializer_list>
#include <functional>
#include <unordered_set>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair <int, int> par;
typedef pair <ll, ll> parll;
int const INF = 1e9 + 7;
ll const LLINF = 1e18 + 7;
ld const eps = 1e-8;
ld const PI = acos(-1);
ll const p_hash = 257;
ll const mod = 1e9 + 9;
bool operator == (par const& a, par const& b) {
	return (a.first == b.first && a.second == b.second);
}
par operator + (par const& a, par const& b) {
	return{ a.first + b.first, a.second + b.second };
}
par operator - (par const& a, par const& b) {
	return{ a.first - b.first, a.second - b.second };
}

inline ll h(string & a) {
	ll res = a[0];
	for (int i = 1; i < a.size(); i++) {
		res *= p_hash;
		res %= mod;
		res += a[i];
		res %= mod;
	}
	return res;
}

inline bool pal(string & a) {
	for (int i = 0; i < a.size() / 2; i++) {
		if (a[i] != a[a.size() - 1 - i]) return false;
	}
	return true;
}

map <ll, vector <int> > str;
map <ll, string> byhash;
map <ll, ll> rev;
map <ll, int> adv;
map <ll, bool> done;

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	ll n, k;
	cin >> k >> n;
	for (int i = 0; i < k; i++) {
		string s; int a;
		cin >> s >> a;
		ll hs = h(s);
		byhash[hs] = s;
		str[hs].push_back(a);
		reverse(s.begin(), s.end());
		rev[hs] = h(s);

	}
	for (auto i = str.begin(); i != str.end(); i++) {
		sort(i->second.begin(), i->second.end());
		reverse(i->second.begin(), i->second.end());
	}
	ll tot = 0;
	int mid = 0;
	for (auto i = str.begin(); i != str.end(); i++) {
		if (done[i->first]) continue;
		int a = 0, b = 0;
		if (!pal(byhash[i->first])) {
			done[i->first] = true;
			done[rev[i->first]] = true;
			vector <int> & v1 = i->second, v2 = str[rev[i->first]];
			while (a < v1.size() && b < v2.size()) {
				if (v1[a] + v2[b] > 0) {
					tot += v1[a] + v2[b];
					//adv[i->first] = max(adv[i->first], max(v1[a], v2[b]) - (v1[a] + v2[b]));
					a++;
					b++;
				} else break;
			}
		} else {
			done[i->first] = true;
			vector <int> & v = i->second;
			int a = 0;
			for (; a < v.size(); a += 2) {
				if (a != v.size() - 1 && v[a] + v[a + 1] > 0) {
					tot += v[a] + v[a + 1];
					adv[i->first] = max(adv[i->first], max(v[a], v[a + 1]) - (v[a] + v[a + 1]));
				}
			}
			if (v.size() % 2 && mid < v.back()) mid = v.back();
		}
	}
	ll ans = tot + mid;
	for (auto i = str.begin(); i != str.end(); i++) ans = max(ans, tot + adv[i->first]);
	cout << ans;
	return 0;
}