import java.util.*
import kotlin.math.absoluteValue
import kotlin.math.max
import kotlin.math.min

data class Word(val string: String, val cost: Int)

sealed class State
data class Forward(val wordId: Int, val pos: Int): State()
data class Backward(val wordId: Int, val pos: Int): State()
fun main() {
    val n = readLine()!!.trim().toInt()
    val words = Array(n){
        val (s, c) = readLine()!!.trim().split(' ')
        Word(s, c.toInt())
    }
    val forward = words.map(Word::string)
    val backward = words.map{it.string.reversed()}
    val forwardNext = forward.map{word ->
        word.indices.map{pos ->
            val prefix = word.substring(pos, word.length)
            backward.indices.filter{b -> backward[b].startsWith(prefix) || prefix.startsWith(backward[b])}.toIntArray()
        }
    }
    val backwardNext = backward.map{word ->
        word.indices.map{pos ->
            val prefix = word.substring(pos, word.length)
            forward.indices.filter{f -> forward[f].startsWith(prefix) || prefix.startsWith(forward[f])}.toIntArray()
        }
    }
    val singleMax = words.filter{it.string == it.string.reversed()}.minBy(Word::cost)?.cost?.toLong() ?: Long.MAX_VALUE
    val minCostForward = Array(forward.size){LongArray(forward[it].length + 1){singleMax} }
    val minCostBackward = Array(backward.size){LongArray(backward[it].length + 1){singleMax} }
    val queue = PriorityQueue<Pair<Long, State>>(compareBy(Pair<Long, *>::first))
    for (i in 0 until n) {
        minCostForward[i][0] = words[i].cost.toLong()
        queue.add(words[i].cost.toLong() to Forward(i, 0))
    }
    while (queue.isNotEmpty()) {
        val (cost, state) = queue.poll()
        //println("cost: $cost, state: $state")
        when (state) {
            is Forward -> {
                if (state.pos < forward[state.wordId].length && minCostForward[state.wordId][state.pos] == cost) {
                    val forwardRest = forward[state.wordId].length - state.pos
                    for (next in forwardNext[state.wordId][state.pos]) {
                        if (backward[next].length > forwardRest) {
                            if (minCostBackward[next][forwardRest] > cost + words[next].cost) {
                                minCostBackward[next][forwardRest] = cost + words[next].cost
                                queue.add(cost + words[next].cost to Backward(next, forwardRest))
                            }
                        }else {
                            if (minCostForward[state.wordId][state.pos + backward[next].length] > cost + words[next].cost) {
                                minCostForward[state.wordId][state.pos + backward[next].length] = cost + words[next].cost
                                queue.add(cost + words[next].cost to Forward(state.wordId, state.pos + backward[next].length))
                            }
                        }
                    }
                }
            }
            is Backward -> {
                if (state.pos < backward[state.wordId].length && minCostBackward[state.wordId][state.pos] == cost) {
                    val backwardRest = backward[state.wordId].length - state.pos
                    for (next in backwardNext[state.wordId][state.pos]) {
                        if (forward[next].length > backwardRest) {
                            if (minCostForward[next][backwardRest] > cost + words[next].cost) {
                                minCostForward[next][backwardRest] = cost + words[next].cost
                                queue.add(cost + words[next].cost to Forward(next, backwardRest))
                            }
                        }else {
                            if (minCostBackward[state.wordId][state.pos + forward[next].length] > cost + words[next].cost) {
                                minCostBackward[state.wordId][state.pos + forward[next].length] = cost + words[next].cost
                                queue.add(cost + words[next].cost to Backward(state.wordId, state.pos + forward[next].length))
                            }
                        }
                    }
                }
            }
        }
    }
    val forwardMin = (0 until n).flatMap{i ->
        (0 .. forward[i].length).filter{j -> forward[i].substring(j, forward[i].length) == forward[i].substring(j, forward[i].length).reversed()}.map(minCostForward[i]::get)
    }.min()!!
    val backwardMin = (0 until n).flatMap{i ->
        (0 .. backward[i].length).filter{j -> backward[i].substring(j, backward[i].length) == backward[i].substring(j, backward[i].length).reversed()}.map(minCostBackward[i]::get)
    }.min()!!
    println(min(forwardMin, backwardMin).takeIf{it != Long.MAX_VALUE} ?: -1)
}

Measured memory_bytes: 47048