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)

#include<bits/stdc++.h>
#define fi first
#define se second
#define lc (x<<1)
#define rc (x<<1|1)
#define gc getchar()//(p1==p2&&(p2=(p1=buf)+fread(buf,1,size,stdin),p1==p2)?EOF:*p1++)
#define mk make_pair
#define pi pair<int,int>
#define fi first
#define se second
#define pb push_back
#define IT iterator
#define vi vector<int>
#define vl vector<ll>
#define SZ(a) ((int)a.size())
#define all(a) a.begin(),a.end()
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int N=55,T=1010,size=1<<20,mod=998244353;
const ll inf=1e18;

template<class o> void qr(o &x) {
	char c=gc; x=0; int f=1;
	while(!isdigit(c)){if(c=='-')f=-1; c=gc;}
	while(isdigit(c)) x=x*10+c-'0',c=gc;
	x*=f;
}
template<class o> void qw(o x) {
	if(x/10) qw(x/10);
	putchar(x%10+'0');
}
template<class o> void pr1(o x) {
	if(x<0)x=-x,putchar('-');
	qw(x); putchar(' ');
}
template<class o> void pr2(o x) {
	if(x<0)x=-x,putchar('-');
	qw(x); puts("");
}

//math
ll mult(ll a,ll b,ll p) {
	a=(a%p+p)%p; b=(b%p+p)%p;
	ll c=(ld)a*b/p;
	return a*b-c*p;
}
ll gcd(ll a,ll b) {return !a?b:gcd(b%a,a);}
ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
ll power(ll a,ll b=mod-2) {
	ll c=1;
	while(b) {
		if(b&1) c=c*a%mod;
		b /= 2; a=a*a%mod;
	}
	return c;
}
ll Power(ll a,ll b=mod-2) {
	ll c=1;
	while(b) {
		if(b&1) c=mult(c,a,mod);
		b /= 2; a=mult(a,a,mod);
	}
	return c;
}

int n;
char s[N];

struct AC {
	int trie[T][26],fail[T],tot=1,ed[T];
	void ins(char *s,int x) {
		int p=1;
		for(int i=1;s[i];i++) {
			int c=s[i]-'a';
			if(!trie[p][c]) trie[p][c]=++tot;
			p=trie[p][c]; 
		}
		if(ed[p]) ed[p]=min(ed[p],x);
		else ed[p]=x;
	}
} a,b;

ll f[T][T],ans=inf;
bool vis[T][T];
struct rec {
	int x,y;ll z;
	rec(int a=1,int b=1,ll c=0) {x=a; y=b; z=c;}
	bool operator<(rec b) const {return z>b.z;}
} ;
priority_queue<rec> q;

void add(int x,int y,ll z) {
	if(f[x][y]>z)
		f[x][y]=z,q.push(rec(x,y,z));
}

void solve() {
	memset(f,63,sizeof f); add(1,1,0);
	while(q.size()) {
		int x=q.top().x,y=q.top().y; q.pop();
		if(vis[x][y]) continue;
		vis[x][y]=1;
		for(int c=0;c<26;c++) {
			int tx=a.trie[x][c],ty=b.trie[y][c];
			if(tx&&ty&&!vis[tx][ty]) {
				add(tx,ty,f[x][y]);
				ll u=a.ed[tx],v=b.ed[ty];
				if(u) add(1,ty,u+f[x][y]);
				if(v) add(tx,1,f[x][y]+v);
				if(u&&v) ans=min(ans,f[x][y]+u+v);
			}
		}
	}
	if(ans==inf) puts("-1");
	else pr2(ans/2);
}

int main() {
	qr(n);
	for(int i=1,x;i<=n;i++) {
		scanf("%s",s+1); qr(x); 
		a.ins(s,x);
		int len=strlen(s+1);
		reverse(s+1,s+len+1);
		b.ins(s,x);
	}
	solve();
	return 0;
}