#include <bits/stdc++.h>
using namespace std;

#define for_(i,a,b) for(int i=a;i<b;++i)
#define ALL(a) a.begin(),a.end()
#define INIT(a,b) memset(a,b,sizeof(a))
using lint = long long int;

string convert(const string& L, const string& R) {
    int n = min(L.size(), R.size()), m = L.size();
    for_(i,0,n) if (L[m - i - 1] != R[i]) return "#";
    if (L.size() < R.size()) return R.substr(L.size());
    return L.substr(0, L.size() - R.size());
}

int N;
string S[55];
lint C[55];

int main() {
    cin >> N;
    for_(i,0,N) cin >> S[i] >> C[i];

    struct State {
        int p;
        string T;
        lint cost;
        bool operator < (const State& o) const { return cost > o.cost; }
    };

    map<string, lint> memo[2];
    priority_queue<State> que;

    for_(i,0,N) {
        int m = S[i].size();
        string L = "";
        for_(j,0,m) {
            vector<string> cand = {S[i].substr(j), S[i].substr(j + 1)};
            for (const string& R : cand) {
                string T = convert(L, R);
                if (T != "#") {
                    int p = (L.size() < R.size() ? 1 : 0);
                    que.push(State{p, T, C[i]});
                    memo[p][T] = C[i];
                }
            }
            L += S[i][j];
        }
    }

    while (!que.empty()) {
        State s = que.top(); que.pop();
        if (memo[s.p][s.T] < s.cost) continue;

        if (s.T == "") {
            cout << s.cost << endl;
            return 0;
        }

        for_(i,0,N) {
            string L = (s.p == 0 ? s.T : S[i]);
            string R = (s.p == 1 ? s.T : S[i]);

            int p = (L.size() < R.size() ? 1 : 0);
            string T = convert(L, R);
            if (memo[p].count(T) == 0) memo[p][T] = 1LL << 60;
            if (memo[p][T] > s.cost + C[i]) {
                memo[p][T] = s.cost + C[i];
                que.push(State{p, T, s.cost + C[i]});
            }
        }
    }

    cout << -1 << endl;
}