#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cmath>
#include <map>
#include <queue>
#include <iomanip>
#include <set>
#include <tuple>
#define mkp make_pair
#define mkt make_tuple
#define rep(i,n) for(int i = 0; i < (n); ++i)
#define all(v) v.begin(),v.end()
using namespace std;
typedef long long ll;
const ll MOD=1e9+7;
template<class T> void chmin(T &a,const T &b){if(a>b) a=b;}
template<class T> void chmax(T &a,const T &b){if(a<b) a=b;}

const ll INF=1e18;

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);

  int N;
  cin>>N;
  vector<string> S(N);
  vector<ll> C(N);
  rep(i,N) cin>>S[i]>>C[i];

  vector<string> T=S;
  rep(i,N) reverse(all(T[i]));
  priority_queue<tuple<ll,int,string>,vector<tuple<ll,int,string>>,greater<tuple<ll,int,string>>> PQ;
  rep(i,N) PQ.push(mkt(C[i],1,T[i]));
  ll ans=INF;
  map<pair<string,int>,int> mp;
  while(!PQ.empty()){
      auto f=PQ.top();
      PQ.pop();
      string now=get<2>(f);
      int rev=get<1>(f);
      ll cost=get<0>(f);
      if(mp.count(mkp(now,rev))) continue;

      bool ok=true;
      for(int i=0;i<now.size();i++) if(now[i]!=now[now.size()-1-i]) ok=false;
      if(ok){
          chmin(ans,cost);
          continue;
      }
      mp[mkp(now,rev)]=cost;

      if(rev==0){
          for(int i=0;i<N;i++){
              if(now.size()==S[i].size()){
                  if(now==S[i]) chmin(ans,cost+C[i]);
              }else if(now.size()<S[i].size()){
                  int match=0;
                  int sz=S[i].size();
                  for(int j=0;j<now.size();j++) if(now[j]==S[i][j]) match++;
                  if(match==now.size()){
                      string nex="";
                      for(int j=now.size();j<S[i].size();j++) nex+=S[i][j];
                      reverse(all(nex));
                      PQ.push(mkt(cost+C[i],1,nex));
                  }
              }else{
                  int match=0;
                  int sz=S[i].size();
                  for(int j=0;j<S[i].size();j++) if(now[j]==S[i][j]) match++;
                  if(match==S[i].size()){
                      string nex="";
                      for(int j=S[i].size();j<now.size();j++) nex+=now[j];
                      PQ.push(mkt(cost+C[i],0,nex));
                  }
              }
          }
      }else{
          for(int i=0;i<N;i++){
              if(now.size()==S[i].size()){
                  if(now==S[i]) chmin(ans,cost+C[i]);
              }else if(now.size()<S[i].size()){
                  int match=0;
                  int sz=S[i].size();
                  for(int j=0;j<now.size();j++) if(now[now.size()-1-j]==S[i][sz-1-j]) match++;
                  if(match==now.size()){
                      string nex="";
                      for(int j=0;j<S[i].size()-now.size();j++) nex+=S[i][j];
                      reverse(all(nex));
                      PQ.push(mkt(cost+C[i],0,nex));
                  }
              }else{
                  int match=0;
                  int sz=S[i].size();
                  for(int j=0;j<S[i].size();j++) if(now[now.size()-1-j]==S[i][sz-1-j]) match++;
                  if(match==S[i].size()){
                      string nex="";
                      for(int j=0;j<now.size()-S[i].size();j++) nex+=now[j];
                      PQ.push(mkt(cost+C[i],1,nex));
                  }
              }
          }
      }
  }

  if(ans==INF) cout<<-1<<endl;
  else cout<<ans<<endl;

  return 0;
}


Measured memory_bytes: 3748