// #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>
using namespace std;
using ll = long long int;
using int64 = long long int;
 
template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}
 
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const int INF = 1LL << 29;
const ll LONGINF = 1LL << 60;
const ll MOD = 1000000007LL;

ll dp[55][25][25][2];

struct Elem {
    int k, l, r, f;
    ll cost;
    Elem(int a, int b, int c, int x, ll d) : k(a), l(b), r(c), f(x), cost(d) {}
    auto get() {
        return make_tuple(k, l, r, f, cost);
    }
    bool operator<(const Elem &e) const {
        return cost > e.cost;
    }
};

int main() {
    int N; scanf("%d", &N);
    vector<string> S(N);
    vector<ll> C(N);
    for(int i=0; i<N; i++) {
        cin >> S[i] >> C[i];
    }

    ll ans = LONGINF;
    priority_queue<Elem> que;
    fill(dp[0][0][0], dp[N][0][0], LONGINF);
    for(int i=0; i<N; i++) {
        int L = S[i].size();
        for(int j=0; j<L; j++) {
            // 奇数長にするとき (真ん中が j)
            {
                int l = j, r = j;
                while(l-1 >= 0 and r+1 < L and S[i][l-1] == S[i][r+1]) {
                    l--; r++;
                }

                // どっちかは使い切ってないとダメ
                if(l == 0) {
                    // [r+1, L) は未使用
                    dp[i][r+1][L][0] = C[i];
                    que.emplace(i, r+1, L, 0, C[i]);
                }
                if(r+1 == L) {
                    // [0, l) は未使用
                    dp[i][0][l][1] = C[i];
                    que.emplace(i, 0, l, 1, C[i]);
                }
            }
            
            // 偶数長にするとき (j と j+1 の間)
            if(j+1 < L and S[i][j] == S[i][j+1]) {
                int l = j, r = j+1;
                while(l-1 >= 0 and r+1 < L and S[i][l-1] == S[i][r+1]) {
                    l--; r++;
                }

                // どっちかは使い切ってないとダメ
                if(l == 0) {
                    // [r+1, L) は未使用
                    dp[i][r+1][L][0] = C[i];
                    que.emplace(i, r+1, L, 0, C[i]);
                }
                if(r+1 == L) {
                    // [0, l) は未使用
                    dp[i][0][l][1] = C[i];
                    que.emplace(i, 0, l, 1, C[i]);
                }
            }

            // 全部残す
            dp[i][0][L][0] = C[i];
            que.emplace(i, 0, L, 0, C[i]);
            dp[i][0][L][1] = C[i];
            que.emplace(i, 0, L, 1, C[i]);
        }
    }

    auto next_state = [&](int k, int l, int r, int f, int p) {
        const string& s = S[p];
        int ll = 0, rr = (int)s.size();
        while(r-l > 0 and rr-ll>0) {
            int i = (f == 0 ? rr-1 : ll);
            int j = (f == 0 ? l : r-1);
            if(s[i] != S[k][j]) {
                return make_tuple(-1, -1, -1, -1);
            }
            if(f == 0) l++, rr--;
            else r--, ll++;
        }
        if(r-l > 0) {
            return make_tuple(k, l, r, f);
        }
        else {
            return make_tuple(p, ll, rr, f^1);
        }
    };

    while(que.size()) {
        Elem cur = que.top(); que.pop();
        int k, l, r, f; ll c;
        tie(k, l, r, f, c) = cur.get();

        /*
        fprintf(stderr, "%c", " !"[l == r]);
        fprintf(stderr, " state [k=%d, l=%d, r=%d, f=%d]: %lld\n", k, l, r, f, c);
        */

        if(l == r) chmin(ans, c);
        if(dp[k][l][r][f] < c) continue;
        for(int i=0; i<N; i++) {
            ll nk, nl, nr, nf;
            tie(nk, nl, nr, nf) = next_state(k, l, r, f, i);
            if(nk < 0) continue;
            ll nc = c + C[i];
            if(dp[nk][nl][nr][nf] > nc) {
                dp[nk][nl][nr][nf] = nc;
                que.emplace(nk, nl, nr, nf, nc);
            }
            if(nl == nr and dp[nk][nl][nr][nf^1] > nc) {
                dp[nk][nl][nr][nf^1] = nc;
                que.emplace(nk, nl, nr, nf^1, nc);
            }
        }
    }

    if(ans == LONGINF) cout << -1 << endl;
    else cout << ans << endl;
    return 0;
}


Measured memory_bytes: 4288