#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
#define all(x) (x).begin(), (x).end()
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vector<bool>> vvb;
typedef vector<vector<int>> vvi;
typedef vector<vector<ll>> vvl;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void debugF(ostream &os) {os << endl;}
template <typename Head, typename... Tail>
void debugF(ostream &os, Head H, Tail... T) { os << " " << H; debugF(os, T...); }
#define debug(...) cout << "[" << #__VA_ARGS__ << "]:", debugF(cout, __VA_ARGS__)
template<typename T> istream &operator>>(istream &is, vector<T> &v){ for (auto &x : v) is >> x; return is; }
template<typename T> ostream &operator<<(ostream &os, vector<T> &v){ for(int i = 0; i < v.size(); os << (i>0 ? " ":"") << v[i++]); return os;}

vector<string> S;
vi W;

struct node{
    int idx, pos;
    bool suf;
    bool operator<(const node &other) const {
        if(idx < other.idx) return true;
        if(idx > other.idx) return false;
        if(pos < other.pos) return true;
        if(pos > other.pos) return false;
        if(suf == true && other.suf == false) return true;
        return false;
    }
};
node tNode;
int tId;

vector<vector<pair<int, int>>> g;
map<node,int> idNode;

bool isPalindrome(node &v){
    int l,r;
    string &s = S[v.idx];
    if(v.suf){
        l = v.pos;
        r = s.size() - 1;
    }else{
        l = 0;
        r = v.pos;
    }
    while(l < r){
        if(s[l] != s[r]) return false;
        l++;r--;
    }
    return true;
}

void buildN(node &v, int vId, int oi){
    int spos;
    int opos, dir;
    string &s = S[v.idx];
    string &other = S[oi];
    if(v.suf){
        spos = v.pos;
        opos = other.size()-1;
        dir = -1;
    }else{
        spos = v.pos;
        opos = 0; 
        dir = 1;
    }
    int i = spos, j = opos;
    while(i >= 0 && i < s.size() && j >= 0 && j < other.size()){
        if(s[i] != other[j]) return;
        i += (-1)*dir; j += dir;
    }
    bool sValid = i >= 0 && i < s.size();
    bool oValid = j >= 0 && j < other.size();
    node u = v;
    if(sValid){
        u.pos = i;
    }else if(oValid){
        u.idx = oi;
        u.suf = !v.suf;
        u.pos = j;
    }else{
        // equal
        u = tNode;
    }
    int uId = idNode[u];
    g[vId].push_back({uId, W[oi]});
}


class Dijkstra{
public:
    static ll solve(vector<vector<pii>> &g, int s, int target = -1){
        //g[v] = list of (u,w) , where v->u with weight w.
        int n = g.size();
        assert(s >= 0 && s < n);

        vl dist(n, -1);
        vector<bool> used(n, false);
        set<pair<ll,int>> S;
        S.insert({0,s});
        
        while(!S.empty()){
            auto min_data = *S.begin();
            S.erase(S.begin());

            ll min_dist = min_data.first;
            int v = min_data.second;
            dist[v] = min_dist;
            used[v] = true;

            if(target == v)
                break;

            for(auto u_data : g[v]){
                int u = u_data.first;
                ll w = u_data.second;
                if(used[u])
                    continue;
                if(dist[u] == -1 || (dist[v]+w < dist[u])){
                    if(dist[u] != -1)
                        S.erase({dist[u],u});
                    dist[u] = dist[v] + w;
                    S.insert({dist[u],u});
                }
            }
        }

        return dist[target];
    }
};


int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n, i, j;
    cin >> n;
    S.resize(n);
    W.resize(n);
    g.clear();
    int cnt = 0;
    for(i=0;i<n;i++){
        cin >> S[i] >> W[i];
        for(j=0;j<S[i].size();j++){
            node v;
            v.idx = i; v.pos = j; v.suf = true;
            idNode[v] = cnt++;
            v.suf = false;
            idNode[v] = cnt++;
        }
    }
    
    tNode.idx = -1;
    idNode[tNode] = cnt++;
    tId = cnt - 1;
    node start;
    start.idx = -2;
    idNode[start] = cnt++;
    int sId = cnt - 1;
    g.resize(idNode.size());

    for(i=0;i<n;i++){
        for(j=0;j<S[i].size();j++){
            node v;
            v.idx = i; v.pos = j;
            v.suf = true;
            int vId = idNode[v];
            for(int k=0;k<n;k++){
                buildN(v, vId, k);
            }
            if(isPalindrome(v)){
                g[vId].push_back({tId, 0});
            }
            v.suf = false;
            vId = idNode[v];
            for(int k=0;k<n;k++){
                buildN(v, vId, k);
            }
            if(isPalindrome(v)){
                g[vId].push_back({tId, 0});
            }
        }
    }
    for(i=0;i<n;i++){
        node v;
        v.idx = i; v.pos = 0; v.suf = true;
        int vId = idNode[v];
        g[sId].push_back({vId, W[i]});
    }

    auto ret = Dijkstra::solve(g, sId, tId);
    cout << ret << "\n";
    
    return 0;
}

Measured memory_bytes: 3788