import java.lang.Math.*
import java.util.*

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)
    fun toRadian():Double = when{
        sin >= 0 -> acos(cos)
        else -> 2 * PI - acos(cos)
    }
}
data class Point(val x:Rational, val y:Rational){
    operator fun minus(other:Point):Point = Point(x - other.x, y - other.y)
    operator fun compareTo(other:Point):Int = x.compareTo(other.x).let{if (it == 0) y.compareTo(other.y) else it}
    companion object {
        operator fun invoke(x:Int, y:Int):Point = Point(Rational(x.toLong(), 1L), Rational(y.toLong(), 1L))
    }
}
data class Wire(val from:Point, val to:Point){
    val length:Double = (to - from).let{sqrt((it.x * it.x + it.y * it.y).toDouble())}
    val angle:Angle = (to - from).let{(x, y) -> Angle(y.toDouble() / length, x.toDouble() / length)}
}
fun distanceSquare(from:Point, to:Point):Rational = (to - from).let{it.x * it.x + it.y * it.y}
fun Wire.crossPoint(other:Wire):Point? {//TODO()
    //println("$this crossPoint $other")
    val diff = to - from // aDiff.x (y - from.y) == aDiff.y (x - from.x)
    val oDiff = other.to - other.from
    if (diff.x == 0.toRational() && diff.y == 0.toRational()) return null
    if (diff.y * oDiff.x == diff.x * oDiff.y) {
        if (cross(from, other.to, to) != 0.toRational()) return null
        val (greater, less) = if (other.to >= other.from) Pair(other.to, other.from) else Pair(other.from, other.to)
        return if (greater >= to && to >= less) from
        else null
    }
    if (cross(from, other.to, to) * cross(from, other.from, to) > 0 || cross(other.from, from, other.to) * cross(other.from, to, other.to) > 0) return null
    //diff.y * oDiff.x * (x - from.x) + from.y * oDiff.x * diff.x == oDiff.y * diff.x * (x - other.from.x) + other.from.y * oDiff.x * diff.x
    val x = (from.y * oDiff.x * diff.x + other.from.x * oDiff.y * diff.x - other.from.y * oDiff.x * diff.x - from.x * oDiff.x * diff.y) / (diff.x * oDiff.y - oDiff.x * diff.y)
    // diff.x * oDiff.y (y - from.y) + from.x * diff.y * oDiff.y == diff.y * oDiff.x (y - other.from.y) + other.from.x * diff.y * oDiff.y
    val y = (from.x * diff.y * oDiff.y + other.from.y * diff.y * oDiff.x - from.y * diff.x * oDiff.y - other.from.x * diff.y * oDiff.y) / (diff.y * oDiff.x - diff.x * oDiff.y)
    return Point(x, y)
}
fun Wire.isInclude(point:Point):Boolean {
    if (cross(from, point, to) != 0.toRational()) return false
    val (greater, less) = if (to >= from) Pair(to, from) else Pair(from, to)
    return greater >= point && point >= less
}
fun cross(from:Point, mid:Point, to:Point):Rational {
    val vecA = mid - from
    val vecB = to - mid
    return vecA.x * vecB.y - vecA.y * vecB.x
}
fun dot(from:Point, mid:Point, to:Point):Rational {
    val vecA = mid - from
    val vecB = to - mid
    return vecA.x * vecB.x + vecA.y * vecB.y
}
fun Int.toRational():Rational = Rational(this.toLong(), 1L)
class Rational(num:Long, den:Long){
    operator fun compareTo(other: Rational): Int {
        return (numerator * other.denominator).compareTo(denominator * other.numerator)
    }
    operator fun compareTo(other:Int):Int {
        return (numerator).compareTo(denominator * other)
    }
    override operator fun equals(other:Any?):Boolean {
        return when(other){
            is Rational -> this.compareTo(other) == 0
            is Int -> this.compareTo(other) == 0
            else -> false
        }
    }

    override fun hashCode(): Int {
        return Pair(numerator, denominator).hashCode()
    }

    override fun toString(): String {
        return "$numerator/$denominator"
    }
    val denominator:Long = abs(den) / gcd(abs(den), abs(num))
    val numerator:Long = abs(num) * sign(num) * sign(den) / gcd(abs(den), abs(num))
    operator fun plus(other:Rational):Rational = Rational(numerator * other.denominator + other.numerator * denominator, denominator * other.denominator)
    operator fun minus(other:Rational):Rational = Rational(numerator * other.denominator - other.numerator * denominator, denominator * other.denominator)
    operator fun times(other:Rational):Rational = Rational(numerator * other.numerator, denominator * other.denominator)
    operator fun div(other:Rational):Rational = Rational(numerator * other.denominator, denominator * other.numerator)
    fun toDouble():Double = numerator.toDouble() / denominator
    companion object {
        private fun gcd(a:Long, b:Long):Long {
            return when(b){
                0L -> a
                else -> gcd(b, a % b)
            }
        }
        private fun sign(value:Long):Int {
            return value.compareTo(0)
        }
    }
}
data class RobotState(val onWireId:Int, val current:Point, val to:Point, val direction:Int)
fun main(args:Array<String>):Unit {
    while(true){
        val n = readLine()!!.trim().toInt()
        if (n == 0) return
        val wires = Array(n){
            val (x1, y1, x2, y2) = readLine()!!.trim().split(' ').map(String::toInt)
            Wire(Point(x1, y1), Point(x2, y2))
        }
        val (start, goal) = readLine()!!.trim().split(' ').map(String::toInt).let{
            val (sx, sy, gx, gy) = it
            Pair(Point(sx, sy), Point(gx, gy))
        }
        val wireMinCost = Array(n){Array(2){Double.MAX_VALUE}}
        val wirePrev = Array(n){Array(2){null as RobotState?}}
        val priorityQueue = PriorityQueue(compareBy(Pair<Double, RobotState>::first)).apply {
            for (i in wires.indices){
                if (wires[i].isInclude(start)) {
                    if (wires[i].to != start) {
                        wireMinCost[i][0] = 0.0
                        add(Pair(0.0, RobotState(i, start, wires[i].to, 0)))
                    }
                    if (wires[i].from != start) {
                        wireMinCost[i][1] = 0.0
                        add(Pair(0.0, RobotState(i, start, wires[i].from, 1)))
                    }
                }
            }
        }
        while (priorityQueue.isNotEmpty() && !priorityQueue.peek().second.let{(_, cu, to, _) -> Wire(cu, to)}.isInclude(goal)){
            val (cost, state) = priorityQueue.remove()
            if (cost == wireMinCost[state.onWireId][state.direction]){
                val currentWire = Wire(state.current, state.to)
                for (i in wires.indices){
                    if (i != state.onWireId){
                        val p = currentWire.crossPoint(wires[i])
                        when(p){
                            is Point -> {
                                if (acos((wires[i].angle - currentWire.angle).cos) + cost < wireMinCost[i][0]){
                                    wireMinCost[i][0] = acos((wires[i].angle - currentWire.angle).cos) + cost
                                    wirePrev[i][0] = state
                                    priorityQueue.add(Pair(wireMinCost[i][0], RobotState(i, p, wires[i].to, 0)))
                                }
                                if (acos(-(wires[i].angle - currentWire.angle).cos) + cost < wireMinCost[i][1]){
                                    wireMinCost[i][1] = acos(-(wires[i].angle - currentWire.angle).cos) + cost
                                    wirePrev[i][1] = state
                                    priorityQueue.add(Pair(wireMinCost[i][1], RobotState(i, p, wires[i].from, 1)))
                                }
                            }
                            else -> Unit
                        }
                    }
                }
            }
        }
/*        val endState= priorityQueue.peek().second
        var current = endState
        var prev = wirePrev[current.onWireId][current.direction]
        while(prev != null){
            //println("${current.to} <- ${current.current} <- ${next.current}")
            //println("${current.current}")
            println("${Wire(prev.current, current.current).angle.toRadian() * 180 / PI} -> ${Wire(current.current, current.to).angle.toRadian() * 180 / PI}")
            println("${(wireMinCost[current.onWireId][current.direction] - wireMinCost[prev.onWireId][prev.direction]) * 180 / PI}")
            current = prev
            prev = wirePrev[current.onWireId][current.direction]
        }*/
        println(
                if (priorityQueue.isEmpty()) -1
                else priorityQueue.peek().first * 180 / PI
        )
    }
}


Measured memory_bytes: 43124