#include <iostream>
#include <string>
#include <string_view>
#include <vector>
#include <queue>
#include <utility>
#include <limits>
using i64 = long long;
using P = std::pair<i64, int>;

int main() {
    constexpr i64 inf = std::numeric_limits<i64>::max();
    int n;
    std::cin >> n;
    std::vector<std::pair<std::string, i64>> v;
    for (int i = 0; i < n; i++) {
        std::string s;
        i64 c;
        std::cin >> s >> c;
        v.emplace_back(s, c);
    }

    std::vector<int> ss { 0 };
    for (const auto &e : v) ss.push_back(ss.back() + e.first.size());

    const int slen = ss.back(), s = 2 * slen, t = 2 * slen + 1;
    std::vector<std::vector<std::pair<int, i64>>> g(t + 1);
    std::vector<i64> dist(t + 1, inf);
    dist[s] = 0;

    // fprintf(stderr, "slen = %d, s = %d, t = %d\n", slen, s, t);

    for (int i = 0; i < n; i++) {
        g[s].emplace_back(ss[i], v[i].second);
        g[s].emplace_back(slen + ss[i], v[i].second);

        std::string_view s = v[i].first;
        const int ilen = s.size();
        for (int l = 0; l < s.size(); l++) {
            for (int j = 0; j < n; j++) {
                const std::string_view sv = v[j].first;
                const int jlen = sv.size();

                // i: prefix, j: suffix
                int p = 0;
                while (l + p < ilen && p < jlen && s[l + p] == sv[jlen - 1 - p]) p++;
                bool lf = l + p == ilen, rf = p == jlen;
                if (lf && rf) g[ss[i] + l].emplace_back(t, v[j].second);
                else if (lf) g[ss[i] + l].emplace_back(slen + ss[j] + p, v[j].second);
                else if (rf) g[ss[i] + l].emplace_back(ss[i] + l + p, v[j].second);

                // i: suffix, j: prefix
                p = 0;
                while (l + p < ilen && p < jlen && s[ilen - 1 - l - p] == sv[p]) p++;
                lf = l + p == ilen, rf = p == jlen;
                if (lf && rf) g[slen + ss[i] + l].emplace_back(t, v[j].second);
                else if (lf) g[slen + ss[i] + l].emplace_back(ss[j] + p, v[j].second);
                else if (rf) g[slen + ss[i] + l].emplace_back(slen + ss[i] + l + p, v[j].second);
            }
        }
    }

    // for (int i = 0; i < g.size(); i++) {
    //     for (const auto [to, cost] : g[i]) fprintf(stderr, "%d -> %d w/ %lld\n", i, to, cost);
    // }

    std::priority_queue<P, std::vector<P>, std::greater<>> q;
    q.emplace(0, s);
    while (!q.empty()) {
        const auto [d, v] = q.top();
        q.pop();
        if (dist[v] < d) continue;
        for (const auto [to, cost] : g[v]) {
            const i64 nd = d + cost;
            if (dist[to] <= nd) continue;
            dist[to] = nd;
            q.emplace(nd, to);
        }
    }

    auto judge = [](std::string_view s) {
        const int len = s.size();
        for (int i = 0; i < len; i++) if (s[i] != s[len - 1 - i]) return false;
        return true;
    };

    i64 ret = dist[t];
    for (int i = 0; i < n; i++) {
        const std::string_view s = v[i].first;
        const int len = s.size();
        for (int j = 0; j < len; j++) {
            // prefix
            if (judge(s.substr(j)) && ret > dist[ss[i] + j]) {
                ret = dist[ss[i] + j];
            }
            // suffix
            if (judge(s.substr(0, len - j)) && ret > dist[slen + ss[i] + j]) {
                ret = dist[slen + ss[i] + j];
            }
        }
    }

    std::cout << (ret == inf ? -1 : ret) << std::endl;

    return 0;
}


Measured memory_bytes: 3712