#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

#ifdef _LOCAL_DEBUG
#include "templates/debug.h"
#else
#define debug(...)
#endif

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

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    vector<string> strs(n);
    vector<ll> cost(n);
    for (int i = 0; i < n; i++) {
        cin >> strs[i] >> cost[i];
    }
    // map<pair<string, string>, ll> dis;
    map<pair<string, string>, ll> dis;
    queue<tuple<string, string, ll>> q;
    ll ans = 2e18;
    for (int i = 0; i < n; i++) {
        if (is_palindrome(strs[i]))
            ans = min(ans, cost[i]);
        else {
            q.push({strs[i], string(""), cost[i]});
            dis[{strs[i], string("")}] = cost[i];
        }
    }
    while (q.size()) {
        auto [s1, s2, d] = q.front();
        q.pop();
        if (s2.empty()) {
            assert(s1.size() > 0);
            for (int i = 0; i < n; i++) {
                size_t m = min(s1.size(), strs[i].size());
                bool ok = true;
                for (size_t j = 0, k = strs[i].size() - 1; j < m; j++, k--) {
                    if (s1[j] != strs[i][k]) {
                        ok = false;
                        break;
                    }
                }
                if (ok) {
                    if (s1.size() == strs[i].size()) {
                        ans = min(ans, d + cost[i]);
                    } else if (s1.size() < strs[i].size()) {
                        string new_str = strs[i].substr(0, strs[i].size() - m);
                        if (is_palindrome(new_str))
                            ans = min(ans, d + cost[i]);
                        else if (auto it = dis.find({"", new_str});
                                 it == dis.end() || it->second > d + cost[i]) {
                            q.push({"", new_str, d + cost[i]});
                            dis[{"", new_str}] = d + cost[i];
                        }
                    } else {
                        string new_str = s1.substr(m);
                        if (is_palindrome(new_str))
                            ans = min(ans, d + cost[i]);
                        else if (auto it = dis.find({"", new_str});
                                 it == dis.end() || it->second > d + cost[i]) {
                            q.push({new_str, "", d + cost[i]});
                            dis[{new_str, ""}] = d + cost[i];
                        }
                    }
                }
            }
        } else {
            assert(s1.empty());
            for (int i = 0; i < n; i++) {
                size_t m = min(strs[i].size(), s2.size());
                bool ok = true;
                for (size_t k = s2.size() - 1, j = 0; j < m; j++, k--) {
                    if (strs[i][j] != s2[k]) {
                        ok = false;
                        break;
                    }
                }
                if (ok) {
                    if (strs[i].size() == s2.size()) {
                        ans = min(ans, d + cost[i]);
                    } else if (strs[i].size() < s2.size()) {
                        string new_str = s2.substr(0, s2.size() - m);
                        if (is_palindrome(new_str))
                            ans = min(ans, d + cost[i]);
                        else if (auto it = dis.find({"", new_str});
                                 it == dis.end() || it->second > d + cost[i]) {
                            q.push({"", new_str, d + cost[i]});
                            dis[{"", new_str}] = d + cost[i];
                        }
                    } else {
                        string new_str = strs[i].substr(m);
                        if (is_palindrome(new_str))
                            ans = min(ans, d + cost[i]);
                        else if (auto it = dis.find({"", new_str});
                                 it == dis.end() || it->second > d + cost[i]) {
                            q.push({new_str, "", d + cost[i]});
                            dis[{new_str, ""}] = d + cost[i];
                        }
                    }
                }
            }
        }
    }
    if (ans >= 2e18)
        cout << "-1\n";
    else
        cout << ans << '\n';
    return 0;
}

Measured memory_bytes: 3676