// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")

#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

#define DEBUG
#ifdef DEBUG
#define debug(...) __f(#__VA_ARGS__, __VA_ARGS__)
	template <typename Arg1>
	void __f(const char* name, Arg1&& arg1)
	{
		cerr << name << " = " << arg1 << endl;
	}
	template <typename Arg1, typename... Args>
	void __f(const char* names, Arg1&& arg1, Args&&... args)
	{
		const char* comma = strchr(names + 1, ','); cerr.write(names, comma - names) << " = " << arg1 << " || ";
		__f(comma+1, args...);
	}
#else
#define debug(...)
#endif

template <class Ch, class Tr, class Container>
basic_ostream <Ch, Tr> & operator << (basic_ostream <Ch, Tr> & os, Container const& x) {
    os << "{ ";
    for(auto& y : x) os << y << " ; ";
    return os << "}";
}

template <class X, class Y>
ostream & operator << (ostream & os, pair <X, Y> const& p) {
	return os << "[ " << p.first << ", " << p.second << "]" ;
}

#define FAST_IO std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define ll long long int
#define pb push_back
#define mp make_pair
#define ld long double
#define sz(a) (ll)(a).size()
#define endl "\n"

// priority_queue<ll, vector<ll>, less<ll>>pq;     // Max Heap
// priority_queue<ll, vector<ll>, greater<ll>>pq;  // Min Heap

typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
//K-th smallest
//cout << k << "kth (1 based indexing) smallest: " << *A.find_by_order(k - 1) << endl;
//NO OF ELEMENTS < X
//cout << "No of elements less than " << X << " are " << A.order_of_key(X) << endl;

map<pair<string, ll>, ll>done, dp,  ongoing;  
ll n;
set<string>s;
map<string, ll>m;
vector<pair<string, ll>>v;

bool is_pal(string a)
{
	for(int i=0;i<sz(a);i++) if(a[i] != a[sz(a) - 1  - i]) return false;
	return true;
}

ll rec(string a, ll side, ll iter)
{
	if(ongoing[{a, side}] == 1) return 1e18;
	if(done[{a, side}] == 1) return dp[{a, side}];
	ongoing[{a, side}] = 1;
	done[{a, side}] = 1;
	bool ok = false;
	ll ans = 1e18;
	for(int i=0;i<sz(v);i++)
	{
		string temp = v[i].first;
		if(side == 0)
		{	
			reverse(temp.begin(), temp.end());
			if(sz(a) < sz(temp))
			{
				ll x = sz(a);
				string temp2 = temp.substr(0, x);
				if(temp2 != a) continue;
				ok = true;
				temp2 = temp.substr(x, sz(temp));
				if(is_pal(temp2)) ans = min(ans, v[i].second);
				else
				{	
					reverse(temp2.begin(), temp2.end());
					ans = min(ans, v[i].second + rec(temp2, 1, iter + 1));
				}
			}
			else if(sz(temp) < sz(a))
			{
				string temp2 = a.substr(0, sz(temp));
				if(temp2 != temp) continue;
				ok = true;
				temp2 = a.substr(sz(temp), sz(a));
				if(is_pal(temp2)) ans = min(ans, v[i].second);
				else ans = min(ans, v[i].second + rec(temp2, 0, iter + 1));
			}
			else
			{
				if(temp != a) continue;
				ok =  true;
				ans = min(ans, v[i].second);
			}
		}
		else
		{
			string a1 = a;
			reverse(a1.begin(), a1.end());
			if(sz(a1) < sz(temp))
			{
				ll x = sz(a1);
				string temp2 = temp.substr(0, x);
				if(temp2 != a1) continue;
				ok = true;
				temp2 = temp.substr(x, sz(temp));
				if(is_pal(temp2)) ans = min(ans, v[i].second);
				else ans = min(ans, v[i].second + rec(temp2, 0, iter + 1));
			}
			else if(sz(temp) < sz(a1))
			{
				string temp2 = a1.substr(0, sz(temp));
				if(temp2 != temp) continue;
				ok = true;
				temp2 = a1.substr(sz(temp), sz(a1));
				if(is_pal(temp2)) ans = min(ans, v[i].second);
				else
				{	
					reverse(temp2.begin(), temp2.end());
					ans = min(ans, v[i].second + rec(temp2, 1, iter + 1));
				}
			}
			else
			{
				if(temp != a1) continue;
				ok =  true;
				ans = min(ans, v[i].second);
			}
		}
	}
	ongoing[{a, side}] = 0;
	if(!ok) return dp[{a, side}] = 1e18;
	return dp[{a, side}] = ans;
}

int main()
{
	FAST_IO;

	cin >> n;
	for(int i=0;i<n;i++)
	{
		string a;
		ll b;
		cin >> a >> b;
		if(s.find(a) == s.end())
		{	
			s.insert(a);
			m[a] = b;
		}
		else m[a] = min(m[a], b);
	}
	ll temp = 1e18;
	for(auto it : s) 
	{	
		v.pb({it, m[it]});
		if(is_pal(it)) temp = min(temp, m[it]);
	}	
	temp = min(temp, rec("", 0, 0));
	if(temp >= 1e18) cout << -1 << endl;
	else cout << temp << endl;
    return 0;
}

Measured memory_bytes: 3820