#include <bits/stdc++.h>
using namespace std;
template <class T> inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T> inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return 1;
    }
    return 0;
}

#ifdef DEBUG
void debug() { cerr << "\n"; }
template <class T> void debug(const T &x) { cerr << x << "\n"; }
template <class T, class... Args> void debug(const T &x, const Args &... args) {
    cerr << x << " ";
    debug(args...);
}
template <class T> void debugVector(const vector<T> &v) {
    for(const T &x : v) {
        cerr << x << " ";
    }
    cerr << "\n";
}
#else
void debug() {}
template <class T, class... Args>
void debug(const T &x, const Args &... args) {}
template <class T> void debugVector(const vector<T> &v) {}
#endif

using ll = long long;
#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
const double EPS = 1e-7;
const int INF = 1 << 30;
const ll LLINF = 1LL << 60;
constexpr int MOD = 1000000007;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

//-------------------------------------

struct State {
    string s;
    ll cost;
    int type;
    State() = default;
    State(string s, ll cost, int type) : s(s), cost(cost), type(type) {}
    bool operator<(const State &state) const {
        return (this->cost > state.cost);
    }
};

using P = pair<string, int>;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N;
    cin >> N;
    vector<string> s(N);
    vector<ll> c(N);
    map<P, ll> cost;
    cost[P("", 0)] = cost[P("", 1)] = LLINF;
    priority_queue<State> que;
    for(int i = 0; i < N; i++) {
        cin >> s[i] >> c[i];
        int sz = s[i].size();
        for(int j = 0; j < sz; j++) {
            // 先頭
            string t = s[i].substr(0, j);
            string rev_t = t;
            reverse(ALL(rev_t));
            if(t == rev_t) {
                string tmp = s[i].substr(j, sz - j);
                if(cost.count(P(tmp, 0))) {
                    if(cost[P(tmp, 0)] > c[i]) {
                        cost[P(tmp, 0)] = c[i];
                        que.push(State(tmp, c[i], 0));
                    }
                } else {
                    cost[P(tmp, 0)] = c[i];
                    que.push(State(tmp, c[i], 0));
                }
            }
            // 末尾
            t = s[i].substr(j, sz - j);
            rev_t = t;
            reverse(ALL(rev_t));
            if(t == rev_t) {
                string tmp = s[i].substr(0, j);
                reverse(ALL(tmp));
                if(cost.count(P(tmp, 1))) {
                    if(cost[P(tmp, 1)] > c[i]) {
                        cost[P(tmp, 1)] = c[i];
                        que.push(State(tmp, c[i], 1));
                    }
                } else {
                    cost[P(tmp, 1)] = c[i];
                    que.push(State(tmp, c[i], 1));
                }
            }
        }
    }
    while(que.size()) {
        auto now = que.top();
        que.pop();
        if(cost[P(now.s, now.type)] < now.cost) {
            continue;
        }
        for(int i = 0; i < N; i++) {
            string t = s[i];
            if(now.type == 0) {
                reverse(ALL(t));
            }
            if(t.size() < now.s.size()) {
                string a = now.s.substr(0, t.size());
                if(t == a) {
                    string b = now.s.substr(t.size(), now.s.size() - t.size());
                    if(cost.count(P(b, now.type))) {
                        if(cost[P(b, now.type)] > now.cost + c[i]) {
                            cost[P(b, now.type)] = now.cost + c[i];
                            que.push(State(b, now.cost + c[i], now.type));
                        }
                    } else {
                        cost[P(b, now.type)] = now.cost + c[i];
                        que.push(State(b, now.cost + c[i], now.type));
                    }
                }
            } else {
                string a = t.substr(0, now.s.size());
                if(now.s == a) {
                    string b = t.substr(now.s.size(), t.size() - now.s.size());
                    if(cost.count(P(b, 1 - now.type))) {
                        if(cost[P(b, 1 - now.type)] > now.cost + c[i]) {
                            cost[P(b, 1 - now.type)] = now.cost + c[i];
                            que.push(State(b, now.cost + c[i], 1 - now.type));
                        }
                    } else {
                        cost[P(b, 1 - now.type)] = now.cost + c[i];
                        que.push(State(b, now.cost + c[i], 1 - now.type));
                    }
                }
            }
        }
    }
    ll ans = min(cost[P("", 0)], cost[P("", 1)]);
    cout << (ans == LLINF ? -1 : ans) << "\n";
}

Measured memory_bytes: 3836