struct Scanner {
    private var elements = [String]()
    private var index = 0

    mutating func peek() -> String {
        while elements.count == index {
            elements = readLine()!.split(separator: " ").map(String.init)
            index = 0
        }
        return elements[index]
    }

    mutating func next() -> String {
        let value = peek()
        index += 1
        return value
    }

    mutating func nextInt() -> Int {
        return Int(next())!
    }

    mutating func nextDouble() -> Double {
        return Double(next())!
    }
}

struct Array2D<Element> {
    let n1: Int
    let n2: Int
    private var elements: [Element]

    init(repeating: Element, _ n1: Int, _ n2: Int) {
        self.n1 = n1
        self.n2 = n2
        self.elements = [Element](repeating: repeating, count: n1 * n2)
    }

    subscript(i: Int, j: Int) -> Element {
        get {
            elements[i * n2 + j]
        }
        set {
            elements[i * n2 + j] = newValue
        }
    }
}

struct Array3D<Element> {
    let n1: Int
    let n2: Int
    let n3: Int
    private var elements: [Element]

    init(repeating: Element, _ n1: Int, _ n2: Int, _ n3: Int) {
        self.n1 = n1
        self.n2 = n2
        self.n3 = n3
        self.elements = [Element](repeating: repeating, count: n1 * n2 * n3)
    }

    subscript(i: Int, j: Int, k: Int) -> Element {
        get {
            elements[(i * n2 + j) * n3 + k]
        }
        set {
            elements[(i * n2 + j) * n3 + k] = newValue
        }
    }
}

infix operator +++: AdditionPrecedence
infix operator ++=: AssignmentPrecedence
infix operator --=: AssignmentPrecedence

extension Int {
    static func +++ (lhs: Int, rhs: Int) -> Int {
        if lhs == Int.max || rhs == Int.max { return Int.max }
        return lhs + rhs
    }

    static func ++= (lhs: inout Int, rhs: Int) {
        if lhs < rhs {
            lhs = rhs
        }
    }

    static func --= (lhs: inout Int, rhs: Int) {
        if lhs > rhs {
            lhs = rhs
        }
    }
}

var scanner = Scanner()
let N = scanner.nextInt()
var S = [[Character]]()
var C = [Int]()

for _ in 0 ..< N {
    S.append([Character](scanner.next()))
    C.append(scanner.nextInt())
}

extension Array where Element: Equatable {
    func isPalindrome() -> Bool {
        self == self.reversed()
    }
}

struct Edge {
    var from: (Int, Int, Int)
    var to: (Int, Int, Int)
    var cost: Int
}

var edges = [Edge]()
for i in 0 ..< N {
    for j in 0 ..< S[i].count {
        for k in 0 ..< N {
            if S[i].count - j >= S[k].count {
                // left
                if [Character](S[i].suffix(S[i].count - j).prefix(S[k].count)) == S[k].reversed() {
                    edges.append(Edge(
                        from: (0, i, j),
                        to: (0, i, j + S[k].count),
                        cost: C[k]
                    ))
                }

                // right
                if [Character](S[i].prefix(S[i].count - j).suffix(S[k].count)) == S[k].reversed() {
                    edges.append(Edge(
                        from: (1, i, j),
                        to: (1, i, j + S[k].count),
                        cost: C[k]
                    ))
                }
            } else {
                // left
                if S[i].suffix(S[i].count - j) == S[k].suffix(S[i].count - j).reversed() {
                    edges.append(Edge(
                        from: (0, i, j),
                        to: (1, k, S[i].count - j),
                        cost: C[k]
                    ))
                }

                // right
                if [Character](S[i].prefix(S[i].count - j)) == S[k].prefix(S[i].count - j).reversed() {
                    edges.append(Edge(
                        from: (1, i, j),
                        to: (0, k, S[i].count - j),
                        cost: C[k]
                    ))
                }
            }
        }

    }
}


var dp = Array3D(repeating: Int.max, 2, N, 21)
for i in 0 ..< N {
    for j in 0 ... S[i].count {
        if [Character](S[i].suffix(S[i].count - j)).isPalindrome() {
            dp[0, i, j] = 0
        }
        if [Character](S[i].prefix(S[i].count - j)).isPalindrome() {
            dp[1, i, j] = 0
        }
    }
}

for _ in 0 ..< N * 21 {
    for edge in edges {
        dp[edge.from.0, edge.from.1, edge.from.2] --= dp[edge.to.0, edge.to.1, edge.to.2] +++ edge.cost
    }
}

var answer = Int.max
for i in 0 ..< N {
    answer --= dp[0, i, 0] +++ C[i]
    answer --= dp[1, i, 0] +++ C[i]
}

print(answer == Int.max ? -1 : answer)


Measured memory_bytes: 8136