
object Main extends App {

  import scala.math.{sqrt, abs}
  import scala.io.StdIn.readLine

  val n = readLine().toInt
  val Array(ca, cb) = Array.tabulate(2){_ ⇒
    val Array(x, y, r) = readLine().split(' ').map(_.toDouble)
    Circle(Point(x, y), r)
  }
  val red = Array.tabulate(n){_ ⇒
    val Array(x, y) = readLine().split(' ').map(_.toDouble)
    Point(x, y)
  }
  val blue = Array.tabulate(n){_ ⇒
    val Array(x, y) = readLine().split(' ').map(_.toDouble)
    Point(x, y)
  }
  val rTuple = red.map{p ⇒ (p, tangentialLine(p, ca), tangentialLine(p, cb))}
  val bTuple = blue.map{p ⇒ (p, tangentialLine(p, ca), tangentialLine(p, cb))}
  val edges = rTuple.map{r ⇒ bTuple.map{b ⇒ minDistanceByCircle(r, b, (ca, cb))}}
  searchMinCostMatch(edges) match{
    case Some(d) ⇒ println(d)
    case None ⇒ println("Impossible")
  }

  case class Point(x: Double, y: Double) {
    def + (other: Point): Point = Point(x + other.x, y + other.y)

    def - (other: Point): Point = Point(x - other.x, y - other.y)
  }

  case class Circle(center: Point, radius: Double)

  object Line {
    def apply(point: Point, angle: Angle): Line = new Line(-angle.sin, angle.cos, angle.sin * point.x - angle.cos * point.y)

    def apply(a: Point, b: Point): Line = new Line(b.y - a.y, a.x - b.x, (a.y - b.y) * b.x + (b.x - a.x) * b.y)

    def isParallel(lineA: Line, lineB: Line): Boolean = abs(lineA.mA * lineB.mB - lineA.mB * lineB.mA) < 1e-10

    def crossPoint(lineA: Line, lineB: Line): Option[Point] = {
      if (isParallel(lineA, lineB)) None
      else {
        val x = (lineB.mC * lineA.mB - lineA.mC * lineB.mB) / (lineA.mA * lineB.mB - lineB.mA * lineA.mB)
        val y = (lineB.mA * lineA.mC - lineA.mA * lineB.mC) / (lineA.mA * lineB.mB - lineB.mA * lineA.mB)
        Some(Point(x, y))
      }
    }
  }

  class Line private(val mA: Double, val mB: Double, val mC: Double) {
    def angle: Angle = {
      val len = sqrt(mA * mA + mB * mB)
      Angle(-mA / len, mB / len)
    }
  }

  case class Angle(sin: Double, cos: Double) {
    def + (other: Angle): Angle = Angle(sin * other.cos + cos * other.sin, cos * other.cos - sin * other.sin)

    def - (other: Angle): Angle = Angle(sin * other.cos - cos * other.sin, cos * other.cos + sin * other.sin)
  }

  case class Edge(endA: Point, endB: Point)

  def distance(a: Point, b: Point): Double = {
    sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y))
  }

  def isBlocked(edge: Edge, circle: Circle): Boolean = {
    val epsilon = 1e-10
    if (distance(edge.endA, circle.center) < circle.radius || distance(edge.endB, circle.center) < circle.radius) true
    val eLine = Line(edge.endA, edge.endB)
    val cLine = Line(circle.center, eLine.angle + Angle(1, 0))
    val cp = Line.crossPoint(eLine, cLine).get
    if (distance(cp, circle.center) > (1 - epsilon) * circle.radius) false
    else distance(edge.endA, edge.endB) > distance(cp, edge.endA) && distance(edge.endA, edge.endB) > distance(cp, edge.endB)
  }

  def minDistanceByCircle(a: (Point, Iterable[Line], Iterable[Line]), b: (Point, Iterable[Line], Iterable[Line]), circle: (Circle, Circle)): Option[Double] = {
    val (ca, cb) = circle
    val (ap, aaLines, abLines) = a
    val (bp, baLines, bbLines) = b
    if (!isBlocked(Edge(ap, bp), ca) && !isBlocked(Edge(ap, bp), cb)) Some(distance(ap, bp))
    else {
      val r = (aaLines.flatMap { aa ⇒ baLines.flatMap { ba ⇒ Line.crossPoint(aa, ba) } }.filterNot { p ⇒ isBlocked(Edge(ap, p), cb) || isBlocked(Edge(bp, p), cb) } ++
        aaLines.flatMap { aa ⇒ bbLines.flatMap { bb ⇒ Line.crossPoint(aa, bb) } }.filterNot { p ⇒ isBlocked(Edge(ap, p), cb) || isBlocked(Edge(bp, p), ca) } ++
        abLines.flatMap { ab ⇒ baLines.flatMap { ba ⇒ Line.crossPoint(ab, ba) } }.filterNot { p ⇒ isBlocked(Edge(ap, p), ca) || isBlocked(Edge(bp, p), cb) } ++
        abLines.flatMap { ab ⇒ bbLines.flatMap { bb ⇒ Line.crossPoint(ab, bb) } }.filterNot { p ⇒ isBlocked(Edge(ap, p), ca) || isBlocked(Edge(bp, p), ca) })
        .map { p ⇒ distance(ap, p) + distance(bp, p) }.filter {
        _ <= 10000
      }
      if (r.isEmpty) None
      else Some(r.min)
    }
  }

  def tangentialLine(point: Point, circle: Circle): Iterable[Line] = {
    val relationalCenter = circle.center - point
    val sinSquare = (circle.radius * circle.radius) / (relationalCenter.x * relationalCenter.x + relationalCenter.y * relationalCenter.y)
    val cosSquare = 1 - sinSquare
    val rAngle = Angle(sqrt(sinSquare), sqrt(cosSquare))
    val dist = distance(point, circle.center)
    val sin = relationalCenter.y / dist
    val cos = relationalCenter.x / dist
    val aAngle = Angle(sin, cos)
    List(Line(point, aAngle + rAngle), Line(point, aAngle - rAngle))
  }

  object Node {

    class Red(val id: Int, private val mStart: Start, private val mEdges: Array[Option[Double]]) extends Node {
      private var mPotential: Double = 0.0
      private var mMatchingBlue: Option[Blue] = None
      private var mBlueNodes: List[(Double, Blue)] = List()

      override def edges: Iterable[(Double, Node)] = mMatchingBlue match {
        case Some(blue) ⇒ (0.0, mStart) :: mBlueNodes.filterNot { case (_, b) ⇒ b == blue }
        case None ⇒ mBlueNodes
      }

      override def potential: Double = mPotential

      override def resetPath(): Unit = {
        mPotential += minCost
        minCost = Double.MaxValue
        prev = None
      }

      def matchingCost: Double = {
        mEdges(mMatchingBlue.get.id).get
      }

      override def ensureIncrementalPath(next: Node): Unit = {
        mMatchingBlue = Some(next.asInstanceOf[Blue])
        prev.get.ensureIncrementalPath(this)
      }

      def setBlueNodes(blue: Array[Blue]): Unit = {
        mBlueNodes = blue.flatMap { b ⇒ mEdges(b.id).map { d ⇒ (d, b) } }.toList
      }
    }

    class Blue(val id: Int, private val mGoal: Goal, private val mEdges: Array[Option[Double]]) extends Node {
      private var mPotential: Double = mEdges.flatten.min
      private var mMatchingRed: Option[Red] = None

      override def potential: Double = mPotential

      override def resetPath(): Unit = {
        mPotential += minCost
        minCost = Double.MaxValue
        prev = None
      }

      def edges: Iterable[(Double, Node)] = {
        mMatchingRed.map[(Double, Node)] { it ⇒ (-mEdges(it.id).get, it) }.getOrElse((0.0, mGoal)) :: Nil
      }

      override def ensureIncrementalPath(next: Node): Unit = {
        mMatchingRed = Some(prev.get.asInstanceOf[Red])
        prev.get.ensureIncrementalPath(this)
      }
    }

    class Start extends Node {
      private var mIsUsed: Array[Boolean] = Array()
      private var mRedNodes: Array[Red] = Array()
      minCost = 0.0

      override def edges: Iterable[(Double, Node)] = {
        mIsUsed.zipWithIndex.filterNot {
          _._1
        }.map { z ⇒ (0.0, mRedNodes(z._2)) }
      }

      override def potential: Double = 0.0

      override def ensureIncrementalPath(next: Node): Unit = {
        next match {
          case red: Red ⇒ mIsUsed(red.id) = true
        }
      }

      override def resetPath(): Unit = {}

      def setRedNodes(red: Array[Red]): Unit = {
        mRedNodes = red
        mIsUsed = Array.tabulate(red.length) { _ ⇒ false }
      }
    }

    class Goal extends Node {
      private var mIsUsed: Array[Boolean] = Array()
      private var mBlueNodes: Array[Blue] = Array()
      private var mPotential: Double = 0.0

      override def edges: Iterable[(Double, Node)] = mIsUsed.zipWithIndex.filter {
        _._1
      }.map { z ⇒ (0.0, mBlueNodes(z._2)) }

      override def potential: Double = mPotential

      override def ensureIncrementalPath(next: Node): Unit = ???

      override def resetPath(): Unit = {
        mPotential += minCost
        minCost = Double.MaxValue
        mIsUsed(prev.get.asInstanceOf[Blue].id) = true
        prev = None
      }

      def setBlueNodes(blue: Array[Blue]): Unit = {
        mBlueNodes = blue
        mIsUsed = Array.tabulate(blue.length) { _ ⇒ false }
      }
    }

  }

  sealed trait Node {
    def edges: Iterable[(Double, Node)]

    def potential: Double

    var minCost: Double = Double.MaxValue
    var prev: Option[Node] = None

    def ensureIncrementalPath(next: Node)

    def resetPath(): Unit
  }

  implicit object Ord extends Ordering[(Double, Node)]{
    override def compare(x: (Double, Node), y: (Double, Node)): Int = x._1.compare(y._1)
  }
  def searchMinCostMatch(edges: Array[Array[Option[Double]]]): Option[Double] = {
    if (edges.exists {
      _.forall {
        case Some(_) ⇒ true
        case None ⇒ false
      }
    }) None
    val n = edges.length
    val start = new Node.Start
    val goal = new Node.Goal
    val red = Array.tabulate(n) { i ⇒ new Node.Red(i, start, edges(i)) }
    val blue = Array.tabulate(n) { i ⇒ new Node.Blue(i, goal, edges.map {
      _ (i)
    })
    }
    red.foreach(_.setBlueNodes(blue))
    start.setRedNodes(red)
    goal.setBlueNodes(blue)
    val priorityQueue = scala.collection.mutable.PriorityQueue[(Double, Node)]()
    (0 until n).foreach { _ ⇒
      priorityQueue.enqueue((0.0, start))
      while (!priorityQueue.isEmpty) {
        val (dist, node) = priorityQueue.dequeue()
        if (node.minCost == dist) {
          node.edges.foreach { case (e, to) ⇒
            if (to.minCost > node.potential + e - to.potential + dist) {
              to.minCost = node.potential + e - to.potential + dist
              to.prev = Some(node)
              priorityQueue.enqueue((to.minCost, to))
            }
          }
        }
      }
      goal.prev match {
        case Some(n) ⇒ n.ensureIncrementalPath(goal)
        case None ⇒ return None
      }
      start.resetPath()
      goal.resetPath()
      red.foreach(_.resetPath())
      blue.foreach(_.resetPath())
    }
    Some(red.map {
      _.matchingCost
    }.sum)
  }
}
