//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC target("avx2")
// 293206GT
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <unordered_set>
#include <stack>
#include <string>
#include<algorithm>
#include <random>
#include <bitset>
#include <chrono>

typedef long long ll;
#define int ll
using namespace std;
#define put(a) cout << (a) << '\n'
#define sqr(x) (x) * (x)
typedef pair<int, int> pii;
typedef long double ld;
typedef pair<ld, ld> pld;
typedef unsigned long long ull;

typedef vector<int> vi;
typedef vector<pii> vpii;
#define rep(x, y, a) for (int x = (y); x < (int)(a); ++x)
#define all(a) a.begin(), a.end()
#define chkmax(a, b) a = max(a, (b))
#define chkmin(a, b) a = min(a, (b))

namespace IO {

    template<class A, class B>
    ostream &operator<<(ostream &out, vector<pair<A, B>> a);

    template<class A>
    ostream &operator<<(ostream &out, vector<A> a);

    template<class A, class B>
    ostream &operator<<(ostream &out, pair<A, B> a) {
        out << a.first << " " << a.second;
        return out;
    }

    template<class A, class B>
    ostream &operator<<(ostream &out, vector<pair<A, B>> a) {
        for (pair<A, B> x: a)
            out << x.first << " " << x.second << '\n';
        return out;
    }

    template<class A>
    ostream &operator<<(ostream &out, vector<A> a) {
        for (A x: a) out << x << ' ';
        return out;
    }

    template<class A, class B>
    istream &operator>>(istream &in, pair<A, B> &a) {
        in >> a.first >> a.second;
        return in;
    }

    template<class A>
    istream &operator>>(istream &in, vector<A> &a) {
        for (A &x: a) in >> x;
        return in;
    }
}
using namespace IO;


mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int N = 51;
const int M = 23;
int dp_pref[N][M];
int dp_suf[N][M];
vector<string>s;
int c[N];
int n;
int used_pref[N][M];
int used_suf[N][M];
const int INF = 2e18;
int is_pal(string st) {
    rep(i, 0, st.size() / 2) if (st[i] != st[st.size() - i - 1]) return 0;
    return 1;
}
void dfs(int f, int i, int j) {
    if (j == 0) return;
    if (f) {
        if (used_pref[i][j]) return;
        used_pref[i][j] = 1;
        rep(st, 0, n) {
            if (s[st].size() < j) {
                int fl = is_pal(s[i].substr(j - s[st].size(), s[st].size()) + s[st]);
                if (fl) {
                    dfs(1, i, j - s[st].size());
                    chkmin(dp_pref[i][j], dp_pref[i][j - s[st].size()] + c[st]);
                }
            } else {
                int fl = is_pal(s[i].substr(0, j) + s[st].substr(0, j));
                if (fl) {
                    dfs(0, st, s[st].size() - j);
                    chkmin(dp_pref[i][j], dp_suf[st][s[st].size() - j] + c[st]);
                }
            }
        }
    } else {
        if (used_suf[i][j]) return;

        used_suf[i][j] = 1;
        rep(st, 0, n) {
            if (s[st].size() < j) {
                int fl = is_pal(s[st] + s[i].substr(s[i].size() - j, s[st].size()));
                if (fl) {
                    dfs(0, i, j - s[st].size());
                    chkmin(dp_suf[i][j], dp_suf[i][j - s[st].size()] + c[st]);
                }
            } else {
                int fl = is_pal(s[st].substr(s[st].size() - j, j) + s[i].substr(s[i].size() - j, j));
                if (fl) {
                    dfs(1, st, s[st].size() - j);
                    chkmin(dp_suf[i][j], dp_pref[st][s[st].size() - j] + c[st]);
                }
            }
        }
    }
}
void solve() {
    cin >> n;
    s.resize(n);
rep(i, 0, N) rep(j, 0, M){
    dp_pref[i][j] = INF;
    dp_suf[i][j] = INF;
}
    rep(i, 0, n) dp_pref[i][0] = 0;
    rep(i, 0, n) dp_suf[i][0] = 0;
    rep(i, 0, n)cin >> s[i] >> c[i];
    int ans = INF;
    rep(i, 0, n) {
        dfs(0, i, s[i].size());
        dfs(1, i, s[i].size());
        chkmin(ans, dp_pref[i][s[i].size()] + c[i]);
        chkmin(ans, dp_suf[i][s[i].size()] + c[i]);
        rep(st, 0, s[i].size() / 2) {
            if (is_pal(s[i].substr(0, st * 2 + 1))) {
                dfs(0, i, s[i].size() - st * 2 - 1);
                chkmin(ans, dp_suf[i][s[i].size() - st * 2 - 1] + c[i]);
            }
            if (is_pal(s[i].substr(0, st * 2 + 2))) {
                dfs(0, i, s[i].size() - st * 2 - 2);
                chkmin(ans, dp_suf[i][s[i].size() - st * 2 - 2] + c[i]);
            }
        }
        rep(st, s[i].size() / 2, s[i].size()) {
            int len = (s[i].size() - st - 1) * 2;
            if (is_pal(s[i].substr(st - len / 2 + 1, len))) {
                dfs(1, i, s[i].size() - len);
                chkmin(ans, dp_pref[i][s[i].size() - len] + c[i]);
            }
            len = (s[i].size() - st - 1) * 2 + 1;
            if (is_pal(s[i].substr(st - len / 2, len))) {
                dfs(1, i, s[i].size() - len);
                chkmin(ans, dp_pref[i][s[i].size() - len] + c[i]);
            }
        }
    }
    put(ans < INF?ans:-1);
}


signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout.precision(30);
//    freopen("input.txt", "r", stdin);
    int q = 1;
//    cin >> q;

    while (q--) solve();
}


Measured memory_bytes: 3244