#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
#include <queue>
#include <deque>
#include <bitset>
#include <iterator>
#include <list>
#include <stack>
#include <map>
#include <set>
#include <functional>
#include <numeric>
#include <utility>
#include <iomanip>
#include <limits>
#include <time.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>

#define debug(x) cout << #x << " = " << x << endl
#define fori(i, ini, lim) for(int i = int(ini); i < int(lim); i++)
#define ford(i, ini, lim) for(int i = int(ini); i >= int(lim); i--)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;
typedef tuple<ll, int, int, int> state;

const int MAX_N = 55;
const int MAX_SS = 25;
string s[MAX_N];
ll dis[MAX_N][2][MAX_SS];
int cost[MAX_N], n;

bool palindrome(const string &S) {
    return equal(S.begin(), S.end(), S.rbegin());
}

ll dijkstra() {
    memset(dis, 0x7F, sizeof dis);

    priority_queue<state, vector<state>, greater<state>> pq;
    fori (i, 0, n) {
        pq.emplace(cost[i], i, 0, 0);
        dis[i][0][1] = cost[i];
    }

    ll ans = -1;

    while (!pq.empty()) {
        state cur = pq.top();
        pq.pop();

        ll w;
        int id, type, pos;
        tie(w, id, type, pos) = cur;

        if (w > dis[id][type][pos + 1]) {
            continue;
        }
        
        string cur_s = s[id];
        string rem = type == 0 ? cur_s.substr(pos, (int) cur_s.size() - pos) : cur_s.substr(0, pos + 1);
        
        if (palindrome(rem)) {
            ans = w;
            break;
        }

        fori (i, 0, n) {
            string it_s = s[i];
            bool ok = true;

            if (type == 0) {
                for (int j = 0; pos + j < (int) cur_s.size() && j < (int) it_s.size(); j++) {
                    bool match = cur_s[pos + j] == it_s[(int) it_s.size() - j - 1];
                    if (!match) {
                        ok = false;
                        break;
                    }
                }
            }
            else {
                for (int j = 0; pos - j >= 0 && j < (int) it_s.size(); j++) {
                    bool match = cur_s[pos - j] == it_s[j];
                    if (!match) {
                        ok = false;
                        break;
                    }
                }
            }

            if (ok) {
                state new_state;

                if (type == 0) {
                    int needed = cur_s.size() - pos;
                    if ((int) it_s.size() >= needed) {
                        new_state = state(w + cost[i], i, !type, (int) it_s.size() - needed - 1);
                    }
                    else {
                        new_state = state(w + cost[i], id, type, pos + (int) it_s.size());
                    }
                }
                else {
                    int needed = pos + 1;
                    if ((int) it_s.size() >= needed) {
                        new_state = state(w + cost[i], i, !type, needed);
                    }
                    else {
                        new_state = state(w + cost[i], id, type, pos - (int) it_s.size());
                    }
                }

                if (get<0>(new_state) < dis[get<1>(new_state)][get<2>(new_state)][get<3>(new_state) + 1]) {
                    dis[get<1>(new_state)][get<2>(new_state)][get<3>(new_state) + 1] = get<0>(new_state);
                    pq.emplace(new_state);
                }
            }
        }
    }

    return ans;
}

void solve() {
    cin >> n;
    fori (i, 0, n) {
        cin >> s[i] >> cost[i];
    }
    ll ans = dijkstra();
    cout << ans << endl;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    solve();
    return 0;
}



Measured memory_bytes: 3676