#include <cstdio>
#include <map>
#include <iostream>
#include <vector>
#include <algorithm>
#include <complex>
#include <queue>
using namespace std;

static const double EPS = 1e-10;
typedef complex<double> P;
 
std::istream& operator>>(std::istream& is,P& p)
{
	is >> p.real() >> p.imag();
	return is;
}
struct L : public vector<P> {L(const P &a, const P &b) {push_back(a); push_back(b);} L(){push_back(P(0,0)); push_back(P(0,0));}};
namespace std {bool operator < (const P& a, const P& b) {return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);} }
double cross(const P& a, const P& b) {return imag(conj(a)*b);}
bool intersectLL(const L &l, const L &m) {return abs(cross(l[1]-l[0], m[1]-m[0])) > EPS || abs(cross(l[1]-l[0], m[0]-l[0])) < EPS;}
bool intersectSP(const L &s, const P &p) {return abs(s[0]-p)+abs(s[1]-p)-abs(s[1]-s[0]) < EPS;}

P crosspoint(const L &l, const L &m) {
	double A = cross(l[1] - l[0], m[1] - m[0]);
	double B = cross(l[1] - l[0], l[1] - m[0]);
	if (abs(A) < EPS && abs(B) < EPS) return m[0];
	return m[0] + B / A * (m[1] - m[0]);
}

struct Node{
	int id;
	double dir;
	double cost;
	Node(int id,double dir,double cost) : id(id),dir(dir),cost(cost){}
};
bool operator <(const Node &a,const Node &b){ return a.cost > b.cost;}

double PI = acos(-1);
//fix(x):=角度を[0,2π)の範囲にする
double fix(double x){
	while( x >= 2 * PI ) x -= 2 * PI;
	while( x < 0) x += 2 * PI;
	return x;
}
int main(){
	int n;
	while(cin >> n && n){
		L l[n];
		for(int i = 0 ; i < n ; i++) cin >> l[i][0] >> l[i][1];
		P s,g;
		cin >> s >> g;
		
		vector<P> tar,tar_; // tar:=ダイクストラで中継点/ゴール/スタートとなるであろう点の集合
		tar_.push_back(s);
		tar_.push_back(g);
		for(int i = 0 ; i < n ; i++){
			tar_.push_back(l[i][0]); 
			tar_.push_back(l[i][1]);
			for(int j = 0 ; j < n ; j++){
				if( intersectLL(l[i],l[j]) ) tar_.push_back(crosspoint(l[i],l[j]));
			}
		}
		
		// 重複点を削除する
		sort(tar_.begin(),tar_.end());
		for(int i = 0 ; i < tar_.size() ; i++)
			if( !i || abs(tar_[i-1]-tar_[i]) > EPS ) tar.push_back(tar_[i]);
		
		// 点a→点bが可能かどうかのグラフを構築
		vector< vector<int> > connect(tar.size());
		for(int i = 0 ; i < tar.size() ; i++){
			for(int j = i+1 ; j < tar.size() ; j++){
				for(int k = 0 ; k < n ; k++){
					if( intersectSP(l[k],tar[i]) && intersectSP(l[k],tar[j]) ){
						connect[i].push_back(j);
						connect[j].push_back(i);
						break;
					}
				}
			}
		}
		
		double res = -1;
		priority_queue<Node> Q;
		map< pair<int,long long> , int> done;
		for(int i = 0 ; i < tar.size() ; i++){
			if( abs(tar[i]-s) < EPS ){
				Q.push(Node(i,-114514,0)); // スタート地点を追加
				break;
			}
		}
		while( Q.size() ){
			Node q = Q.top(); Q.pop();
			//(位置,角度)で状態を持っているが，角度が誤差で無限に候補が発生するかもしれないので適当に丸めて扱う
			if( done[make_pair(q.id,(long long)(q.dir*10000000))]++ ) continue;
			P my = tar[q.id];
			if( abs(my-g) < EPS ){
				res = q.cost *180/PI;
				break;
			}
			for(int i = 0 ; i < connect[q.id].size() ; i++){
				int oid = connect[q.id][i];
				P other = tar[oid] - my;
				double rad = fix(atan2(other.imag(),other.real()));
				double diff = fabs(q.dir-rad);
				diff = min(2*PI-diff,diff);
				if( q.dir == -114514 ) diff = 0;
				Q.push(Node(oid,rad,q.cost+diff));
			}
		}
		printf("%.10lf\n",res);
	}
}

Measured memory_bytes: 1440