import java.lang.Math.abs
import java.lang.Math.sqrt
import java.util.*

data class Point(val x:Double, val y:Double){
    operator fun plus(other:Point):Point = Point(x + other.x, y + other.y)
    operator fun minus(other:Point):Point = Point(x - other.x, y - other.y)
}
data class Circle(val center:Point, val radius:Double)
class Line private constructor(private val mA:Double, val mB:Double, val mC:Double){// ax + by + c = 0
//cos(y-y1)=sin(x-x1)
fun xAt(y:Double):Double? = if (mA != 0.0) (mB * y + mC) / (-mA) else null
    fun yAt(x:Double):Double? = if (mB != 0.0) (mA * x + mC) / (-mB) else null
    constructor(point:Point, angle:Angle):this(-angle.sin, angle.cos, angle.sin * point.x - angle.cos * point.y)
    constructor(a:Point, b:Point):this(b.y - a.y, a.x - b.x, (a.y - b.y) * b.x + (b.x - a.x) * b.y)
    fun angle():Angle = sqrt(mA * mA + mB * mB).let{Angle(-mA / it, mB / it)}
    companion object {
        private fun isParallel(lineA:Line, lineB:Line):Boolean {
            return abs(lineA.mA * lineB.mB - lineA.mB * lineB.mA) < 1e-10
        }
        fun crossPoint(lineA:Line, lineB:Line):Point? {
            if (isParallel(lineA, lineB)) return null
            // ab'x + bb'y + b'c = 0
            val x = (lineB.mC * lineA.mB - lineA.mC * lineB.mB) / (lineA.mA * lineB.mB - lineB.mA * lineA.mB)
            // aa'x + a'by + a'c = 0
            val y = (lineB.mA * lineA.mC - lineA.mA * lineB.mC) / (lineA.mA * lineB.mB - lineB.mA * lineA.mB)
            return Point(x, y)
        }
    }
}
data class Angle(val sin:Double, val cos:Double){
    operator fun plus(other:Angle):Angle = Angle(sin * other.cos + cos * other.sin, cos * other.cos - sin * other.sin)
    operator fun minus(other:Angle):Angle = Angle(sin * other.cos - cos * other.sin, cos * other.cos + sin * other.sin)
}
data class Edge(val endA:Point, val endB:Point)
fun distance(a:Point, b:Point):Double{
    return sqrt((a - b).let{it.x * it.x + it.y * it.y}.toDouble())
}
fun 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) return true
    val eLine = Line(edge.endA, edge.endB)
    val cLine = Line(circle.center, eLine.angle() + Angle(1.0, 0.0))
    val cp = Line.crossPoint(eLine, cLine)!!
    if (distance(cp, circle.center) > circle.radius - circle.radius * epsilon) return false
    if (distance(edge.endA, edge.endB) > distance(cp, edge.endB) && distance(edge.endA, edge.endB) > distance(cp, edge.endA)) return true
    return false
}

fun minDistanceByCircle(a:Triple<Point, Iterable<Line>, Iterable<Line>>, b:Triple<Point, Iterable<Line>, Iterable<Line>>, circles:Pair<Circle, Circle>):Double? {
    val (ca, cb) = circles
    if (!isBlocked(Edge(a.first, b.first), ca) && !isBlocked(Edge(a.first, b.first), cb)) return distance(a.first, b.first)
    val (ap, aaLines, abLines) = a
    val (bp, baLines, bbLines) = b
    return (
            aaLines.flatMap { aa -> baLines.mapNotNull { ba -> Line.crossPoint(aa, ba) } }.filterNot{
                isBlocked(Edge(ap, it), cb) || isBlocked(Edge(bp, it), cb)
            }.map{distance(ap, it) + distance(bp, it)} +
                    aaLines.flatMap { aa -> bbLines.mapNotNull { bb -> Line.crossPoint(aa, bb) } }.filterNot {
                        isBlocked(Edge(ap, it), cb) || isBlocked(Edge(bp, it), ca)
                    }.map{distance(ap, it) + distance(bp, it)} +
                    abLines.flatMap { ab -> baLines.mapNotNull { ba -> Line.crossPoint(ab, ba) } }.filterNot{
                        isBlocked(Edge(ap, it), ca) || isBlocked(Edge(bp, it), cb)
                    }.map{distance(ap, it) + distance(bp, it)} +
                    abLines.flatMap { ab -> bbLines.mapNotNull { bb -> Line.crossPoint(ab, bb) } }.filterNot {
                        isBlocked(Edge(ap, it), ca) || isBlocked(Edge(bp, it), ca)
                    }.map{distance(ap, it) + distance(bp, it)}
            ).filter{it <= 10000.0}.min()
}
fun tangentialLine(point:Point, circle: Circle):Iterable<Line> {
    val relationalCenter = circle.center - point
    val sinSquare = circle.radius.let{it * it} / (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)
    return listOf(Line(point, aAngle + rAngle), Line(point, aAngle - rAngle))
}

fun main(args:Array<String>):Unit{
    val n = readLine()!!.trim().toInt()
    val circles = List(2){
        val (x, y, r) = readLine()!!.trim().split(' ').filter{"""\d+""".toRegex().matches(it)}.map(String::toDouble)
        Circle(Point(x, y), r)
    }
    val pair = Pair(circles.first(), circles.last())
    val red = Array(n){
        val (x, y) = readLine()!!.trim().split(' ').filter{"""\d+""".toRegex().matches(it)}.map(String::toDouble)
        Point(x, y)
    }
    val blue = Array(n){
        val (x, y) = readLine()!!.trim().split(' ').filter{"""\d+""".toRegex().matches(it)}.map(String::toDouble)
        Point(x, y)
    }
    val edges = calTangentialLine(red, pair).map { r -> calTangentialLine(blue, pair).map { b -> minDistanceByCircle(r, b, pair) }.toTypedArray() }.toTypedArray()
    val minC = searchMinCostMatch(edges)

    println(minC ?: "Impossible")
}
fun calTangentialLine(points:Array<Point>, pair:Pair<Circle, Circle>):Array<Triple<Point, Iterable<Line>, Iterable<Line>>>{
    return points.map{p -> Triple(p, tangentialLine(p, pair.first), tangentialLine(p, pair.second))}.toTypedArray()
}

interface Node{
    fun edges():Iterable<Pair<Double, Node>>
    val potential:Double
    var minCost:Double
    var prev:Node?
    fun ensureIncrementalPath(next:Node):Unit
    fun resetPath():Unit
    class Red(val id:Int, private val mStart:Start, private val mEdges:Array<Double?>):Node{
        override fun resetPath() {
            potential += minCost
            minCost = Double.MAX_VALUE
            prev = null
        }
        val matchingCost:Double
            get() = mEdges[(mMatchingBlue as Blue).id]!!
        override fun ensureIncrementalPath(next:Node) {
            mMatchingBlue = when(next){
                is Blue -> next
                else -> throw Exception()
            }
            prev!!.ensureIncrementalPath(this)
        }

        override var prev: Node? = null
        private var mMatchingBlue:Blue? = null  //マッチングしているBlueノードがあればそのノード。なければnull
        private var mBlueNodes:Iterable<Pair<Double, Blue>> = listOf() //このノードと辺を持つBlueノードとその重み
        override fun edges(): Iterable<Pair<Double, Node>> {//
            return when(mMatchingBlue){
                null -> mBlueNodes
                else -> mBlueNodes.filterNot{it.second == mMatchingBlue} + Pair(0.0, mStart)
            }
        }

        override var potential: Double = 0.0
            private set
        override var minCost: Double = Double.MAX_VALUE

        fun setBlueNodes(blue:Array<Blue>):Unit{
            mBlueNodes = blue.mapNotNull {b ->  mEdges[b.id]?.let{Pair(it, b)} }
        }


        override fun toString(): String {
            return "Red(id = $id, minCost = $minCost, potential = $potential)"
        }
    }

    class Blue(val id:Int, private val mGoal:Goal, private val mEdges:Array<Double?>):Node {
        override fun ensureIncrementalPath(next: Node) {
            mMatchingRed = prev as Red
            prev!!.ensureIncrementalPath(this)
        }
        override fun resetPath() {
            potential += minCost
            minCost = Double.MAX_VALUE
            prev = null
        }

        override fun toString(): String {
            return "Blue(id = $id, minCost = $minCost, potential = $potential)"
        }
        override var prev: Node? = null
        private var mMatchingRed:Red? = null
        override fun edges(): Iterable<Pair<Double, Node>> {
            return listOf(mMatchingRed?.let{
                Pair(-mEdges[it.id]!!, it)
            } ?: Pair(0.0, mGoal))
        }

        override var potential: Double = mEdges.filterNotNull().min() ?: throw Exception()
            private set
        override var minCost: Double = Double.MAX_VALUE

    }

    class Start:Node {
        override fun ensureIncrementalPath(next: Node) {
            when(next){
                is Red -> mIsUsed[next.id] = true
                else -> throw Exception()
            }
        }

        override fun resetPath() {        }

        override var prev: Node?
            get() = null
            set(_){}
        private var mRedNodes:Array<Red> = arrayOf()
        private var mIsUsed:Array<Boolean> = arrayOf()
        override fun edges(): Iterable<Pair<Double, Node>> {
            return mIsUsed.withIndex().filterNot { it.value }.map{Pair(0.0, mRedNodes[it.index])}
        }

        override val potential: Double = 0.0
        override var minCost: Double
            get() = 0.0
            set(_){}

        fun setRedNodes(red:Array<Red>):Unit {
            mRedNodes = red
            mIsUsed = Array(red.size){false}
        }
    }

    class Goal:Node {
        override fun ensureIncrementalPath(next: Node) {
            throw Exception()
        }

        override fun resetPath() {
            potential += minCost
            minCost = Double.MAX_VALUE
            mIsUsed[(prev as Blue).id] = true
            prev = null
        }

        override fun toString(): String {
            return "Goal(minCost = $minCost)"
        }
        override var prev: Node? = null
        private var mBlueNodes:Array<Blue> = arrayOf()
        private var mIsUsed:Array<Boolean> = arrayOf()
        override fun edges(): Iterable<Pair<Double, Node>> {
            return mIsUsed.withIndex().filter{it.value}.map{Pair(0.0, mBlueNodes[it.index])}
        }

        override var potential: Double = 0.0
            private set
        override var minCost: Double = Double.MAX_VALUE

        fun setBlueNodes(blue:Array<Blue>):Unit {
            mBlueNodes = blue
            mIsUsed = Array(blue.size){false}
        }
    }
}
fun searchMinCostMatch(edges:Array<Array<Double?>>):Double? {
    if (edges.any{it.all{it == null}}) return null
    val n = edges.size  //|Red| == |Blue| == n
    val start = Node.Start()
    val goal = Node.Goal()
    val red = Array(n){Node.Red(it, start, edges[it])}
    val blue = Array(n){b -> Node.Blue(b, goal, edges.map{it[b]}.toTypedArray())}
    red.forEach { it.setBlueNodes(blue) }
    start.setRedNodes(red)
    goal.setBlueNodes(blue)
    val priorityQueue = PriorityQueue(compareBy(Pair<Double, Node>::first))
    repeat(n){
        priorityQueue.add(Pair(0.0, start))
        while(priorityQueue.isNotEmpty()){
            val (dist, node) = priorityQueue.poll()
            if (node.minCost == dist){
                node.edges().forEach { (e, to) ->
                    if (to.minCost > node.potential + e - to.potential + dist) {
                        to.minCost = node.potential + e - to.potential + dist
                        to.prev = node
                        priorityQueue.add(Pair(to.minCost, to))
                    }
                }
            }
        }
        (goal.prev ?: return null).ensureIncrementalPath(goal)
        start.resetPath()
        goal.resetPath()
        red.forEach(Node::resetPath)
        blue.forEach(Node::resetPath)
    }
    return red.sumByDouble(Node.Red::matchingCost)
}
