#include <bits/stdc++.h>

#define task "F"
#define all(v) (v).begin(), (v).end()
#define rep(i, l, r) for (int i = (l); i <= (r); ++i)
#define Rep(i, r, l) for (int i = (r); i >= (l); --i)
#define DB(X) { cerr << #X << " = " << (X) << '\n'; }
#define DB1(A, _) { cerr << #A << "[" << _ << "] = " << (A[_]) << '\n'; }
#define DB2(A, _, __) { cerr << #A << "[" << _ << "][" << __ << "] = " << (A[_][__]) << '\n'; }
#define DB3(A, _, __, ___) { cerr << #A << "[" << _ << "][" << __ << "][" << ___ << "] = " << (A[_][__][___]) << '\n'; }
#define PR(A, l, r) { cerr << '\n'; rep(_, l, r) DB1(A, _); cerr << '\n';}
#define SZ(x) ((int)(x).size())
#define pb push_back
#define eb emplace_back
#define pf push_front
#define F first
#define S second
#define by(x) [](const auto& a, const auto& b) { return a.x < b.x; } // sort(arr, arr + N, by(a));
#define next ___next
#define prev ___prev
#define y1 ___y1
#define left ___left
#define right ___right
#define y0 ___y0
#define div ___div
#define j0 ___j0
#define jn ___jn

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using namespace std;
typedef pair<int, int> ii;
typedef pair<ii, int> iii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<ll> vl;
const int N = 52;
int n, cost[N], nid = 0;
ll d[8003];
string s[N];
map<string, int> mp[2];
struct State
{
    string x = "";
    int side; // 0 is left, 1 is right
    ll cost;
    State() {}
    State(string _x, int _s, ll _c) : x(_x), side(_s), cost(_c) {}
};
bool operator < (const State &A, const State &B)
{
    return A.cost > B.cost;
}
void dijsktra()
{
    priority_queue<State> pq;
    string tmp = "";
    mp[0][tmp] = mp[1][tmp] = 0;
    fill(d, d + 8003, 1e18);
    rep(i, 1, n)
    {
        rep(c, 0, SZ(s[i]) - 1)
        {
            bool ok = 1, ok1 = 1;
            rep(j, 1, min(c, SZ(s[i]) - c))
            {
                if (s[i][c - j] != s[i][c + j - 1]) ok = 0;
                if (c + j < SZ(s[i]) && s[i][c - j] != s[i][c + j]) ok1 = 0;
            }

            if (ok)
            {
                if (c >= SZ(s[i]) - c)
                {
                    string tem = s[i].substr(0, 2 * c - SZ(s[i]));
                    if (mp[0].find(tem) == mp[0].end()) mp[0][tem] = ++nid;
                    if (d[mp[0][tem]] > cost[i]) d[mp[0][tem]] = cost[i], pq.push(State(tem, 0, cost[i]));
                }
                else
                {
                    string tem = s[i].substr(2 * c);
                    if (mp[1].find(tem) == mp[1].end()) mp[1][tem] = ++nid;
                    if (d[mp[1][tem]] > cost[i]) d[mp[1][tem]] = cost[i], pq.push(State(tem, 1, cost[i]));
                }
            }
            if (ok1)
            {
                if (c >= SZ(s[i]) - c - 1)
                {
                    string tem = s[i].substr(0, 2 * c - SZ(s[i]) + 1);
                    if (mp[0].find(tem) == mp[0].end()) mp[0][tem] = ++nid;
                    if (d[mp[0][tem]] > cost[i]) d[mp[0][tem]] = cost[i], pq.push(State(tem, 0, cost[i]));
                }
                else
                {
                    string tem = s[i].substr(2 * c + 1);
                    if (mp[1].find(tem) == mp[1].end()) mp[1][tem] = ++nid;
                    if (d[mp[1][tem]] > cost[i]) d[mp[1][tem]] = cost[i], pq.push(State(tem, 1, cost[i]));
                }
            }
        }
        if (mp[0].find(s[i]) == mp[0].end()) mp[0][s[i]] = ++nid;
        if (d[mp[0][s[i]]] > cost[i]) d[mp[0][s[i]]] = cost[i], pq.push(State(s[i], 0, cost[i]));
    }
    while (!pq.empty())
    {
        State u = pq.top();
        pq.pop();
        //DB(u.x);
        //DB(u.cost);
        //DB(u.side);
        if (u.cost != d[mp[u.side][u.x]]) continue;
        if (u.x.empty())
        {
            cout << d[0];
            exit(0);
        }
        rep(i, 1, n)
        {
            if (u.side) // add -> left
            {
                bool ok = 1;
                rep(j, 1, min(SZ(s[i]), SZ(u.x))) if (s[i][SZ(s[i]) - j] != u.x[j - 1])
                {
                    ok = 0;
                    break;
                }
                if (ok)
                {
                    if (SZ(s[i]) > SZ(u.x))
                    {
                        string tem = s[i].substr(0, SZ(s[i]) - SZ(u.x));
                        if (mp[0].find(tem) == mp[0].end()) mp[0][tem] = ++nid;
                        if (d[mp[0][tem]] > u.cost + cost[i]) d[mp[0][tem]] = u.cost + cost[i], pq.push(State(tem, 0, d[mp[0][tem]]));
                    } else
                    {
                        string tem = (u.x).substr(SZ(s[i]));
                        if (mp[1].find(tem) == mp[1].end()) mp[1][tem] = ++nid;
                        if (d[mp[1][tem]] > u.cost + cost[i]) d[mp[1][tem]] = u.cost + cost[i], pq.push(State(tem, 1, d[mp[1][tem]]));
                    }
                }
            } else // add -> right
            {
                bool ok = 1;
                rep(j, 1, min(SZ(s[i]), SZ(u.x))) if (u.x[SZ(u.x) - j] != s[i][j - 1])
                {
                    ok = 0;
                    break;
                }
                if (ok)
                {
                    if (SZ(s[i]) < SZ(u.x))
                    {
                        string tem = (u.x).substr(0, SZ(u.x) - SZ(s[i]));
                        DB(tem);
                        if (mp[0].find(tem) == mp[0].end()) mp[0][tem] = ++nid;
                        if (d[mp[0][tem]] > u.cost + cost[i]) d[mp[0][tem]] = u.cost + cost[i], pq.push(State(tem, 0, d[mp[0][tem]]));
                    } else
                    {
                        string tem = s[i].substr(SZ(u.x));
                        if (mp[1].find(tem) == mp[1].end()) mp[1][tem] = ++nid;
                        if (d[mp[1][tem]] > u.cost + cost[i]) d[mp[1][tem]] = u.cost + cost[i], pq.push(State(tem, 1, d[mp[1][tem]]));
                    }
                }
            }
        }
    }
    cout << -1;
}
int main()
{
    //freopen(task".in", "r", stdin);
    //freopen(task".out", "w", stdout);
    ios_base::sync_with_stdio(false); cin.tie(nullptr);
    cin >> n;
    rep(i, 1, n) cin >> s[i] >> cost[i];
    dijsktra();
    return 0;
}


Measured memory_bytes: 3872