#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
//constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-12;

//int N, M, K, T, H, W, L, R;
long long int N, M, K, T, H, W, L, R;

struct Node {
	int a, b, c;
	long long int cost;
	Node(const int aa, const int bb, const int cc, const long long int co) {
		a = aa, b = bb, c = cc, cost = co;
	}
	bool operator<(const Node&n)const {
		return cost > n.cost;
	}
};

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin >> N;
	vector<string>s(N);
	vector<string>t(N);
	vector<long long int>cost(N);
	long long int ans = MOD * MOD;
	for (int i = 0; i < N; i++) {
		cin >> s[i] >> cost[i];
		t[i] = s[i];
		reverse(t[i].begin(), t[i].end());
		if (s[i] == t[i]) {
			ans = min(ans, cost[i]);
		}
	}
	vector<vector<vector<long long int>>>dp(N, vector<vector<long long int>>(21, vector<long long int>(2, MOD*MOD)));
	priority_queue<Node>PQ;
	for (int i = 0; i < N; i++) {
		dp[i][0][0] = cost[i];
		PQ.emplace(i, 0, 0, cost[i]);
	}
	while (!PQ.empty()) {
		auto box = PQ.top();
//		cout << box.a << " " << box.b << " " << box.c << " " << box.cost << endl;
		PQ.pop();
		if (box.c == 0) {
			int llen = s[box.a].size() - box.b;
			for (int i = 0; i < N; i++) {
				int rlen = t[i].size();
				int len = min(llen, rlen);
				if (s[box.a].substr(box.b, len) == t[i].substr(0, len)) {
					if (llen == rlen) {
						ans = min(ans, box.cost + cost[i]);
					}
					else if (llen > rlen) {
						if (dp[box.a][box.b + len][box.c] > box.cost + cost[i]) {
							dp[box.a][box.b + len][box.c] = box.cost + cost[i];
							PQ.emplace(box.a, box.b + len, box.c, box.cost + cost[i]);
						}
					}
					else {
						if (dp[i][len][1] > box.cost + cost[i]) {
							dp[i][len][1] = box.cost + cost[i];
							PQ.emplace(i, len, 1, dp[i][len][1]);
						}
					}
				}
			}
		}
		else {
			int rlen = t[box.a].size() - box.b;
			for (int i = 0; i < N; i++) {
				int llen = s[i].size();
				int len = min(llen, rlen);
				if (t[box.a].substr(box.b, len) == s[i].substr(0, len)) {
					if (llen == rlen) {
						ans = min(ans, box.cost + cost[i]);
					}
					else if (llen > rlen) {
						if (dp[i][len][0] > box.cost + cost[i]) {
							dp[i][len][0] = box.cost + cost[i];
							PQ.emplace(i, len, 0, dp[i][len][0]);
						}
					}
					else {
						if (dp[box.a][box.b + len][box.c] > box.cost + cost[i]) {
							dp[box.a][box.b + len][box.c] = box.cost + cost[i];
							PQ.emplace(box.a, box.b + len, box.c, box.cost + cost[i]);
						}
					}
				}
			}
		}
	}
//	cout << "hoge" << endl;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j <= s[i].size(); j++) {
			for (int k = 0; k < 2; k++) {
				if (k == 0) {
					auto a = s[i].substr(j, s[i].size() - j);
					auto b = a;
					reverse(b.begin(), b.end());
					if (a == b) {
						ans = min(ans, dp[i][j][k]);
					}
				}
				else {
					auto a = t[i].substr(j, t[i].size() - j);
					auto b = a;
					reverse(b.begin(), b.end());
					if (a == b) {
						ans = min(ans, dp[i][j][k]);
					}
				}
			}
		}
	}
	if (ans == MOD * MOD)ans = -1;
	cout << ans << endl;
}

Measured memory_bytes: 3712