#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep_range(i, s, e) for (int i = (s); i < (int)(e); i++)
#define rep_rev(i, s, e) for (int i = (s)-1; i >= (int)(e); i--)
#define sort_vec(v) sort((v).begin(),(v).end())
typedef int64_t lint;
// lint mod = 998244353;
// lint mod = 1000000007;
template< typename T1, typename T2 >
inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }
template< typename T1, typename T2 >
inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }

// ダイクストラ
vector<lint> dijkstra(vector<set<int>> g, map<pair<int,int>,lint> costs, int s){
  int n=g.size();

  using state=pair<lint,int>;
  // using state=pair<lint,pair<int,int>>; で状態を増やす
  priority_queue<state,vector<state>,greater<state>> que;
  vector<lint> mincost(n,9e18);

  que.emplace(0,s);
  mincost[s]=0;
  while(!que.empty()){
    state us=que.top(); que.pop();
    lint ucost=us.first;
    int u=us.second;
    if(ucost>mincost[u]) continue;

    for(int v:g[u]){
      lint vcost=ucost+costs[{u,v}];  // 移動コスト
      if(chmin(mincost[v],vcost)){
        que.emplace(vcost,v);
      }
    }
  }
  return mincost;
}
////////////////////////////////

lint app() {
  int n;
  cin>>n;

  vector<string> s(n),srev(n);
  vector<lint> c(n);
  rep(i,n){
    cin>>s[i]>>c[i];
    srev[i]=s[i];
    reverse(srev[i].begin(),srev[i].end());
  }

  set<pair<bool,string>> nodeset;
  nodeset.emplace(true,"");
  rep(i,n){
    rep(j,s[i].size()) nodeset.emplace(true,s[i].substr(j));
    rep(j,s[i].size()) nodeset.emplace(false,srev[i].substr(j));
  }
  nodeset.emplace(false,"$");

  vector<pair<bool,string>> nodes;
  map<pair<bool,string>,int> nodeindex;
  for(auto u:nodeset){
    nodeindex[u]=nodes.size();
    nodes.push_back(u);
  }
  int nnodes=nodes.size();

  //rep(i,nnodes) cout<<nodes[i].first<<nodes[i].second<<endl;

  vector<set<int>> g(nnodes,set<int>());
  map<pair<int,int>,lint> costs;
  rep_range(i,1,nnodes){
    auto u=nodes[i];
    rep(j,n){
      bool over=u.first;
      string st=u.second;
      string sadd=over?srev[j]:s[j];
      if(sadd.size()<=st.size()){
        if(equal(sadd.begin(),sadd.end(),st.begin())){
          bool overafter=over;
          string stafter=st.substr(sadd.size());
          if(equal(stafter.begin(),stafter.end(),stafter.rbegin())){
            overafter=false;
            stafter="$";
          }
          int k=nodeindex[{overafter,stafter}];
          //cout<<st<<'<'<<sadd<<'='<<stafter<<k<<' '<<c[j]<<endl;
          g[i].emplace(k);
          if(costs[{i,k}]==0) costs[{i,k}]=c[j];
          else chmin(costs[{i,k}],c[j]);
        }
      }else{
        if(equal(st.begin(),st.end(),sadd.begin())){
          bool overafter=!over;
          string stafter=sadd.substr(st.size());
          if(equal(stafter.begin(),stafter.end(),stafter.rbegin())){
            overafter=false;
            stafter="$";
          }
          int k=nodeindex[{overafter,stafter}];
          //cout<<st<<'<'<<sadd<<'='<<stafter<<k<<' '<<c[j]<<endl;
          g[i].emplace(k);
          if(costs[{i,k}]==0) costs[{i,k}]=c[j];
          else chmin(costs[{i,k}],c[j]);
        }
      }
    }
  }


  lint ans = dijkstra(g,costs,nodeindex[{true,""}])[nodeindex[{false,"$"}]];
  if(ans==9e18) return -1;
  return ans;
}

int main(){cout<<app()<<endl;return 0;}


Measured memory_bytes: 4572