#include <vector>
#include <stack>
#include <queue>
#include <list>
#include <bitset>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <algorithm>
#include <numeric>
#include <iostream>
#include <iomanip>
#include <string>
#include <chrono>
#include <random>
#include <cmath>
#include <cassert>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <functional>
#include <sstream>

using namespace std;

struct State {
    State(int i = 0, int l = 0, int d = 0) : idx(i), len(l), dir(d) {

    } 
    int idx;
    int len;
    int dir;
};


int main(int argc, char** argv) {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(12);


    int n;
    cin >> n;
    vector<string> S(n);
    vector<long long> C(n);
    for (int i = 0; i < n; ++i) {
        cin >> S[i] >> C[i];
    }

    int m = 0;
    for (auto& s : S) {
        m = max(m, (int) s.length());
    }

    vector<State> states;
    map<int, int> indices;

    auto encode = [&](int i, int p, int d) {
        long long res = i << 10 | p << 1 | d;
        return res;
    };

    auto decode = [&](int x) -> vector<int> {
        int i = x >> 10;
        int p = (x >> 1) & ((1 << 8) - 1);
        int d = x & 1;
        cout << "state: " << i << " " << p  << "(" << S[i].length() << ")" << " " << d << endl;
        return {i, p, d};
    };

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j <= S[i].length(); ++j) {
            for (int k = 0; k < 2; ++k) {
                indices[encode(i, j, k)] = states.size();
                states.emplace_back(i, j, k);
            }
        }
    }


    auto isPalindrome = [&](string s) {
        if (s.empty()) {
            return true;
        }
        string t = s;
        reverse(t.begin(), t.end());
        return s == t;
    };


    auto ok = [&](string s, string t, int u, int v, int dir) {
        int n = s.length();
        int m = t.length();
        if (dir == 0) {
            reverse(t.begin(), t.end());
            for (int i = 0; i < n && i < m; ++i) {
                if (s[i] != t[i]) {
                    return -1;
                }
            }
        } else {
            reverse(s.begin(), s.end());
            for (int i = 0; i < n && i < m; ++i) {
                if (s[i] != t[i]) {
                    return -1;
                }
            }
        }

        if (n >= m) {
            int len = S[u].length() - (n - m);
            if (isPalindrome(s.substr(m))) {
                len = S[u].length();
            }
            return indices[encode(u, len, dir)];
        } else {
            int len = n;
            if (isPalindrome(t.substr(n))) {
                len = m;
            }
            return indices[encode(v, len, dir ^ 1)];
        }
    };


    int N = states.size();
    vector<vector<pair<int,int>>> graph(N);
    for (int i = 0; i < N; ++i) {
        int idx = states[i].idx;
        int len = states[i].len;
        int dir = states[i].dir;
        if (len < S[idx].length()) {
            string s;
            if (dir == 0) {
                s = S[idx].substr(len);
            } else {
                s = S[idx].substr(0, S[idx].length() - len);
            }
            for (int j = 0; j < n; ++j) {
                auto v = ok(s, S[j], idx, j, dir);
                if (v >= 0) {
                    // cout << i << "->" << v << " " << C[j] << endl;
                    graph[i].emplace_back(v, C[j]);   
                }
            }
        }
    }
    

    const long long INF = 1LL << 61;

    // vector<vector<vector<long long>>> dis(n, vector<vector<int>>(m + 1, vector<int>(2, INF)));
    vector<long long> dis(N + 1, INF);

    using PII = pair<long long, int>;
    priority_queue<PII, vector<PII>, greater<PII>> pq;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < 2; ++j) {
            int u = indices[encode(i, 0, j)];
            dis[u] = C[i];
            pq.emplace(dis[u], u);
        }
    }

    while (!pq.empty()) {
        int u = pq.top().second;
        long long d = pq.top().first;
        pq.pop();

        // auto V = decode(u);
        // cout << V[0] << "," << V[1] << "," << V[2] << " " << d << endl;
        if (dis[u] != d) {
            continue;
        }

        for (auto& e : graph[u]) {
            int v = e.first;
            long long w = e.second;
            long long nd = d + w;
            if (nd < dis[v]) {
                dis[v] = nd;
                pq.emplace(nd, v);
            }
        }
    }

    long long res = 1LL << 62;

    for (int i = 0; i < n; ++i) {
        int m = S[i].length();
        for (int j = 0; j < 2; ++j) {
            int v = indices[encode(i, m, j)];
            res = min(res, dis[v]);
        }
    }

    for (int i = 0; i < n; ++i) {
        if (isPalindrome(S[i])) {
            res = min(res, C[i]);
        }
    }
    if (res >= INF) {
        res = -1;
    }

    cout << res << '\n';

    return 0;
}

Measured memory_bytes: 3868