Problem:
Score : 600 points

Problem Statement

We have N strings of lowercase English letters: S_1, S_2, \cdots, S_N.

Takahashi wants to make a string that is a palindrome by choosing one or more of these strings - the same string can be chosen more than once - and concatenating them in some order of his choice.

The cost of using the string S_i once is C_i, and the cost of using it multiple times is C_i multiplied by that number of times.

Find the minimum total cost needed to choose strings so that Takahashi can make a palindrome.

If there is no choice of strings in which he can make a palindrome, print -1.

Constraints

1 \leq N \leq 50

1 \leq |S_i| \leq 20

S_i consists of lowercase English letters.

1 \leq C_i \leq 10^9

Input

Input is given from Standard Input in the following format:

N
S_1 C_1
S_2 C_2
:
S_N C_N

Output

Print the minimum total cost needed to choose strings so that Takahashi can make a palindrome, or -1 if there is no such choice.

Sample Input 1

3
ba 3
abc 4
cbaa 5

Sample Output 1

7

We have ba, abc, and cbaa.

For example, we can use ba once and abc once for a cost of 7, then concatenate them in the order abc, ba to make a palindrome.
Also, we can use abc once and cbaa once for a cost of 9, then concatenate them in the order cbaa, abc to make a palindrome.

We cannot make a palindrome for a cost less than 7, so we should print 7.

Sample Input 2

2
abcab 5
cba 3

Sample Output 2

11

We can choose abcab once and cba twice, then concatenate them in the order abcab, cba, cba to make a palindrome for a cost of 11.

Sample Input 3

4
ab 5
cba 3
a 12
ab 10

Sample Output 3

8

We can choose a once, which is already a palindrome, but it is cheaper to concatenate ab and cba.

Sample Input 4

2
abc 1
ab 2

Sample Output 4

-1

We cannot make a palindrome, so we should print -1.

Solution in C++ (GCC 9.2.1) (judge verdict: Wrong Answer)

///****In the name of ALLAH, most Gracious, most Compassionate****//

#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair <ll, ll> pii;

#define ALL(a) a.begin(), a.end()
#define FastIO ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
#define IN freopen("input.txt","r+",stdin)
#define OUT freopen("output.txt","w+",stdout)

#define DBG(a) cerr<< "line "<<__LINE__ <<" : "<< #a <<" --> "<<(a)<<endl
#define NL cout<<endl

template < class T1,class T2>
ostream &operator <<(ostream &os,const pair < T1,T2 > &p)
{
    os<<"{"<<p.first<<","<<p.second<<"}";
    return os;
}

const ll N=4e3+5;
const ll oo=1e18;

string s[N];

ll cost[N];
ll dist[N];


ll get_node(ll i,ll j, ll t)
{
    return i*40 + j *2 + t;
}
ll get_idx(ll u)
{
    return u/40;
}
ll get_char(ll u)
{
    return (u%40)/2;
}
ll get_parity(ll u)
{
    return u%2;
}

vector<pii > g[N];

bool common_match_suff(ll i,ll j,ll k)
{
    ll len = min((ll)s[i].size() - j,(ll) s[k].size());
    for(ll ii=0; ii<len; ii++)
        if(s[i][j+ii]!=s[k][s[k].size() - ii - 1 ])
            return 0;
    return 1;
}
bool common_match_pref(ll i,ll j,ll k)
{
    ll len = min(j + 1, (ll)s[k].size());
    for(ll ii=0; ii<len; ii++)
        if(s[i][j-ii]!=s[k][ii])
            return 0;
    return 1;
}


bool is_pal(ll i,ll j)
{
    ll len = min(j + 1,(ll) s[i].size() -j );
    for(ll ii=0; ii<len; ii++)
        if(s[i][j-ii] != s[i][j+ii])
            return 0;
    return 1;
}


ll dijkstra()
{
    priority_queue <  pair < ll, ll  > > pq;
    for(ll i=0; i<=50*20; i++)
        dist[i] = oo;
    dist[0]= 0;
    pq.push({0, 0 });


    while(!pq.empty())
    {
        pii cu = pq.top();
        pq.pop();

        ll u = cu.second;
        ll d = - cu.first;

        if(dist[u]!=d)
            continue ;

        for(pii vw : g[u])
        {
            ll v = vw.first;
            ll w = vw.second;

            ll c = d + w;

            if(dist[v] > c)
            {
                dist[v] = c;
                pq.push({-c, v});
            }
        }
    }
    if(dist[1] > 1e17)
        return -1;
    return dist[1];
}


void print()
{
    for(ll i=0; i<=50*20; i++)
    {
        if(!g[i].empty())
        {
            DBG(i);
            for(pii vw: g[i])
                cout<<vw<<" ";
            NL;
        }
    }
}

int32_t main()
{
    FastIO;
    ll n;
    cin>>n;
    for(ll i=1; i<=n; i++)
    {
        cin>>s[i]>>cost[i];
    }
    for(ll i=1; i<=n; i++)
    {
        for(ll j=0; j<s[i].size(); j++)
        {
            for(ll k=1; k<=n; k++)
            {
                if(common_match_suff(i,j,k))
                {
//                    cout<<"suffix \n";
//                    DBG(i);
//                    DBG(j);
//                    DBG(k);
//                    NL;

                    ll x = s[i].size()-j;
                    ll y = s[k].size();
                    if( x == y )
                    {
                        g[0].push_back({get_node(i,j, 1), cost[k]});
                    }
                    else if(x> y)
                    {
                        g[get_node(i,j+y,  1 )].push_back({get_node(i,j, 1 ), cost[k]});
                    }
                    else /// x < y
                    {
                        g[get_node(k,s[k].size() - x  -1, 0 )].push_back({get_node(i,j, 1 ), cost[k]});
                    }

                }
                if(common_match_pref(i,j,k))
                {
//                    cout<<" prefix \n";
//                    DBG(i);
//                    DBG(j);
//                    DBG(k);
//                    NL;

                    ll x = j+1;
                    ll y = s[k].size();
                    if( x == y )
                    {
                        g[0].push_back({get_node(i,j, 0 ), cost[k]});
                    }
                    else if(x> y)
                    {
                        g[get_node(i,j - y,  0 )].push_back({get_node(i,j, 0 ), cost[k]});
                    }
                    else /// x < y
                    {
                        g[get_node(k,x, 1 )].push_back({get_node(i,j, 0 ), cost[k]});
                    }

                }


            }
        }
    }
    for(ll i=1; i<=n; i++)
    {
        for(ll j=0; j<s[i].size(); j++)
        {
            if(is_pal(i,j))
            {
                ll x = j+1;
                ll y =  s[i].size()- j;

//                DBG(i);
//                DBG(j);
//                DBG(x);
//                DBG(y);
//                NL;

                if(x==y)
                {
                    g[0].push_back({1, cost[i]});
                }
                else if(x > y)
                {
                    g[get_node(i,j-y, 0)].push_back({1, cost[i]});
                }
                else /// x< y
                {
                    g[get_node(i,j+x, 1)].push_back({1,cost[i]});
                }
            }
        }

        g[get_node(i,0, 1)].push_back({ 1, cost[i]});
        g[get_node(i,s[i].size() - 1, 0)].push_back({1,cost[i]});
    }
//    print();
    cout<<dijkstra()<<"\n";

}