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

#ifdef LOCAL
#define DEBUG(...) debug(#__VA_ARGS__, __VA_ARGS__);
#else
#define DEBUG(...) 6;
#endif

template<typename T, typename S> ostream& operator << (ostream &os, const pair<T, S> &p) {return os << "(" << p.first << ", " << p.second << ")";}
template<typename C, typename T = decay<decltype(*begin(declval<C>()))>, typename enable_if<!is_same<C, string>::value>::type* = nullptr>
ostream& operator << (ostream &os, const C &c) {bool f = true; os << "["; for (const auto &x : c) {if (!f) os << ", "; f = false; os << x;} return os << "]";}
template<typename T> void debug(string s, T x) {cerr << s << " = " << x << "\n";}
template<typename T, typename... Args> void debug(string s, T x, Args... args) {cerr << s.substr(0, s.find(',')) << " = " << x << " | "; debug(s.substr(s.find(',') + 2), args...);}

int c[50];
string s[50];

bool isPalindrome(const string &t) {
    int n = t.length();
    for (int i=0; i<n/2; i++)
        if (t[i] != t[n-i-1])
            return false;
    return true;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    int n;
    cin >> n;
    for (int i=0; i<n; i++)
        cin >> s[i] >> c[i];

    map<pair<string, int>, long long> dist;
    priority_queue<pair<long long, pair<string, int>>, vector<pair<long long, pair<string, int>>>, greater<pair<long long, pair<string, int>>>> pq;
    for (int i=0; i<n; i++) {
        dist[{s[i], 0}] = dist[{s[i], 1}] = c[i];
        pq.push({c[i], {s[i], 0}});
        pq.push({c[i], {s[i], 1}});
    }
    while (!pq.empty()) {
        long long d = pq.top().first;
        string mid = pq.top().second.first;
        int which = pq.top().second.second;
        pq.pop();
        if (dist.count({mid, which}) && d > dist[{mid, which}])
            continue;
        if (isPalindrome(mid)) {
            cout << d << "\n";
            return 0;
        }

        for (int i=0; i<n; i++) {
            if (which) {    // mid on right side, adding on left
                bool ok = true;
                for (int j=0; j<min(mid.length(), s[i].length()); j++)
                    if (mid[(int)mid.length()-j-1] != s[i][j]) {
                        ok = false;
                        break;
                    }
                if (ok) {
                    string ns = mid.length() < s[i].length() ? s[i].substr(mid.length()) : mid.length() == s[i].length() ? "" : mid.substr(0, mid.length() - s[i].length());
                    int side = mid.length() > s[i].length();
                    if (!dist.count({ns, side}) || d + c[i] < dist[{ns, side}]) {
                        dist[{ns, side}] = d + c[i];
                        pq.push({dist[{ns, side}], {ns, side}});
                    }
                }
            } else {    // mid on left, adding on right
                bool ok = true;
                for (int j=0; j<min(mid.length(), s[i].length()); j++)
                    if (mid[j] != s[i][(int)s[i].length()-j-1]) {
                        ok = false;
                        break;
                    }
                if (ok) {
                    string ns = mid.length() < s[i].length() ? s[i].substr(0, s[i].length() - mid.length()) : mid.length() == s[i].length() ? "" : mid.substr(s[i].length());
                    int side = mid.length() < s[i].length();
                    if (!dist.count({ns, side}) || d + c[i] < dist[{ns, side}]) {
                        dist[{ns, side}] = d + c[i];
                        pq.push({dist[{ns, side}], {ns, side}});
                    }
                }
            }
        }
    }
    cout << "-1\n";

    return 0;
}


Measured memory_bytes: 3792