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

using ll = long long;
static const ll INF = 1e18;

bool is_palindrome(string &s) {
  for (int i = 0; i < s.size() / 2; i++) {
    if (s[i] != s[s.size() - i - 1]) return false;
  }
  return true;
}

// ダイクストラ法 O(ElogV)
vector<ll> d; // 最短距離

void dijkstra(const vector<vector<pair<int, ll>>> &G, int s, ll cost) {
  priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq; // first:最短距離 second:頂点の番号
  d.assign(G.size(), INF); // 初期化
  d[s] = cost;
  pq.push(make_pair(cost, s));
  while (!pq.empty()) {
    pair<ll, int> p = pq.top();
    pq.pop();
    int v = p.second;
    if (d[v] < p.first) continue;
    for (int i = 0; i < G[v].size(); i++) {
      pair<int, ll> p2 = G[v][i];
      if (d[p2.first] > d[v] + p2.second) {
        d[p2.first] = d[v] + p2.second;
        pq.push(make_pair(d[p2.first], p2.first));
      }
    }
  }
  return;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  
  int n;
  cin >> n;
  
  vector<string> s(n), t(n);
  vector<ll> c(n);
  for (int i = 0; i < n; i++) {
    cin >> s.at(i) >> c.at(i);
    t.at(i) = s.at(i);
    reverse(t.at(i).begin(), t.at(i).end());
  }
  
  map<string, int> suf, pre;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < s[i].size(); j++) {
      suf[s[i].substr(j)] = 0;
      pre[t[i].substr(j)] = 0;
    }
  }
  
  vector<bool> pal(2100, false);
  pal[0] = true; // 空文字列
  int tmp = 1;
  for (auto &i : suf) {
    i.second = tmp;
    string i2 = i.first;
    if (is_palindrome(i2)) pal[tmp] = true;
    tmp++;
  }
  tmp = 1001;
  for (auto &i : pre) {
    i.second = tmp;
    string i2 = i.first;
    if (is_palindrome(i2)) pal[tmp] = true;
    tmp++;
  }
  
  vector<vector<pair<int, ll>>> G(2100);
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < s[i].size(); j++) {
      string keep = s[i].substr(j);
      for (int ii = 0; ii < n; ii++) {
        string keep2 = t[ii];
        if (keep.size() == keep2.size()) {
          if (keep == keep2) {
            G[suf[keep]].emplace_back(make_pair(0, c[ii]));
          }
        }
        else if (keep.size() < keep2.size()) {
          if (keep == keep2.substr(0, keep.size())) {
            string keep3 = keep2.substr(keep.size());
            G[suf[keep]].emplace_back(make_pair(pre[keep3], c[ii]));
          }
        }
        else {
          if (keep2 == keep.substr(0, keep2.size())) {
            string keep3 = keep.substr(keep2.size());
            G[suf[keep]].emplace_back(make_pair(suf[keep3], c[ii]));
          }
        }
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < s[i].size(); j++) {
      string keep = t[i].substr(j);
      for (int ii = 0; ii < n; ii++) {
        string keep2 = s[ii];
        if (keep.size() == keep2.size()) {
          if (keep == keep2) {
            G[pre[keep]].emplace_back(make_pair(0, c[ii]));
          }
        }
        else if (keep.size() < keep2.size()) {
          if (keep == keep2.substr(0, keep.size())) {
            string keep3 = keep2.substr(keep.size());
            G[pre[keep]].emplace_back(make_pair(suf[keep3], c[ii]));
          }
        }
        else {
          if (keep2 == keep.substr(0, keep2.size())) {
            string keep3 = keep.substr(keep2.size());
            G[pre[keep]].emplace_back(make_pair(pre[keep3], c[ii]));
          }
        }
      }
    }
  }
  
  ll ans = 1e18;
  for (int i = 0; i < n; i++) {
    dijkstra(G, suf[s[i]], c[i]);
    for (int j = 0; j < 2100; j++) {
      if (pal[j]) ans = min(ans, d[j]);
    }
  }
  
  if (ans == 1e18) cout << -1 << '\n';
  else cout << ans << '\n';
}

Measured memory_bytes: 3932