#include<cstdio>
#include<cstring>
#include<queue>
//for the center, then do add
//only the left unmatch part matter
//f[a][i][b][j]:
//s[a][len-i+1~len] & s[b][1~j]
long long f[55][25][55][25];
char s[55][25];
char t[55];
int len[55];
long long c[55];
struct Node{
    int a,i,b,j;
    long long cost;
    Node(){}
    Node(int a,int i,int b,int j,long long cost):a(a),i(i),b(b),j(j),cost(cost){}
    bool operator < (const Node& other)const{
        return cost>other.cost;
    }
};

int isGood(int p,int l,int r){
    int ok = 1;
    int pl = l, pr = r;
    while(pl<=pr){
        if(s[p][pl]!=s[p][pr]){
            ok = 0;
            break;
        }
        else pl++, pr--;
    }
    return ok;
}

int isMatch(int a,int pa,int b,int pb){
    int size = 0;
    for(int i = pa; i <= len[a]; i++) t[++size] = s[a][i];
    for(int i = 1; i <= pb; i++) t[++size] = s[b][i];
    int ok = 1;
    int pl = 1, pr = size;
    while(pl<=pr){
        if(t[pl]!=t[pr]){
            ok = 0;
            break;
        }
        else pl++, pr--;
    }
    //if(ok) printf("a = %d, pa = %d, b = %d, pb = %d\n",a,pa,b,pb);
    return ok;
}

int main(){
    int n;
    scanf("%d",&n);
    for(int i = 1; i <= n; i++){
        scanf("%s%lld",s[i]+1,&c[i]);
        len[i] = strlen(s[i]+1);
    }
    std::priority_queue<Node>Q;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= len[i]; j++){
            if(isGood(i,1,j)){
                Node cur = Node(i,1,i,j,c[i]);
                Q.push(cur);
            }
            if(isGood(i,j,len[i])){
                Node cur = Node(i,j,i,len[i],c[i]);
                Q.push(cur);
            }
        }
    }
    for(int u = 1; u <= n; u++){
        for(int v = 1; v <= n; v++){
            for(int i = 1; i <= len[u]; i++){
                if(isMatch(u,i,v,len[v])){
                    Node cur = Node(u,i,v,len[v],c[u]+c[v]);
                    Q.push(cur);
                }
            }
            for(int i = 1; i <= len[v]; i++){
                if(isMatch(u,1,v,i)){
                    Node cur = Node(u,1,v,i,c[u]+c[v]);
                    Q.push(cur);
                }
            }
        }
    }
    long long inf = 1e17+7;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            for(int pa = 1; pa <= 21; pa++){
                for(int pb = 1; pb <= 21; pb++){
                    f[i][pa][j][pb] = inf;
                }
            }
        }
    }
    long long ans = -1;
    while(Q.size()!=0){
        while(Q.size()!=0){
            Node cur = Q.top();
            if(cur.cost>f[cur.a][cur.i][cur.b][cur.j]) Q.pop();
            else break;
        }
        if(Q.size()==0) break;
        Node cur = Q.top(); Q.pop();
        int a = cur.a, i = cur.i, b = cur.b, j = cur.j;
        long long cost = cur.cost;
        //printf("a = %d, i = %d, b = %d, j = %d\n",a,i,b,j);
        if(i==1 && j==len[b]){
            if(ans==-1) ans = cost;
            else if(cur.cost<ans) ans = cost;
        }
        else if(i==1){
            //add to left
            for(int add = 1; add <= n; add++){
                int pa = len[add]+1, pb = j;
                while(pa-1>=1 && pb+1<=len[b] && s[add][pa-1]==s[b][pb+1]) pa--, pb++;
                if(pa==1 || pb==len[b]){
                    if(f[add][pa][b][pb]>cost+c[add]){
                        f[add][pa][b][pb] = cost+c[add];
                        Q.push(Node(add,pa,b,pb,cost+c[add]));
                    }
                }
            }
        }
        else{
            //add to right
            for(int add = 1; add <= n; add++){
                int pa = i, pb = 0;
                while(pa-1>=1 && pb+1<=len[add] && s[a][pa-1]==s[add][pb+1]) pa--, pb++;
                if(pa==1 || pb==len[add]){
                    if(f[a][pa][add][pb]>cost+c[add]){
                        f[a][pa][add][pb] = cost+c[add];
                        Q.push(Node(a,pa,add,pb,cost+c[add]));
                    }
                }
            }
        }
    }
    printf("%lld\n",ans);
    return 0;
}


Measured memory_bytes: 14680