#include <bits/stdc++.h>

using namespace std;

#define SZ(x) (int)(x.size())
#define REP(i, n) for(int i=0;i<(n);++i)
#define FOR(i, a, b) for(int i=(a);i<(b);++i)
#define RREP(i, n) for(int i=(int)(n);i>=0;--i)
#define RFOR(i, a, b) for(int i=(int)(a);i>=(int)(b);--i)
#define ALL(a) (a).begin(),(a).end()
#define DUMP(x) cerr<<#x<<" = "<<(x)<<endl
#define DEBUG(x) cerr<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<< endl;

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using P = pair<int, int>;

const double eps = 1e-8;
const ll MOD = 1000000007;
const int INF = INT_MAX / 2;
const ll LINF = LLONG_MAX / 2;

template<typename T1, typename T2>
bool chmax(T1 &a, const T2 &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template<typename T1, typename T2>
bool chmin(T1 &a, const T2 &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> p) {
  os << p.first << ":" << p.second;
  return os;
}

template<class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  REP(i, SZ(v)) {
    if (i) os << " ";
    os << v[i];
  }
  return os;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);

  int n;
  cin >> n;
  vector<string> s;
  vector<ll> c;
  map<string, ll> mp;
  REP(i, n) {
    string tmps; ll tmpc;
    cin >> tmps >> tmpc;
    if(mp.find(tmps) == mp.end() || mp[tmps] > tmpc) mp[tmps] = tmpc;
  }
  for(auto &e: mp) {
    s.push_back(e.first);
    c.push_back(e.second);
  }
  n = SZ(s);

  using elm = pair<ll, pair<int, string>>;
  vector<map<string, ll>> d(2, map<string, ll>());
  priority_queue<elm, vector<elm>, greater<elm>> pq;

  REP(j, n) {
    d[0][s[j]] = c[j];
    pq.push({c[j], {0, s[j]}});
  }

  while (!pq.empty()) {
    auto now = pq.top();
    pq.pop();
    ll val = now.first;
    int isl = now.second.first;
    string nows = now.second.second;

    if (val > d[isl][nows]) continue;

    REP(i, n) {
      bool ok = true;
      string tmps = s[i];
      if (!isl) reverse(ALL(tmps));
      REP(j, min(SZ(nows), SZ(tmps))) {
        ok &= tmps[j] == nows[j];
      }
      if (!ok) continue;


      if (SZ(nows) > SZ(tmps)) {
        string nxts = nows.substr(SZ(tmps), SZ(nows) - SZ(tmps));
        //cout << nxts << endl;
        ll nxtval = val + c[i];
        if (d[isl].find(nxts) == d[isl].end() || d[isl][nxts] > nxtval) {
          d[isl][nxts] = nxtval;
          pq.push({nxtval, {isl, nxts}});
        }
      } else if (SZ(nows) < SZ(tmps)) {
        string nxts = tmps.substr(SZ(nows), SZ(tmps) - SZ(nows));
        //cout << nxts << endl;
        ll nxtval = val + c[i];
        if (d[!isl].find(nxts) == d[!isl].end() || d[!isl][nxts] > nxtval) {
          d[!isl][nxts] = nxtval;
          pq.push({nxtval, {!isl, nxts}});
        }
      } else {
        ll nxtval = val + c[i];
        if (d[1].find("") == d[1].end() || d[1][""] > nxtval) {
          d[1][""] = nxtval;
        }
      }
    }
  }

  ll ans = LLONG_MAX;
  REP(i, 2) {
    for (auto &e: d[i]) {
      //cout << i << ":" << e << endl;
      string tmp = e.first;
      ll val = e.second;
      bool ispal = true;
      REP(j, SZ(tmp) / 2) {
        ispal &= tmp[j] == tmp[SZ(tmp) - 1 - j];
      }
      if (ispal) chmin(ans, val);
    }
  }
  cout << (ans == LLONG_MAX ? -1 : ans) << endl;


}











Measured memory_bytes: 3748