import scala.collection.mutable

object Main extends App {
  val sc = new java.util.Scanner(System.in)
  val n = sc.nextInt()
  val scs = Array.fill(n)((sc.next(), sc.nextLong()))

  var visited = Set[(String, Boolean)](("", true))
  var ts = List[((String, Boolean), (String, Boolean), Long)]()
  val queue = mutable.Queue(("", true))
  while (queue.nonEmpty) {
    val now @ (r, front) = queue.dequeue()
    for ((s, c) <- scs) {
      val s1 = if (front) s else s.reverse
      if (r.length <= s1.length) {
        if (s1.startsWith(r)) {
          val next = (s1.drop(r.length), (s1 == r) || !front)
          ts ::= (now, next, c)
          if (!visited.contains(next)) {
            visited += next
            queue.enqueue(next)
          }
        }
      } else {
        if (r.startsWith(s1)) {
          val next = (r.drop(s1.length), front)
          ts ::= (now, next, c)
          if (!visited.contains(next)) {
            visited += next
            queue.enqueue(next)
          }
        }
      }
    }
  }

  val renameMap = visited.zipWithIndex.toMap
  val edges = ts.map{case (s1, s2, c) => (renameMap(s1), renameMap(s2), c)}

  val sp = shortestPath(renameMap(("", true)), visited.size, edges)
  var ans = renameMap.filter(_._1._1.length == 1).values.map(sp).minOption.getOrElse(-1L)
  if (sp(renameMap(("", true))) != -1) {
    ans = ans.min(sp(renameMap(("", true))))
  }
  println(ans)

  def shortestPath(s: Int, n: Int, edges: Seq[(Int, Int, Long)]): Array[Long] = {
    val adj = Array.fill(n)(List[(Int, Long)]())
    for ((u, v, l) <- edges) {
      adj(u) ::= (v, l)
    }

    val sp = Array.fill(n)(-1L)
    val heap = new BinaryHeap[Long](n, _ < _)
    heap.add(s, 0)
    while (heap.nonEmpty) {
      val (u, spu) = heap.pop()
      for ((v, l) <- adj(u)) {
        if (sp(v) == -1) {
          sp(v) = spu + l
          heap.add(v, sp(v))
        } else if (spu + l < sp(v)) {
          sp(v) = spu + l
          heap.upPriority(v, sp(v))
        }
      }
    }
    sp
  }

  class BinaryHeap[P](maxSize: Int, comparator: (P, P) => Boolean) {
    private val heap = Array.ofDim[(Int, P)](maxSize)
    private val index = Array.fill(maxSize)(-1)

    var size = 0

    def isEmpty: Boolean = size == 0
    def nonEmpty: Boolean = !isEmpty

    private def par(idx: Int): Int = (idx - 1) / 2
    private def left(idx: Int): Int = 2 * idx + 1
    private def right(idx: Int): Int = 2 * idx + 2

    private def isRoot(idx: Int): Boolean = idx == 0
    private def hasLeft(idx: Int): Boolean = left(idx) < size
    private def hasRight(idx: Int): Boolean = right(idx) < size

    private def swap(i: Int, j: Int): Unit = {
      val t = heap(i)
      heap(i) = heap(j)
      heap(j) = t
      index(heap(i)._1) = i
      index(heap(j)._1) = j
    }

    private def upHeap(idx: Int): Unit = {
      if (!isRoot(idx) && comparator(heap(idx)._2, heap(par(idx))._2)) {
        swap(idx, par(idx))
        upHeap(par(idx))
      }
    }

    private def downHeap(idx: Int): Unit = {
      if (hasLeft(idx)) {
        val t = if (hasRight(idx) && comparator(heap(right(idx))._2, heap(left(idx))._2)) {
          right(idx)
        } else {
          left(idx)
        }
        if (comparator(heap(t)._2, heap(idx)._2)) {
          swap(idx, t)
          downHeap(t)
        }
      }
    }

    def add(a: Int, p: P): Unit = {
      size += 1
      heap(size - 1) = (a, p)
      index(a) = size - 1
      upHeap(size - 1)
    }

    def pop(): (Int, P) = {
      val head = heap(0)
      heap(0) = heap(size - 1)
      size -= 1
      downHeap(0)
      head
    }

    def upPriority(a: Int, p: P): Unit = {
      val idx = index(a)
      heap(idx) = (a, p)
      upHeap(idx)
    }
  }
}
