#include<complex>
#include<vector>
#include<set>
#include<iostream>
#include<stack>
#include<cmath>
#include<queue>

#define FRONT 0x01
#define RIGHT 0x02
#define BACK 0x04
#define LEFT 0x08
#define OVER 0x10

#define CIRCLE_SAME 0x01
#define CIRCLE_CONTAIN 0x02
#define CIRCLE_NO_CROSS 0x04
#define CIRCLE_ONE_CROSS 0x08
#define CIRCLE_ONE_INSIDE_CROSS 0x10
#define CIRCLE_TWO_CROSS 0x20

#define sc second
#define fr first

#define REP(i,n) for(int i = 0; i < (int)(n); ++i)

using namespace std;

typedef double elem;
typedef complex<elem> point, vec;
typedef pair<point, point> line, hline, seg, pp;

const double eps = 1.0e-6;
const double pi = acos(-1.0);
const double infty = 1e40;
point base(0,0);

// oÍ
ostream &operator<<(ostream &os, const pair<point,point> &p){
  os << p.fr << "-" << p.sc;
  return os;
}

// lZ
inline elem sq(elem a){ return a*a; }
inline elem cq(elem a){ return a*a*a; }

// pxÏ·
elem rad(elem deg){ return (deg/180)*pi; }
elem deg(elem rad){ return (rad*180)/pi; }

// ®¬_Ìô¢AÈÇ
bool eq(elem a, elem b){ return abs(a-b) < eps; }
bool lt(elem a, elem b){ return !eq(a,b) && a < b; }
bool leq(elem a, elem b){ return eq(a,b) || a < b; }
bool gt(elem a, elem b){ return !eq(a,b) && a > b; }
bool geq(elem a, elem b){ return eq(a,b) || a > b; }
bool ltz(elem a){ return lt( a, 0 ); }
bool gtz(elem a){ return gt( a, 0 ); }
bool eqv(vec a, vec b){ return eq( abs(b-a),0); }
bool is_zv(vec v){ return eq(abs(v),0); }
elem emax(elem a, elem b){ return gt(a,b)?a:b; }
elem emin(elem a, elem b){ return lt(a,b)?a:b; }

// _Iy[^
bool far(point a, point b){ return gtz( abs(b-a) ); }
bool near(point a, point b){ return leq( abs(b-a), 0 ); }
elem dot(vec a, vec b){ return (a.real() * b.real() + a.imag() * b.imag() ); }
elem cross(vec a, vec b){ return ( a.real() * b.imag() - a.imag() * b.real() ); }

// a©çbÜÅvñèÌpxAàpA]ñ]
elem varg(vec a, vec b){
  elem ret=arg(a)-arg(b);
  if(lt(ret,0))ret+=2*pi;
  if(gt(ret,2*pi))ret-=2*pi;
  if(eq(ret,2*pi))ret=0;
  return ret;
}
elem arg(vec a, vec b){ return acos( dot(a,b) / ( abs(a) * abs(b) ) ); }
point rot(point p, elem theta){ return p * polar((elem)1.0, theta); }
point rotdeg(point p, elem deg){ return p * polar((elem)1.0, rad(deg)); }
point proj(line l, point p){
  double t=dot(p-l.first,l.first-l.second)/abs(l.first-l.second);
  return l.first + t*(l.first-l.second);
}
point reflect(line l, point p){ return p+2.0*(proj(l,p)-p); }

// ñ_Ô£A¼üÆ_ÌÅZ£AüªÆ_ÌÅZ£
elem dist(point a, point b){ return abs(a-b); }
elem dist_l(line l, point x){ return abs(cross(l.sc-l.fr,x-l.fr)) / abs(l.sc-l.fr); }
elem dist_seg(seg s, point x)
{
  if( ltz( dot(s.sc-s.fr,x-s.fr) ) ) return abs(x-s.fr);
  if( ltz( dot(s.fr-s.sc,x-s.sc) ) ) return abs(x-s.sc);
  return dist_l(s,x);
}

// PÊxNgA@üxNgAPÊ@üxNg
vec uvec(vec a){ return a / abs(a); }
vec nmr(vec a){ return a * vec(0,-1); }
vec nml(vec a){ return a * vec(0,1); }
vec unmr(vec a){ return uvec( nmr(a) ); }
vec unml(vec a){ return uvec( nml(a) ); }

// ¼ðA½s»è
bool orth(point a1, point a2, point b1, point b2){ return eq( dot( a2 - a1, b2 - b1 ), 0 ); }
bool orth(vec v1, vec v2){ return eq( dot(v1, v2), 0 ); }
bool prll(point a1, point a2, point b1, point b2){ return eq( cross( a2 - a1, b2 - b1 ), 0 ); }
bool prll(vec v1, vec v2){ return eq( cross(v1, v2), 0 ); }

// CCW oXg¾ªA¸xÉæé
int ccw(point a, point b, point x){
  b -= a;
  x -= a;
  // if( is_zv(b) || is_zv( x ) ) return ERROR;
  if( gtz( cross(b,x) ) ) return LEFT;
  if( ltz( cross(b,x) ) ) return RIGHT;
  if( ltz( dot(b,x) ) ) return BACK;
  if( lt( abs(b), abs(x) ) ) return FRONT;
  return OVER;
}

// üªÌð·»è
bool intersectedSS(seg a, seg b)
{
  if( ccw(a.fr,a.sc,b.fr)&OVER || ccw(a.fr,a.sc,b.sc)&OVER ) return true;
  return
    ( ccw(a.fr,a.sc,b.fr) | ccw(a.fr,a.sc,b.sc) ) == (LEFT|RIGHT) &&
    ( ccw(b.fr,b.sc,a.fr) | ccw(b.fr,b.sc,a.sc) ) == (LEFT|RIGHT) ;
}
// ¼üÌð·»è
bool intersectedLL(line a, line b){ return !eq( cross(a.sc-a.fr,b.sc-b.fr), 0.0 ); }

// ð_vZ
point intersectionSS(seg a, seg b)
{
  elem d1 = dist_l(b,a.fr);
  elem d2 = dist_l(b,a.sc);
  return a.fr + ( d1 / (d1 + d2 ) ) * (a.sc-a.fr);
}
point intersectionLL(line a, line b)
{
  vec va = a.sc - a.fr;
  vec vb = b.sc - b.fr;
  return a.fr + va * ( cross(vb, b.fr - a.fr) / cross(vb,va) );
}

// üªð_êÅ
bool intersectionLL(line a, line b, point &ret){
  return intersectedLL( a, b ) ? ret = intersectionLL( a, b ), true : false;
}
bool intersectionLH(line a, hline b, point &ret){
  point tmp;
  return intersectionLL(a,b,tmp) ? ( ccw(b.fr,b.sc,tmp)&(OVER|FRONT) ? ret=tmp, true : false ) : false;
}
bool intersectionLS(line l, seg s, point &ret){
  point tmp;
  return intersectionLL(l,s,tmp) ? ( ccw(s.fr,s.sc,tmp)&OVER ? ret=tmp, true : false ) : false;
}
bool intersectionHH(hline a, hline b, point &ret){
  point tmp;
  return intersectionLL(a,b,tmp) ? ( ccw(a.fr,a.sc,tmp)&(OVER|FRONT)&&ccw(b.fr,b.sc,tmp)&(OVER|FRONT) ? ret = tmp, true : false ) : false;
}
bool intersectionHS(hline a, seg s, point &ret){
  point tmp;
  return intersectionLS(a,s,tmp) ? ( ccw(a.fr,a.sc,tmp)&(OVER|FRONT) ? ret = tmp, true : false ) : false;
}
bool intersectionSS(seg a, seg b, point &ret){
  return intersectedSS(a,b) ? ret = intersectionSS(a,b), true : false;
}

struct Node{
  point p;
  vector<int> con;
  Node(){}
  Node(point p):p(p){}
};

typedef vector<Node> Graph;

struct State{
  int prev;
  int now;
  double cost;
  State(int prev, int now, double cost):prev(prev),now(now),cost(cost){}
  bool operator>(const State &t)const{
    return cost > t.cost;
  }
};

double weight(int pre, int now, int next, const Graph &G){
  if( now == 0 ) return 0;
  vec a(G[now].p-G[pre].p);
  vec b(G[next].p-G[now].p);
  double ret = varg( a, b );
  // assert(ret>=0);
  return gt(ret,pi)?2*pi-ret:ret;
}

double dijkstra(int st, const Graph &G){
  double ret = infty;
  priority_queue< State, vector<State>, greater<State> > pq;
  bool vis[G.size()+1][G.size()];
  double C[G.size()+1][G.size()];
  for(int i = 0; i < G.size()+1; ++i){
    for(int j = 0; j < G.size(); ++j){
      vis[i][j]=false;
      C[i][j]=infty;
    }
  }
  
  pq.push( State(G.size(),st,0.0) );
  C[G.size()][st]=0;
  while(!pq.empty()){
    State now = pq.top(); pq.pop();
    
    //cout << " PREV : " <<  now.prev << " NOW : " << now.now << " COST : " << now.cost << endl;
    vis[now.prev][now.now] = false;
    
    /*
    if( vis[ now.prev ][ now.now ] ) continue;
    else{
      vis[ now.prev ][ now.now ] =true;
      if( now.now == 1 ){
	//ret = emin( ret, now.cost );
	continue;
      }
    }
    */
    
    const vector<int> &con = G[now.now].con;
    for(int i = 0; i < con.size(); ++i){
      int nextid = con[i];
      double newcost = now.cost + weight(now.prev, now.now, nextid, G);
      if( lt( newcost, C[now.now][nextid] ) ){
	C[now.now][nextid] = newcost;
	if( !vis[now.now][nextid] ){
	  vis[now.now][nextid]=true;
	  State next( now.now, nextid, newcost );
	  pq.push( next );
	}
      }
    }
    
  }

  for(int i = 0; i < G.size()+1; ++i){
    ret = emin( ret, C[i][1] );
  }
  return ret;
}

struct Point{
  point p;
  bool operator<(const Point &t)const{
    return eq(p.real(),t.p.real()) ? lt( p.imag(), t.p.imag() ) : lt(p.real(),t.p.real());
  }
  Point ():p(0,0){}
  Point (point p):p(p){}
};

int main(){
  while(true){
    int n;
    cin >> n;
    if ( n == 0 ) break;
    Graph G;
    set<Point> exist_intersection;
    vector<seg> segs;
    
    for(int i = 0; i < n; ++i){
      elem x1,y1,x2,y2;
      cin >> x1 >> y1 >> x2 >> y2;
      segs.push_back( seg(point(x1,y1),point(x2,y2)) );
    }

    elem sx,sy,gx,gy;cin>>sx>>sy>>gx>>gy;
    G.push_back(point(sx,sy));
    exist_intersection.insert( Point(point(sx,sy)) );
    if(exist_intersection.find(Point(point(gx,gy)))==exist_intersection.end()){
      G.push_back(point(gx,gy));
      exist_intersection.insert(Point(point(gx,gy)));
    }else{
      printf("0.0\n");continue;
    }

    for(int i = 0; i < segs.size(); ++i){
      if( exist_intersection.find(Point(segs[i].fr))==exist_intersection.end()){
	exist_intersection.insert(Point(segs[i].fr));
	G.push_back( segs[i].fr );
      }
      if( exist_intersection.find(Point(segs[i].sc))==exist_intersection.end()){
	exist_intersection.insert(Point(segs[i].sc));
	G.push_back( segs[i].sc );
      }
      for(int j = 0; j < segs.size(); ++j){
	if( i != j ){
	  point tmp;
	  if( intersectionSS( segs[i], segs[j], tmp ) ){
	    if( exist_intersection.find(Point(tmp)) == exist_intersection.end() ){
	      exist_intersection.insert( Point(tmp) );
	      G.push_back( Node(tmp) );
	    }
	  }
	}
      }
    }

    for(int i = 0; i < segs.size(); ++i){
      for(int j = 0; j < G.size(); ++j){
	for(int k = 0; k < G.size(); ++k){
	  if( j != k ){
	    if( ccw( segs[i].fr, segs[i].sc, G[j].p ) == OVER &&
		ccw( segs[i].fr, segs[i].sc, G[k].p ) == OVER ){
	      //cout << G[j].p << ' ' << G[k].p << endl;
	      G[j].con.push_back( k );
	      G[k].con.push_back( j );
	    }
	  }
	}
      }
    }
    
    elem ans = deg( dijkstra( 0, G ) );
    if( geq( ans, infty ) ){
      printf("-1\n");
    }else{
      printf("%.11lf\n",ans);
    }
    
  }
  return 0;
}

Measured memory_bytes: 0