#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
#define REP(i,n) for (ll i = 0; i < (n); ++i)
#define RREP(i, n) for (ll i = (n) - 1; i >= 0; --i)
#define ALL(v) (v).begin(), (v).end()
template<class T>
using reverse_priority_queue = priority_queue<T, vector<T>, greater<T>>;

bool is_palindrome(const string& s){
    const ll n = s.size();
    for(ll i = 0; i <= n - 1 - i; ++i){
        if(s.at(i) != s.at(n - 1 - i)){ return false; }
    }
    return true;
}

bool is_ok(const string& left, const string& right){
    ll n = min(left.size(), right.size());
    REP(i, n){
        if(left.at(i) != right.at(right.size() - 1 - i)){
            return false;
        }
    }
    return true;
}

const string END_STR = "_END_";
const auto END_NODE = make_pair(END_STR, 0LL);

void minset(map<pair<string, ll>, ll>& m, const pair<string, ll>& key, ll val){
    if(m.count(key)){
        m[key] = min(m[key], val);
    }else{
        m[key] = val;
    }
}

int main(){
    ll n;
    cin >> n;
    vector<string> s(n);
    vector<ll> c(n);
    REP(i, n){
        cin >> s.at(i) >> c.at(i);
    }

    map<pair<string, ll>, map<pair<string, ll>, ll>> to;

    // empty -> some string
    REP(i, n){
        const auto& si = s.at(i);
        if(is_palindrome(si)){
            minset(to[{"", 0LL}], END_NODE, c.at(i));
        }else{
            REP(j, n){
                const auto& sj = s.at(j);
                if(!is_ok(si, sj)){ continue; }
                // cerr << "i, j=" << i << ", " << j << endl;
                if(si.size() > sj.size()){
                    const string nxt = si.substr(sj.size());
                    minset(to[{"", 0LL}], {nxt, 0}, c.at(i) + c.at(j));
                }else if(si.size() == sj.size()){
                    minset(to[{"", 0LL}], END_NODE, c.at(i) + c.at(j));
                }else{ // si.size() < sj.size()
                    const string nxt = sj.substr(0, sj.size() - si.size());
                    minset(to[{"", 0LL}], {nxt, 1}, c.at(i) + c.at(j));
                }
            }
        }
    }

    // prefix or suffix -> some string
    REP(i, n){
        const auto& si = s.at(i);
        for(ll l = 1; l <= si.size(); ++l){
            // left
            string t = si.substr(si.size() - l, l);
            pair<string, ll> cur_node = make_pair(t, 0LL);
            if(is_palindrome(t)){
                // cerr << "i=" << i << ", l=" << l << " t=" << t << ", is=" << is_palindrome(t) << endl;
                minset(to[cur_node], END_NODE, 0LL);
            }else{
                REP(j, n){
                    const auto& sj = s.at(j);
                    if(!is_ok(t, sj)){ continue; }
                    if(t.size() > sj.size()){
                        const string nxt = t.substr(sj.size());
                        minset(to[cur_node], {nxt, 0LL}, c.at(j));
                    }else if(t.size() == sj.size()){
                        minset(to[cur_node], END_NODE, c.at(j));
                    }else{ // t.size() < sj.size()
                        const string nxt = sj.substr(0, sj.size() - t.size());
                        minset(to[cur_node], {nxt, 1LL}, c.at(j));
                    }
                }
            }

            // right
            t = si.substr(0, l);
            cur_node = make_pair(t, 1LL);
            if(is_palindrome(t)){
                minset(to[cur_node], END_NODE, 0LL);
            }else{
                REP(j, n){
                    const auto& sj = s.at(j);
                    if(!is_ok(sj, t)){ continue; }
                    if(sj.size() > t.size()){
                        const string nxt = sj.substr(t.size());
                        minset(to[cur_node], {nxt, 0LL}, c.at(j));
                    }else if(sj.size() == t.size()){
                        minset(to[cur_node], END_NODE, c.at(j));
                    }else{ // t.size() > sj.size()
                        const string nxt = t.substr(0, t.size() - sj.size());
                        minset(to[cur_node], {nxt, 1LL}, c.at(j));
                    }
                }
            }
        }
    }

    // for(auto it = to.begin(); it != to.end(); ++it){
    //     cerr << it->first.first << ", " << it->first.second << endl;
    //     for(auto jt = it->second.begin(); jt != it->second.end(); ++jt){
    //         cerr << "  " << jt->first.first << ", " << jt->first.second << ": " << jt->second << endl;
    //     }
    // }

    // dijkstra
    map<pair<string, ll>, ll> dist;
    dist[{"", 0LL}] = 0;
    reverse_priority_queue<pair<ll, pair<string, ll>>> que;
    que.emplace(make_pair(0LL, make_pair("", 0LL)));
    while(!que.empty()){
        const auto q = que.top(); que.pop();
        const ll d = q.first;
        const auto& key = q.second;
        if(dist.count(key) != 0 && dist.at(key) < d){ continue; }
        for(auto it = to[key].begin(); it != to[key].end(); ++it){
            const ll d2 = d + it->second;
            if(dist.count(it->first) == 0 || dist[it->first] > d2){
                dist[it->first] = d2;
                que.emplace(make_pair(d2, it->first));
            }
        }
    }

    // cerr << "dist" << endl;
    // for(auto it = dist.begin(); it != dist.end(); ++it){
    //     cerr << it->first.first << ", " << it->first.second << " = " << it->second << endl;
    // }

    if(dist.count(END_NODE)){
        cout << dist[END_NODE] << endl;
    }else{
        cout << -1 << endl;
    }
    return 0;
}


Measured memory_bytes: 4084