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

template <typename T> class Dijkstra {
private:
  using ll = long long;
  using pp = pair<int, ll>;
public:
  ll INF_DIST = std::numeric_limits<ll>::max() / 2;
private:
  int start = 0;
  int siz = 0;
  void calc (const vector<vector<pair<int, T>>>& g) {
    dist.resize(siz);
    fill(dist.begin(), dist.end(), INF_DIST);
    dist[start] = 0;
    priority_queue<pp, vector<pp>, greater<pp>> que;
    que.emplace(0, start);
    while (que.size()) {
      pp cur = que.top();
      que.pop();
      int idx = cur.second;
      T d = cur.first;
      if (d > dist[idx]) continue;
      for (auto& nxt : g[idx]) {
        int j = nxt.first;
        T d2 = dist[idx] + nxt.second;
        if (d2 <  dist[j]) {
          dist[j] = d2;
          que.emplace(dist[j], j);
        }
      }
    }
  }
public:
  Dijkstra (const vector<vector<pair<int, T>>>& g, int st, int n = -1) : start(st) {if (n < 0) siz = (int) g.size(); calc(g); }
  Dijkstra (const vector<pair<int, T>> in[], int st, int n) : start(st), siz(n) {
    vector<vector<pair<int, T>>> g(n);
    for (int i = 0; i < n; ++i) for (int j = 0; j < (int) in[i].size(); j++) g[i].push_back(in[i][j]);
    calc(g);
  }
  vector<ll> dist;
  vector<ll> get() {return dist;}
};

signed main() { 
  ios::sync_with_stdio(false); cin.tie(0);
  auto is_palindrome = [] (string s) -> bool {
    string t = string(s.rbegin(), s.rend());
    return t == s;
  };
  int n;
  cin >> n;
  vector<string> s(n);
  vector<int> c(n);
  long long ans = 1LL << 60;
  for (int i = 0; i < n; i++) {
    cin >> s[i] >> c[i];
    if (is_palindrome(s[i])) ans = min(ans, 1LL * c[i]);
  }
  map<pair<string, int>, int> mp;
  int num = 1;
  for (int i = 0; i < n; i++) {
    for (int j = 1; j <= (int) s[i].size(); j++) {
      string t = s[i].substr(0, j);
      if (!mp.count(make_pair(t, 0))) mp[make_pair(t, 0)] = num++;
    }
    for (int j = 0; j < (int) s[i].size(); j++) {
      string t = s[i].substr(j);
      if (!mp.count(make_pair(t, 1))) mp[make_pair(t, 1)] = num++;
    }
  }
  mp[make_pair("", 0)] = num++;
  mp[make_pair("", 1)] = num++;
  vector<pair<string, int>> node(num);
  vector<vector<pair<int, long long>>> g(num);
  for (auto& p : mp) node[p.second] = p.first;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j <= (int) s[i].size(); j++) {
      string t = s[i].substr(0, j);
      if (is_palindrome(t)) {
        string tt = s[i].substr(j);
        int idx = mp[make_pair(tt, 1)];
        g[0].emplace_back(idx, c[i]);
      }
      t = s[i].substr(j);
      if (is_palindrome(t)) {
        string tt = s[i].substr(0, j);
        int idx = mp[make_pair(tt, 0)];
        g[0].emplace_back(idx, c[i]);
      }
    }
  }
  for (int i = 0; i < num; i++) {
    if (node[i].first == "") continue;
    for (int j = 0; j < n; j++) {
      string t, tt;
      if (node[i].second == 0) {
        t = node[i].first;
        tt = s[j];
      } else {
        t = s[j];
        tt = node[i].first;
      }
      //cerr << "t = " << t << " tt = " << tt << endl;
      while (!t.empty() && !tt.empty()) {
        if (t.back() != tt[0]) break;
        t.pop_back();
        tt = tt.substr(1);
      }
      if (!t.empty() && !tt.empty()) {
        //cerr << "invalid" << endl;
        continue;
      }
      if (tt.empty()) {
        int idx = mp[make_pair(t, 0)];
        g[i].emplace_back(idx, c[j]);
      }
      if (t.empty()) {
        int idx = mp[make_pair(tt, 1)];
        g[i].emplace_back(idx, c[j]);
      }
      // if (t.empty()) cerr << "t is empty";
      // else cerr << "t = " << t;
      // if (tt.empty()) cerr << " tt is empty";
      // else cerr << " tt = " << tt;
      // cerr << endl;
    }
  }
  // cerr << endl;
  // for (int i = 0; i < num; i++) {
  //   cerr << "i = " << i << " node[i].first = " << node[i].first << " node[i].second = " << node[i].second << endl;
  // }
  // cerr << endl;
  // for (int i = 0; i < num; i++) {
  //   cerr << "i = " << " node[i].first = " << node[i].first << " node[i].second = " << node[i].second << endl;
  //   for (int j = 0; j < (int) g[i].size(); j++) cerr << g[i][j].first << " " << g[i][j].second << endl;
  // }
  // cerr << endl;
  Dijkstra<long long> d(g, 0);
  // cerr << ans << endl;
  ans = min(ans, d.dist[num - 1]);
  ans = min(ans, d.dist[num - 2]);
  // for (int i = 0; i < num; i++) {
  //   cerr << "i = " << i << " node[i].first = " << node[i].first << " node[i].second = " << node[i].second << " dist[i] = " << d.dist[i] << endl;
  // }
  //cerr << num << endl;
  cout << (ans == 1LL << 60 ? -1 : ans) << endl;
  return 0;
}

Measured memory_bytes: 4044