object Main {

  def main(args: Array[String]): Unit = {
    val sc = new java.util.Scanner(System.in)

    val N = sc.nextInt()
    val G = Array.fill(N)(new scala.collection.mutable.ArrayBuffer[(Int, Int)]())
    var i = 0
    while (i < N) {
      val u, k = sc.nextInt()
      var j = 0
      val buffer = G(u)
      while (j < k) {
        val v, c = sc.nextInt()
        buffer.append((v, c))
        j += 1
      }
      i += 1
    }

    def dijkstra(s: Int): Array[Int] = {
      val INF = Int.MaxValue
      val distance = Array.fill(N)(INF)
      distance(s) = 0

      val queue = scala.collection.mutable.PriorityQueue[Int](s)(
        Ordering.by[Int, Int](v => distance(v))(Ordering.Int.reverse))

      def relax(u: Int, v: Int, w: Int): Unit =
        if (distance(u) != INF && distance(u) + w < distance(v)) {
          distance(v) = distance(u) + w
          queue.enqueue(v)
        }

      while (queue.nonEmpty) {
        val u = queue.dequeue()
        G(u) foreach { case (v, w) =>
          relax(u, v, w)
        }
      }
      distance
    }

    val res = dijkstra(0).zipWithIndex.map(u => u._2 + " " + u._1).mkString("\n")
    println(res)
  }

}

