#include<iostream>
#include<complex>
#include<vector>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<cassert>

using namespace std;

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

#define X real()
#define Y imag()

typedef complex<double> P;
typedef pair<P, P> L;
typedef vector<P> Pol;

const double INF = 1e40;
const double EPS = 1e-8;
const double PI = acos(-1);

int sig(double r) {return (r < -EPS) ? -1 : (r > EPS) ? 1: 0;}
bool eq(double a, double b) {return abs(a - b) < EPS;}
bool near(P a, P b) {return abs(b - a) < EPS;}

bool lessX(P a, P b){
  if(!eq(a.X, b.X)) return a.X < b.X;
  if(!eq(a.Y, b.Y)) return a.Y < b.Y;
  return false;
}

// 内積
double dot(P a, P b) {return a.X * b.X + a.Y * b.Y;}
// 外積
double cross(P a, P b) {return a.X * b.Y - a.Y * b.X;}

// 線分のベクトル
P vec(L a) {return a.second - a.first;}

// 線分abに対する点xの位置
enum CCW{FRONT = 1, RIGHT = 2, BACK = 4, LEFT = 8, ON = 16};
int ccw(L s, P p) {
  P a = vec(s);
  p -= s.first;
  double cr = cross(a, p);
  if (eq(cr, 0)) {
    if (sig(dot(a, p)) < 0) return BACK;
    if (sig(norm(a) - norm(p)) < 0) return FRONT;
    return ON;
  }
  return (cr > 0) ? LEFT : RIGHT;
}

// 角度
double ang(P p) {double theta = arg(p); return sig(theta - PI) < 0 ? theta : -PI;}
// 有向角度
double ang(P base, P a, P b) {return ang((b - base) / (a - base));}
P dv(double theta) {return polar(1., theta);}

// 交差判定
bool iSS(L a, L b) {
  int cwa = ccw(a, b.first) | ccw(a, b.second);
  int cwb = ccw(b, a.first) | ccw(b, a.second);
  if ((cwa | cwb) & ON) return true;
  return (cwa & cwb) == (LEFT | RIGHT);
}
// 交点
P pLL(L a, L b) {return a.first + vec(a) * (cross(vec(b), b.first - a.first) / cross(vec(b), vec(a)));}

// 線分アレンジメント 隣の点への辺のみを持つ
pair<vector<P>, vector<vector<int> > > sArr(vector<L> s) {
  vector<P> vp;
  rep (i, s.size()) {
    vp.push_back(s[i].first);
    vp.push_back(s[i].second);
  }
  rep (i,s.size()) {
    rep (j, i) if (iSS(s[i], s[j])) {
      vp.push_back(pLL(s[i], s[j]));
    }
  }
  sort(vp.begin(), vp.end(), lessX);
  vp.erase(unique(vp.begin(), vp.end(), near), vp.end());
  vector<vector<int> > g(vp.size());
  //rep (i, vp.size()) cout << i << " " << vp[i] << endl;
  rep (i, s.size()) {
    vector<pair<double, int> > v;
    rep (j, vp.size()) if (ccw(s[i], vp[j]) == ON) {
      v.push_back(make_pair(norm(vp[j] - s[i].first), j));
    }
    sort(v.begin(), v.end());
    rep (j, v.size() - 1) {
      g[v[j + 1].second].push_back(v[j].second);
      g[v[j].second].push_back(v[j + 1].second);
    }
  }
  return make_pair(vp, g);
}

vector<L> vs;
double mem[2000][2000];
struct hoge{
  double cost;
  int pre, now;
  bool operator<(hoge h) const {return cost > h.cost;}
};

int main() {
  int n;
  for (;;) {
    cin >> n;
    if (n == 0) break;
    vs.clear();
    rep (i, n) {
      L s;
      cin >> s.first.X >> s.first.Y >> s.second.X >> s.second.Y;
      vs.push_back(s);
    }
    pair<vector<P>, vector<vector<int> > > graph = sArr(vs);
    P s, e;
    cin >> s.X >> s.Y >> e.X >> e.Y;
    int m = graph.first.size();
    int ss, ee;
    rep (i, m) if (near(s, graph.first[i])) ss = i;
    rep (i, m) if (near(e, graph.first[i])) ee = i;
    rep (i, m) rep (j, m) mem[i][j] = INF;
    priority_queue<hoge> que;
    hoge h;
    rep (i, graph.second[ss].size()) {
      h.cost = 0;
      h.pre = ss;
      h.now = graph.second[ss][i];
      que.push(h);
    }
    while (!que.empty()) {
      hoge now = que.top();
      que.pop();
      if (mem[now.pre][now.now] <= now.cost) continue;
      mem[now.pre][now.now] = now.cost;
      rep (i, graph.second[now.now].size()) {
	int next = graph.second[now.now][i];
	hoge hh;
	hh.cost = now.cost + PI - abs(ang(graph.first[now.now], graph.first[now.pre], graph.first[next]));
	hh.pre = now.now;
	hh.now = next;
	que.push(hh);
      }
    }
    double res = INF;
    rep (i, m) res = min(res, mem[i][ee]);
    if (eq(res, INF)) cout << -1 << endl;
    else printf("%.12lf\n", res * 360 / (2 * PI));
  }
  return 0;
}

Measured memory_bytes: 0