#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define FOR(i,n,m) for(int i=(int)(n); i<=(int)(m); i++)
#define RFOR(i,n,m) for(int i=(int)(n); i>=(int)(m); i--)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define RITR(x,c) for(__typeof(c.rbegin()) x=c.rbegin();x!=c.rend();x++)
#define setp(n) fixed << setprecision(n)

template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }

#define ll long long
#define vll vector<ll>
#define vi vector<int>
#define pll pair<ll,ll>
#define pi pair<int,int>

#define all(a) (a.begin()),(a.end())
#define rall(a) (a.rbegin()),(a.rend())
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define ins insert

using namespace std;

bool isPal(const string &a)
{
    int N = a.size();
    rep(i,N/2)if(a[i]!=a[N-i-1]) return false;
    return true;
}

const int V_MAX = 50*20*2+1;
const ll INF = 1e18;

struct Edge{int to; ll cost;};
struct State{
    State(){}
    State(int rev, string need):rev(rev),need(need){}
    int rev; string need;
    bool operator<(const State &a) const {
        return (rev!=a.rev)?(rev<a.rev):(need<a.need);
    }
};

//-------------------------------------------------

int main(void)
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N; cin>>N;
    vector<string> S(N);
    vll C(N);
    vector<vector<Edge> > G(V_MAX);
    map<State,int> Map;
    using P = pair<ll,int>;
    priority_queue<P,vector<P>,greater<P> > que;
    vll dist(V_MAX,INF);
    int V = 1;
    rep(i,N){
        cin>>S[i]>>C[i];
        string T = S[i];
        reverse(all(T));
        int sz = T.size();
        rep(j,sz){
            State ss(0,T.substr(j));
            State ps(1,T.substr(0,j+1));
            if (!Map.count(ss)) Map[ss] = (isPal(ss.need))?(0):(V++);
            if (!Map.count(ps)) Map[ps] = (isPal(ps.need))?(0):(V++);
        }
        int st = Map[State(0,T)];
        if (dist[st]>C[i]){
            que.push(P(C[i],st));
            dist[st] = C[i];
        }
    }
    for(auto e:Map){
        int v = e.se;
        if (v==0) continue;
        rep(i,N){
            int rev = e.fi.rev;
            string a = e.fi.need;
            string b = S[i];
            if (rev){
                reverse(all(a));
                reverse(all(b));
            }
            int A = a.size();
            int B = b.size();
            if (A<B) swap(a,b),swap(A,B),rev=1-rev;
            if (a.substr(0,B)!=b.substr(0,B)) continue;
            string next = a.substr(B);
            if (rev) reverse(all(next));
            G[v].pb({Map[State(rev,next)],C[i]});
            // cout<<v<<" -> "<<Map[State(rev,next)]<<" ("<<C[i]<<")"<<endl;
        }
    }
    while(!que.empty()){
        int v; ll cost;
        tie(cost,v) = que.top(); que.pop();
        if (dist[v]<cost) continue;
        for(auto e:G[v]){
            if (dist[e.to]>dist[v]+e.cost){
                dist[e.to]=dist[v]+e.cost;
                que.push(P(dist[e.to],e.to));
            }
        }
    }
    cout<<(dist[0]==INF?-1:dist[0])<<endl;
    return 0;
}


Measured memory_bytes: 3908