import java.lang.Math.abs
import java.lang.Math.sqrt

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 Vector(val x:Double, val y:Double) {
    val length:Double
        get() = sqrt(x * x + y * y)
    constructor(from:Point, to:Point):this(to.x - from.x, to.y - from.y)
}
data class Circle(val center:Point, val radius:Double)
data class Edge(val a:Point, val b:Point){
    val length:Double
        get() = (a - b).let{sqrt(it.x * it.x + it.y * it.y)}
}
data class Angle(val sin:Double, val cos:Double) {
    companion object {
        private const val e:Double = 0.00000000001
    }
    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)
    override operator fun equals(other: Any?): Boolean {
        return when (other) {
            is Angle -> (cos - other.cos).let { it * it < e } && (sin - other.sin).let { it * it < e }
            else -> false
        }
    }
    override fun hashCode(): Int {
        return super.hashCode()
    }
}
class Line private constructor(private val mA:Double, private val mB:Double, private val mC:Double, private val mD:Double){
    val inclination:Angle
        get() = sqrt(mA * mA + mC * mC).let{ len -> (sign(mA) * sign(mC)).let{Angle(abs(mC) / len, it * abs(mA) / len)}}
    constructor(point:Point, angle:Angle):this(angle.cos, point.y, angle.sin, point.x)
    constructor(from:Point, to:Point):this(from.x - to.x, to.y, from.y - to.y, to.x)
    companion object {
        fun crossPoint(a:Line, b:Line):Point? {
            if (isParallel(a, b)) return null
            return Point((b.mA * a.mC * a.mD - a.mA * b.mC * b.mD - a.mA * b.mA * a.mB + a.mA * b.mA * b.mB) / (b.mA * a.mC - a.mA * b.mC),
                    (a.mA * a.mB * b.mC - b.mA * b.mB * a.mC - a.mC * b.mC * a.mD + a.mC * b.mC * b.mD) / (a.mA * b.mC - b.mA * a.mC))
        }
        private fun isParallel(a:Line, b:Line):Boolean{
            return a.inclination == b.inclination
        }
    }
}
fun sign(value:Double):Double {
    return if (value >= 0) 1.0 else -1.0
}
fun distance(a:Point, b:Point):Double{
    return (a - b).let{sqrt(it.x * it.x + it.y * it.y)}
}
fun Point.toVectorFrom(from:Point):Vector = Vector(from, this)
fun Point.toVector():Vector = Vector(x, y)
fun viewAngle(circle: Circle, from: Point): Angle{
    return (circle.radius / distance(circle.center, from)).let{sin -> Angle(sin, sqrt(1 - sin * sin))}
}
fun isBlocked(edge:Edge, circle: Circle):Boolean {
    if (cos(edge.a.toVectorFrom(edge.b), edge.a.toVectorFrom(circle.center)) <= viewAngle(circle, edge.a).cos + 0.000000001) return false
    return cos(edge.a.toVectorFrom(edge.b), edge.a.toVectorFrom(circle.center)) >= 0 &&
            cos(edge.b.toVectorFrom(edge.a), edge.b.toVectorFrom(circle.center)) >= 0
}
fun dot(a:Vector, b:Vector):Double {
    return a.x * b.x + a.y * b.y
}
fun cos(a:Vector, b:Vector):Double {
    return dot(a, b) / a.length / b.length
}
fun tangentialLine(point:Point, circle: Circle):Iterable<Line> {
    val viewA = viewAngle(circle, point)
    val angle = Line(point, circle.center).inclination
    return listOf(Line(point, angle + viewA), Line(point, angle - viewA))
}
fun minDistanceByCircle(a:Pair<Point, Iterable<Line>>, b:Pair<Point, Iterable<Line>>, circles:Iterable<Circle>):Double? {
    val (ap, aLines) = a
    val (bp, bLines) = b
    return aLines.flatMap { aLine ->
        bLines.mapNotNull {bLine ->
            Line.crossPoint(aLine, bLine) }
    }.filterNot{cp ->
        circles.any{isBlocked(Edge(ap, cp), it) || isBlocked(Edge(bp, cp), it)}
    }.map{cp ->
        distance(ap, cp) + distance(bp, cp)
    }.min()
}
fun main(args:Array<String>):Unit{
    val n = readLine()!!.trim().toInt()
    val circles = List(2){
        val (x, y, r) = readLine()!!.trim().split(' ').map(String::toDouble)
        Circle(Point(x, y), r)
    }
    val red = Array(n){
        val (x, y) = readLine()!!.trim().split(' ').map(String::toDouble)
        Point(x, y)
    }.map{p -> Pair(p, circles.flatMap { tangentialLine(p, it)})}
    val blue = Array(n){
        val (x, y) = readLine()!!.trim().split(' ').map(String::toDouble)
        Point(x, y)
    }.map{p -> Pair(p, circles.flatMap{tangentialLine(p, it)})}
    val minCost = searchMinCostMatch(red.map{r -> blue.map{b -> if (circles.any{isBlocked(Edge(r.first, b.first), it)}) minDistanceByCircle(r, b, circles) else distance(r.first, b.first)}.toTypedArray()}.toTypedArray())
    println(when(minCost){
        null -> "Impossible"
        else -> minCost
    })
}
fun searchMinCostMatch(edges:Array<Array<Double?>>):Double? {   //edges[red][blue] => redとblueの最短距離. なければnull
    val n = edges.size  //|Red| == |Blue| == n
    val rPotentialRed = Array(n){0.0}    //potentialRed[red] => redノードのポテンシャル
    val rPotentialBlue = Array(n){b -> edges.mapNotNull{it[b]}.min() ?: return null} //potentialBlue[blue] => blueノードのポテンシャル
    val rMatchingRed = Array(n){-1} //rMatchingRed[red] => redとマッチングしているblueがあればblue. そうでなければ-1
    val rMatchingBlue = Array(n){-1} //rMatchingBlue[blue] => blueとマッチングしているredがあればred.　そうでなければ-1
    val dMinRed = Array(n){Double.MAX_VALUE}    //dijkstra法で最短パスのコスト
    val dMinBlue = Array(n){Double.MAX_VALUE}   //dijkstra法で最短パスのコスト
    val dPrevRed = Array(n){-1}  //dPrevRed[red] => dijkstra法で最短パスの前のノードを保持. -1の場合s
    val dPrevBlue = Array(n){-1}  //dPrevBlue[blue] => dijkstra法で最短パスの前のノードを保持. -1の場合最短パスなし
    val isRenewRed = Array(n){false}
    var rTPotential = 0.0
    repeat(n){
        dMinRed.fill(Double.MAX_VALUE)
        dMinBlue.fill(Double.MAX_VALUE)
        dPrevRed.fill(-1)
        dPrevBlue.fill(-1)
        rMatchingRed.forEachIndexed { red, blue ->
            if (blue == -1) {
                dMinRed[red] = 0.0
                isRenewRed[red] = true
            }
        }
        var tMinCost = Double.MAX_VALUE
        var tIsRenew = false
        var minPath = -1
        while(isRenewRed.any{it} || tIsRenew){
            val (red, cost) = dMinRed.withIndex().filter{isRenewRed[it.index]}.minBy { it.value } ?: IndexedValue(-1, tMinCost)
            tIsRenew = false
            isRenewRed.fill(false)
            if (red == -1 || dMinRed[red] > tMinCost){
                rMatchingBlue.forEachIndexed { blue, nextRed ->
                    if (nextRed != -1){
                        if (dMinBlue[blue] > rTPotential - rPotentialBlue[blue] + tMinCost){
                            dMinBlue[blue] = rTPotential - rPotentialBlue[blue] + tMinCost
                            if (dMinRed[nextRed] > rPotentialBlue[blue] + edges[nextRed][blue]!! - rPotentialRed[nextRed] + dMinBlue[blue]){
                                dMinRed[nextRed] = rPotentialBlue[blue] + edges[nextRed][blue]!! - rPotentialRed[nextRed] + dMinBlue[blue]
                                isRenewRed[nextRed] = true
                            }
                        }
                    }
                }
            }
            else {
                edges[red].forEachIndexed { blue, d ->
                    if (d != null) {
                        if (dMinBlue[blue] > rPotentialRed[red] + d - rPotentialBlue[blue] + cost) {
                            dMinBlue[blue] = rPotentialRed[red] + d - rPotentialBlue[blue] + cost
                            dPrevBlue[blue] = red
                            if (tMinCost > dMinBlue[blue] + rPotentialBlue[blue]){
                                tMinCost = dMinBlue[blue] + rPotentialBlue[blue]
                                tIsRenew = true
                                minPath = blue
                            }
                            if (rMatchingBlue[blue] != -1) {
                                val nextRed = rMatchingBlue[blue]
                                if (dMinRed[nextRed] > rPotentialBlue[blue] + edges[nextRed][blue]!! - rPotentialRed[nextRed] + dMinBlue[blue]) {
                                    dMinRed[nextRed] = rPotentialBlue[blue] + edges[nextRed][blue]!! - rPotentialRed[nextRed] + dMinBlue[blue]
                                    dPrevRed[nextRed] = blue
                                    isRenewRed[nextRed] = true
                                }
                            }
                        }
                    }
                }
            }
        }
        if (minPath == -1) return null
        var blue = minPath
        while(blue != -1){
            val nextBlue = rMatchingRed[dPrevBlue[blue]]
            rMatchingBlue[blue] = dPrevBlue[blue]
            rMatchingRed[dPrevBlue[blue]] = blue
            blue = nextBlue
        }
        for (i in 0 until n){
            rPotentialRed[i] += dMinRed[i]
            rPotentialBlue[i] += dMinBlue[i]
        }
        rTPotential = tMinCost
    }
    return rMatchingRed.mapIndexed { red, blue -> edges[red][blue]!! }.sum()
}
