#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PP;
//#define MOD 1000000007
//#define MOD 998244353
#define INF 2305843009213693951
//#define INF 810114514
#define PI 3.141592653589
#define setdouble setprecision
#define REP(i,n) for(ll i=0;i<(n);++i)
#define OREP(i,n) for(ll i=1;i<=(n);++i)
#define RREP(i,n) for(ll i=(n)-1;i>=0;--i)
#define all1(i) begin(i),end(i)
#define GOODBYE do { cout << "0" << endl; return 0; } while (false)
#define MM <<" "<<
#define Endl endl
#define debug false
#define debug2 false

class Dijkstra{
    /*
    Copyright (c) 2020 0214sh7
    https://github.com/0214sh7/library/
    */
    private:
    typedef std::pair<long long,int> P;
    std::vector<std::vector<P>> G;
    int V;
    //long long INF = (1LL<<61);
    std::priority_queue<P,std::vector<P>,std::greater<P>> que;
    
    public:
    void init(std::vector<std::pair<std::pair<int,int>,long long>> edge){
        //頂点数を決定する
        V=0;
        for(int i=0;i<edge.size();i++){
            V=std::max(V,edge[i].first.first+1);
            V=std::max(V,edge[i].first.second+1);
        }
        
        //辺集合を扱いやすい形式に変換する
        G.resize(V);
        for(int i=0;i<edge.size();i++){
            int from=edge[i].first.first,to=edge[i].first.second;
            long long cost=edge[i].second;
            G[from].push_back({cost,to});
        }
    }
    
    std::vector<long long> solve(int s){
        std::vector<long long> d;
        //INFで初期化する
        for(int i=0;i<V;i++){
            d.push_back(INF);
        }
        d[s]=0;
        que.push({0,s});
        //queは{cost,to}をコストが小さい順に出す
        while(!que.empty()){
            P p = que.top();
            que.pop();
            int v=p.second;
            if(d[v]<p.first)continue;
            for(int i=0;i<G[v].size();i++){
                P e = G[v][i];
                if(d[e.second]>d[v]+e.first){
                    d[e.second] = d[v]+e.first;
                    que.push({d[e.second],e.second});
                }
            }
        }
        return d;
    }
    
    //init:{ {int,int},longlong}のvectorを渡すことで有向グラフを構築する
    //solve:始点を渡すとinitで構築したグラフでダイクストラをし、コストのvectorを返す
};


int main(void){
    ll N;
    vector<string> S;
    vector<ll> C;
    string a;ll b;
    
    cin >> N;
    REP(i,N){
        cin >> a;
        S.push_back(a);
        cin >> b;
        C.push_back(b);
    }
    
    map<pair<string,string>,ll> Mp;
    vector<pair<string,string>> T;
    //文字列を整数に変換するためのマップ
    //0:未使用 1:終端ノード 2:始点ノード({"",""}) 3以降:一般ノード
    //Tにはノードを入れてある　後の辺張りの際に使う
    
    Mp[{"",""}]=2;
    T.push_back({"",""});
    ll k=3;
    
    //ノードとなる文字列対を作る
    //ダイクストラにはこれの代わりにmapで対応させたノードを入れる
    //tには反転された文字列が入ってる
    //すくなくとも片方は空文字列とならなければノードとして無効
    REP(j,N){
        string s="",t="";
        REP(i,S[j].size()){
            s = S[j].substr(S[j].size()-i-1);
            t = S[j].substr(0,i+1);
            reverse(t.begin(),t.end());
            if(Mp[{s,""}]==0){
                Mp[{s,""}]=k;
                k++;
                T.push_back({s,""});
            }
            if(Mp[{"",t}]==0){
                Mp[{"",t}]=k;
                k++;
                T.push_back({"",t});
            }
        }
        //たとえばS[j]="abc"なら{"c",""},{"bc",""},{"abc",""},{"","a"},{"","ba"},{"","cba"}がTに入っていてほしい
    }
    
    pair<pair<int,int>,ll> h;
    vector<pair<pair<int,int>,ll>> edge;
    
    //辺を張る工程
    REP(i,T.size()){
        h.first.first=Mp[T[i]];
        REP(j,N){
            REP(l,2){
                //空文字列の方にS[j]を貼り付ける
                string s=T[i].first,t=T[i].second;
                if(l==0 && s!="")continue;
                if(l==1 && t!="")continue;
                
                if(l==0){
                    s=S[j];
                }else{
                    string u = S[j];
                    reverse(u.begin(),u.end());
                    t=u;
                }
                
                //いらない部分を端折る
                if(s.size()<t.size()){
                    if(s==t.substr(0,s.size())){
                        t=t.substr(s.size());s="";
                    }
                }else if(t.size()<s.size()){
                    if(t==s.substr(0,t.size())){
                        s=(string)s.substr(t.size());t="";
                    }
                }else{
                    if(s==t){
                        s="";t="";
                    }
                }
                
                //ノードして有効なら辺を張る
                if(s==""||t==""){
                    h.first.second=Mp[{s,t}];
                    if(s==""&&t=="")h.first.second=1;
                    h.second=C[j];
                    edge.push_back(h);
                }
                
            }
        }
    }
    
    //回文ノードならそこから終端ノードにも辺を張る
    REP(i,T.size()){
        string t=T[i].first+T[i].second;
        string s=t;
        if(t=="")continue;
        reverse(t.begin(),t.end());
        if(s==t){
            h.first.first=Mp[T[i]];
            h.first.second=1;
            h.second=0;
            edge.push_back(h);
        }
    }
    
    
    //ダイクストラに投げる
    Dijkstra dijk;
    dijk.init(edge);
    vector<ll> d = dijk.solve(2);
    
    //終端ノードは1
    if(d[1]==INF){
        cout << -1 << endl;
    }else{
        cout << d[1] << endl;
    }
    
    return 0;
}



Measured memory_bytes: 3964