#include <bits/stdc++.h>

using namespace std;
using ll = long long;
using Graph = vector<vector<int>>;
using WGraph = vector<vector<pair<int, ll>>>;

template<class T>inline bool chmax(T &a, const T &b) { if (b > a) { a = b; return true; } return false; }
template<class T>inline bool chmin(T &a, const T &b) { if (b < a) { a = b; return true; } return false; }

constexpr int dx[4] = {-1, 0, 0, 1}, dy[4] = {0, -1, 1, 0};
constexpr int INF = 1e9;
constexpr int MOD = 1e9 + 7;
constexpr long long LINF = 1e18;
constexpr double EPS = 1e-10;
constexpr double PI = M_PI;

long long Dijkstra(const WGraph &G, const int s, const int t) {
    int n = (int)G.size();
    std::vector<long long> dis(n, LINF);
    dis[s] = 0;
    using P = std::pair<long long, int>;
    std::priority_queue<P, std::vector<P>, std::greater<P>> que;
    que.push(std::make_pair(0, s));

    while (!que.empty()) {
        auto p = que.top();
        que.pop();
        int v = p.second;
        if (dis[v] < p.first) continue;
        for (auto e : G[v]) {
            if (dis[e.first] > dis[v] + e.second) {
                dis[e.first] = dis[v] + e.second;
                que.push(std::make_pair(dis[e.first], e.first));
            }
        }
    }
    return dis[t] == LINF ? -1 : dis[t];
}

void solve() {
    int N;
    cin >> N;
    vector<string> S(N);
    vector<int> C(N);
    for (int i=0; i<N; ++i) cin >> S[i] >> C[i];

    vector<string> Srev = S;
    for (int i=0; i<N; ++i) reverse(Srev[i].begin(), Srev[i].end());

    map<string, int> forw, rev;
    int cnt = 2;
    for (string s : S) {
        string tmp = "";
        for (auto iter=s.rbegin(); iter!=s.rend(); ++iter) {
            tmp = *iter + tmp;
            forw[tmp] = cnt++;
        }
    }
    for (string s : Srev) {
        string tmp = "";
        for (auto iter=s.rbegin(); iter!=s.rend(); ++iter) {
            tmp = *iter + tmp;
            rev[tmp] = cnt++;
        }
    }

    // 0 - start, 1 - end
    WGraph G(cnt);

    // from start
    for (int i=0; i<N; ++i) {
        int idx = forw[S[i]];
        G[0].push_back({idx, C[i]});
    }

    // to end
    for (auto p : forw) {
        string s = p.first;
        int idx = p.second;
        string t = s;
        reverse(t.begin(), t.end());
        if (s == t) {
            G[idx].push_back({1, 0});
        }
    }
    for (auto p : rev) {
        string s = p.first;
        int idx = p.second;
        string t = s;
        reverse(t.begin(), t.end());
        if (s == t) {
            G[idx].push_back({1, 0});
        }
    }

    // other
    for (auto p : forw) {
        string s = p.first;
        int idx = p.second;
        for (int i=0; i<N; ++i) {
            string t = Srev[i];
            if (s.size() == t.size()) {
                if (s == t) G[idx].push_back({1, C[i]});
            } else if (s.size() > t.size()) {
                if (s.substr(0, t.size()) == t) G[idx].push_back({forw[s.substr(t.size(), s.size())], C[i]});
            } else {
                if (s == t.substr(0, s.size())) G[idx].push_back({rev[t.substr(s.size(), t.size())], C[i]});
            }
        }
    }
    for (auto p : rev) {
        string s = p.first;
        int idx = p.second;
        for (int i=0; i<N; ++i) {
            string t = S[i];
            if (s.size() == t.size()) {
                if (s == t) G[idx].push_back({1, C[i]});
            } else if (s.size() > t.size()) {
                if (s.substr(0, t.size()) == t) G[idx].push_back({rev[s.substr(t.size(), s.size())], C[i]});
            } else {
                if (s == t.substr(0, s.size())) G[idx].push_back({forw[t.substr(s.size(), t.size())], C[i]});
            }
        }
    }

    cout << Dijkstra(G, 0, 1) << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(20);

    solve();

    return 0;
}


Measured memory_bytes: 3908