#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <algorithm>
#include <time.h>
//#include <math.h>
#include <cmath>
#include <fstream>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include <stdlib.h>
#include <iomanip>
#include <cstdio>
#include <cassert>
#include <bitset>

#pragma comment(linker, "/STACK:36777216")
using namespace std;

#define flu fflush(stdout)
#define gg return 0
#define mp make_pair

typedef long double ptype;

long long mod = /*27449*//*998244353*/ 1e9 + 7 /*1e9 + 9*/;
int inf = 1e9;
double eps = 1e-8;
long double pi = acosl(-1);
ifstream in("input.txt");
ofstream out("output.txt");

int trymerge(string left, string right, string& res)
{
	if (left.size() < right.size())
	{
		int p = 0;
		int q = right.size() - 1;
		while (p < left.size() && left[p] == right[q])
		{
			p++;
			q--;
		}
		if (p == left.size())
		{
			res = right.substr(0, q + 1);
			return 2; // suffix part; 
		}
		return 0; // can't match
	}
	else
	{
		int p = 0;
		int q = right.size() - 1;
		while (q >= 0 && left[p] == right[q])
		{
			p++;
			q--;
		}
		if (q == -1)
		{
			res = left.substr(p, left.size() - p);
			return 1; // prefix part; 
		}
		return 0; // can't match
	}
}

bool isPalindrome(string s)
{
	string t = s;
	reverse(t.begin(), t.end());
	return s == t;
}

void solve()
{
	int n;
	cin >> n;
	vector<pair<string, int>> a(n);
	set<pair<long long, pair<int, string>>> q;
	map<pair<int, string>, long long> d;
	for (int i = 0; i < n; i++)
	{
		cin >> a[i].first >> a[i].second;
		q.insert({ a[i].second, {0, a[i].first} });
	//	q.insert({ a[i].second, {1, a[i].first} });
		d[{0, a[i].first}] = a[i].second;
	//	d[{1, a[i].first}] = a[i].second;
	}
	while (q.size())
	{
		auto v = *(q.begin());
		q.erase(q.begin());
		long long dist = v.first;
		string cur = v.second.second;
		int orient = v.second.first;

		if (isPalindrome(cur))
		{
			cout << dist;
			return;
		}
		for (int i = 0; i < n; i++)
		{
			string r1;
			int res;
			if (orient)
			{
				res = trymerge(a[i].first, cur, r1);
			}
			else
			{
				res = trymerge(cur, a[i].first, r1);
			}
			if (res)
			{
				int or1 = res - 1;
				if (!d.count({ or1, r1 }))
				{
					d[{or1, r1}] = dist + a[i].second;
					q.insert({ d[{or1, r1}], {or1, r1} });
				}
				else if (d[{or1, r1}] > dist + a[i].second)
				{
					q.erase({ d[{or1, r1}], {or1, r1} });
					d[{or1, r1}] = dist + a[i].second;
					q.insert({ d[{or1, r1}], {or1, r1} });
				}
			}
		}

	}
	cout << -1;
}

int main()
{
	cout << setprecision(2) << fixed;
	cin.tie();
	cout.tie();
	clock_t t1 = clock();
	int t;
	//cin >> t;
	t = 1;
	while (t--) {
		solve();
	}
	//cout << (clock() - t1) * 1.0 / CLOCKS_PER_SEC;
	gg;
}