// Original C++ solution (slower):
#pragma GCC optimize(2)

#pragma G++ optimize(2)

#include<bits/stdc++.h>

#define si(a) scanf("%d",&a)

#define sl(a) scanf("%lld",&a)

#define sd(a) scanf("%lf",&a)

#define ss(a) scanf("%s",a)

#define ms(a) memset(a,0,sizeof(a))

#define repi(i,a,b) for(register int i=a;i<=b;++i)

#define repd(i,a,b) for(register int i=a;i>=b;--i)

#define reps(s) for(int i=head[s],v=e[i].to;i;i=e[i].nxt,v=e[i].to)

#define ce(i,r) i==r?'\n':' '

#define pb push_back 

#define all(x) x.begin(),x.end()

#define fi first

#define se second

#define pr(x) cout<<#x<<": "<<x<<endl

using namespace std;

typedef long long ll;

const ll inf=1e18;

const int MAX_N=550;

const int MAX_L=305;

ll ans=inf;

int n,len[MAX_N];

ll c[MAX_N],dp[MAX_N][MAX_L][2];

char s[MAX_N][MAX_L];

ll dfs(int id,int pos,int dir)

{

	if(pos>len[id]) return 0;

	if(~dp[id][pos][dir]) return dp[id][pos][dir];

	ll &v=dp[id][pos][dir];

	v=inf;

	bool flag=true;

	if(!dir){ for(int j=pos,k=len[id];j<k;j++,k--) if(s[id][j]!=s[id][k]) {flag=0; break;} } 

	else{ for(int j=pos,k=1;j>k;j--,k++) if(s[id][j]!=s[id][k]) {flag=0; break;} } 



	if(flag) return dp[id][pos][dir]=0;



    for(int i=1,j,k;i<=n;i++) {//???????????

        flag=1;

        if(!dir) {

            for(j=pos,k=len[i];j<=len[id]&&k>=1;j++,k--)

                if(s[id][j]!=s[i][k]) {flag=0; break;}

            if(flag) {

                if(k<1) v=min(v,c[i]+dfs(id,j,0));

                else v=min(v,c[i]+dfs(i,k,1));

            }

        }

        else {

            for(j=pos,k=1;j>=1&&k<=len[i];j--,k++)

                if(s[id][j]!=s[i][k]) {flag=0; break;}

            if(flag) {

                if(j<1) v=min(v,c[i]+dfs(i,k,0));

                else v=min(v,c[i]+dfs(id,j,1));

            }

        }

    }

	return v;

}

int main()

{

 	scanf("%d",&n); memset(dp,-1,sizeof(dp));

    for(int i=1;i<=n;i++) scanf("%s",s[i]+1),scanf("%lld",&c[i]),len[i]=strlen(s[i]+1);

    for(int i=1;i<=n;i++) 

		ans=min(ans,c[i]+dfs(i,1,0));

    printf("%lld\n",ans==inf?-1:ans);return 0;

	return 0;

}


// Optimized solution to the same problem (faster):
#pragma GCC optimize(2)

#pragma G++ optimize(2)

#include<bits/stdc++.h>

#define si(a) scanf("%d",&a)

#define sl(a) scanf("%lld",&a)

#define sd(a) scanf("%lf",&a)

#define ss(a) scanf("%s",a)

#define ms(a) memset(a,0,sizeof(a))

#define repi(i,a,b) for(register int i=a;i<=b;++i)

#define repd(i,a,b) for(register int i=a;i>=b;--i)

#define reps(s) for(int i=head[s],v=e[i].to;i;i=e[i].nxt,v=e[i].to)

#define ce(i,r) i==r?'\n':' '

#define pb push_back 

#define all(x) x.begin(),x.end()

#define fi first

#define se second

#define pr(x) cout<<#x<<": "<<x<<endl

using namespace std;

typedef long long ll;

const ll inf=1e18;

const int MAX_N=55;

const int MAX_L=35;

ll ans=inf;

int n,len[MAX_N];

ll c[MAX_N],dp[MAX_N][MAX_L][2];

char s[MAX_N][MAX_L];

ll dfs(int id,int pos,int dir)

{

	if(pos>len[id]) return dp[id][pos][dir]=0;

	if(~dp[id][pos][dir]) return dp[id][pos][dir];

	ll &tmp=dp[id][pos][dir];

	tmp=inf;

	bool flag=true;

	if(!dir){ for(int st=pos,ed=len[id];st<ed;st++,ed--)if(s[id][st]!=s[id][ed]){ flag=false; break; } } 	

	else{ for(int st=pos,ed=1;st>ed;st--,ed++)if(s[id][st]!=s[id][ed]){ flag=false; break; } } 

	if(flag) return dp[id][pos][dir]=0;

	repi(i,1,n){

		flag=true;

		int j,k;

		if(!dir){

			for(j=pos,k=len[i];j<=len[id]&&k>=1;j++,k--)if(s[id][j]!=s[i][k]){ flag=false; break; }

			if(flag) tmp=min(tmp,c[i]+((k<1)?dfs(id,j,0):dfs(i,k,1)));

		}

		else{

			for(j=pos,k=1;j>=1&&k<=len[i];j--,k++)if(s[id][j]!=s[i][k]){ flag=false; break; }

			if(flag){

				if(j<1) tmp=min(tmp,c[i]+dfs(i,k,0));

				else tmp=min(tmp,c[i]+dfs(id,j,1));

			}

		}

	}

	return tmp;

}

int main()

{

	si(n); memset(dp,-1,sizeof(dp));

	repi(i,1,n) ss(s[i]+1),sl(c[i]),len[i]=strlen(s[i]+1);

	repi(i,1,n) ans=min(ans,c[i]+dfs(i,1,0));

	printf("%lld\n",(ans==inf)?-1:ans);

	return 0;

}


// Fastest known solution for this problem: