#include <algorithm>
#include <cassert>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
#include <limits.h>
using namespace std;
typedef long long ll;
template<class T>
inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return true;
    }
    return false;
}
template<class T>
inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return true;
    }
    return false;
}
const ll INF = LONG_LONG_MAX / 2;
vector<string> ss;
vector<int> cs;
vector<vector<int>> v_to_id;
map<int, pair<string, int>> id_to_v;
vector<vector<pair<int, ll>>> graph;
vector<ll> dists;
void solve(const int N, const int vn) {
    typedef pair<ll, int> Elem;
    priority_queue<Elem, vector<Elem>, greater<Elem>> q;
    dists.resize(vn, INF);
    for (int i = 0; i < N; i++) {
        dists[v_to_id[i][0]] = cs[i];
        q.push(make_pair(cs[i], v_to_id[i][0]));
    }
    while (!q.empty()) {
        Elem elem = q.top();
        q.pop();
        ll cur_dist = elem.first;
        int cur_v = elem.second;
        if (cur_dist > dists[cur_v]) {
            continue;
        }

        for (auto edge : graph[cur_v]) {
            int next_v = edge.first;
            ll next_dist = cur_dist + edge.second;
            if (next_dist < dists[next_v]) {
                dists[next_v] = next_dist;
                q.push(make_pair(next_dist, next_v));
            }
        }
    }
}
int main() {
    int N;
    cin >> N;
    ss.resize(N);
    cs.resize(N);
    for (int i = 0; i < N; i++) {
        cin >> ss[i] >> cs[i];
    }
    for (int i = 0; i < N; i++) {
        string s = ss[i];
        reverse(s.begin(), s.end());
        ss.push_back(s);
        cs.push_back(cs[i]);
    }
    int n = 1;
    v_to_id.resize(N * 2);
    for (int i = 0; i < N * 2; i++) {
        int l = (int) ss[i].size();
        v_to_id[i].resize(l);
        for (int j = 0; j < l; j++) {
            v_to_id[i][j] = n;
            id_to_v[n] = make_pair(ss[i], j);
            n++;
        }
    }
    graph.resize(n);
    for (int i = 0; i < N * 2; i++) {
        int l = (int) ss[i].size();
        for (int j = 0; j < l; j++) {
            int from = v_to_id[i][j];
            for (int ni = 0; ni < N * 2; ni++) {
                if (i / N == ni / N) {
                    continue;
                }
                int nl = (int) ss[ni].size();
                int l_covered = min(l - j, nl);
                if (ss[i].substr(j, l_covered) != ss[ni].substr(0, l_covered)) {
                    continue;
                }
                int to;
                if (nl > l_covered) {
                    to = v_to_id[ni][l_covered];
                } else if (l > j + l_covered) {
                    to = v_to_id[i][j + l_covered];
                } else {
                    to = 0;
                }
                graph[from].push_back(make_pair(to, cs[ni]));
            }
        }
    }
    solve(N, n);
    ll ans = dists[0];
    for (int i = 0; i < N * 2; i++) {
        int l = (int) ss[i].size();
        for (int j = 0; j < l; j++) {
            string t = ss[i].substr(j);
            string u = t;
            reverse(u.begin(), u.end());
            if (t == u)
                chmin(ans, dists[v_to_id[i][j]]);
        }
    }

    if (ans == INF) {
        cout << -1 << endl;
    } else {
        cout << ans << endl;
    }

    return 0;
}


Measured memory_bytes: 3868