#include <bits/stdc++.h>

#ifdef DEBUG
#define DEB(x) x
#else
#define DEB(x)
#endif

#define FOR(i,a,b) for (int i=(a);i<(b);++i)
#define REP(i,n) for (int i=0;i<(n);++i)

using namespace std;

using ll = long long;

template <class T, class U> void amin(T& x, U y) {if (x > y) x = y;}

bool is_palindrome(const string &s) {
    int i = 0;
    int j = s.size() - 1;
    while (i < j) {
        if (s[i++] != s[j--])
            return false;
    }
    return true;
}

int main() {

    cin.tie(0);
    ios::sync_with_stdio(false);

    using P = pair<ll, int>;
    using Edge = pair<int, int>;
    using Graph = vector<vector<Edge>>;

    int M;
    cin >> M;
    vector<string> S(2 * M);
    vector<int> C(2 * M);
    REP(i, M) {
        cin >> S[i] >> C[i];
        S[M + i] = string(S[i].rbegin(), S[i].rend());
        C[M + i] = C[i];
    }

    int N = 1;
    vector<vector<int>> id(2 * M);
    REP(i, 2 * M) {
        int L = S[i].size();
        id[i].resize(L);
        REP(j, L) {
            id[i][j] = N++;
        }
    }

    Graph g(N);
    REP(i, 2 * M) {
        int j_start = i < M ? M : 0;
        int j_end = j_start + M;
        int Li = S[i].size();
        FOR(j, j_start, j_end) {
            REP(pi, Li) {
                string s = S[i].substr(pi);
                string &t = S[j];
                int n_match = 0;
                int L = min(s.size(), t.size());
                while (n_match < L && s[n_match] == t[n_match]) {
                    ++n_match;
                }
                if (n_match != L) {
                    continue;
                }
                int from = id[i][pi];
                int to;
                DEB(printf("from S[%d][%d:] = %s\n", i, pi, s.c_str()););
                DEB(printf("counterpart S[%d] = %s\n", j, t.c_str()););
                if (s.size() < t.size()) {
                    to = id[j][n_match];
                    DEB(printf("to S[%d][%d:] = %s\n", j, n_match, t.substr(n_match).c_str()););
                } else if (s.size() > t.size()) {
                    to = id[i][pi + n_match];
                    DEB(printf("to S[%d][%d:] = %s\n", i, pi + n_match, s.substr(n_match).c_str()););
                } else {
                    to = 0;
                    DEB(printf("to empty string\n"););
                }
                DEB(printf("\n"););
                g[from].emplace_back(to, C[j]);
            }
        }
    }


    constexpr ll INF = LLONG_MAX / 2;

    vector<ll> dp(N, INF);
    priority_queue<P, vector<P>, greater<P>> q;
    REP(i, M) {
        int v = id[i][0];
        dp[v] = C[i];
        q.emplace(dp[v], v);
    }
    while (!q.empty()) {
        auto [d, u] = q.top();
        q.pop();
        if (d > dp[u]) continue;
        for (auto [v, cost]: g[u]) {
            ll d_next = d + cost;
            if (dp[v] > d_next) {
                dp[v] = d_next;
                q.emplace(dp[v], v);
            }
        }
    }

    ll result = dp[0];
    REP(i, 2 * M) {
        int L = S[i].size();
        REP(j, L) {
            string s = S[i].substr(j);
            if (is_palindrome(s)) {
                amin(result, dp[id[i][j]]);
            }
        }
    }

    cout << (result == INF ? -1 : result) << endl;

    return 0;
}


Measured memory_bytes: 3740