#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define MOD 1000000007
#define MOD2 998244353
#define PRIM 3
#define INF (1 << 29)
#define LINF (1LL << 60)
#define EPS (1e-10)
#define PI 3.1415926535897932384626433832795028
typedef long long Int;
typedef pair<Int, Int> P;
typedef long double Real;
typedef complex<Real> CP;

Int EXACTLY = 2100;
Int S = 2101, T = 2102;

Int toHash(Int ind, Int len, Int reversed)
{
    if (len == 0)
        return EXACTLY;
    return ind * 40 + len * 2 + reversed;
}
Int n;
string s[55], s_rev[55];
Int c[55];

vector<P> edge[2200];

vector<Int> dijkstra(Int s)
{
    vector<Int> dist(2200, LINF);
    dist[s] = 0;
    priority_queue<P, vector<P>, greater<P>> pq;
    pq.push(P(0, s));
    while (!pq.empty()) {
        P tmp = pq.top();
        pq.pop();
        Int d = tmp.first;
        Int from = tmp.second;
        if (dist[from] < d)
            continue;
        for (auto e : edge[from]) {
            Int to = e.first;
            Int cost = e.second;
            if (dist[to] > dist[from] + cost) {
                dist[to] = dist[from] + cost;
                pq.push(P(dist[to], to));
            }
        }
    }
    return dist;
}

int main()
{
    cin >> n;
    for (Int i = 0; i < n; i++) {
        cin >> s[i] >> c[i];
        s_rev[i] = s[i];
        reverse(s_rev[i].begin(), s_rev[i].end());
        Int to = toHash(i, s[i].size(), 0);
        edge[S].push_back(P(to, c[i]));
    }

    edge[EXACTLY].push_back(P(T, 0));

    for (Int ind1 = 0; ind1 < n; ind1++) {
        for (Int len1 = 1; len1 <= s[ind1].size(); len1++) {
            {
                Int l = s[ind1].size() - len1;
                Int r = s[ind1].size() - 1;
                bool palin = true;
                for (Int i = l; i <= r; i++) {
                    if (s[ind1][i] != s[ind1][l + r - i])
                        palin = false;
                }
                if (palin) {
                    edge[toHash(ind1, len1, 0)].push_back(P(T, 0));
                    //                    cout << ind1 << " " << len1 << endl;
                }
            }
            {
                Int l = s[ind1].size() - len1;
                Int r = s[ind1].size() - 1;
                bool palin = true;
                for (Int i = l; i <= r; i++) {
                    if (s_rev[ind1][i] != s_rev[ind1][l + r - i])
                        palin = false;
                }
                if (palin) {
                    edge[toHash(ind1, len1, 1)].push_back(P(T, 0));
                    //                    cout << ind1 << " R " << len1 << endl;
                }
            }

            for (Int indE = 0; indE < n; indE++) {
                // Ue
                bool ok = true;
                Int l = min(len1, (Int)s_rev[indE].size());
                for (Int i = 0; i < l; i++) {
                    if (s[ind1][s[ind1].size() - len1 + i] != s_rev[indE][i])
                        ok = false;
                }
                if (ok) {
                    Int from = toHash(ind1, len1, 0);
                    Int to;
                    if (l == len1) {
                        to = toHash(indE, s_rev[indE].size() - l, 1);
                    }
                    else {
                        to = toHash(ind1, len1 - l, 0);
                    }
                    edge[from].push_back(P(to, c[indE]));
                }

                // Shita
                ok = true;
                l = min(len1, (Int)s[indE].size());
                for (Int i = 0; i < l; i++) {
                    if (s_rev[ind1][s_rev[ind1].size() - len1 + i] !=
                        s[indE][i])
                        ok = false;
                }
                if (ok) {
                    Int from = toHash(ind1, len1, 1);
                    Int to;
                    if (l == len1) {
                        to = toHash(indE, s[indE].size() - l, 0);
                    }
                    else {
                        to = toHash(ind1, len1 - l, 1);
                    }
                    edge[from].push_back(P(to, c[indE]));
                }
            }
        }
    }

    auto dist = dijkstra(S);
    if (dist[T] == LINF)
        dist[T] = -1;
    cout << dist[T] << endl;
    /*    for (int i = 0; i < 2200; i++) {
            if (dist[i] != LINF) {
                cout << i << " " << dist[i] << endl;
            }
            }*/

    return 0;
}

Measured memory_bytes: 3240