#include <bits/stdc++.h>

using namespace std;

const double eps = 1e-8;
#define eq(a, b) (fabs((a)-(b)) < eps)
#define lt(a, b) ((a)-(b) < -eps)

struct Point {
  double x, y;
  Point(double x=0, double y=0):x(x), y(y){}
  Point operator+(Point p) {return Point(x+p.x, y+p.y);}
  Point operator-(Point p) {return Point(x-p.x, y-p.y);}
  Point operator*(double a) {return Point(x*a, y*a);}
  Point operator/(double a) {return Point(x/a, y/a);}
  bool operator<(const Point& p) const {return x!=p.x?x<p.x:y<p.y;}
  bool operator==(const Point& p) const {return eq(x, p.x)&&eq(y, p.y);}
};
using Vector = Point;

double dot(Vector a, Vector b) {return a.x*b.x+a.y*b.y;}
double cross(Vector a, Vector b) {return a.x*b.y-a.y*b.x;}
double norm(Vector a) {return dot(a, a);}
double abs(Vector a) {return sqrt(norm(a));}

const int CCW = 1;
const int CW = -1;
const int BCK = 2;
const int FNT = -2;
const int ON = 0;
int ccw(Point p0, Point p1, Point p2) {
  Vector a = p1-p0;
  Vector b = p2-p0;
  if(cross(a, b) > eps) return CCW;
  if(cross(a, b) < -eps) return CW;
  if(dot(a, b) < -eps) return BCK;
  if(norm(a) < norm(b)) return FNT;
  return ON;
}

bool intersect(Point p1, Point p2, Point p3, Point p4) {
  return (ccw(p1, p2, p3)*ccw(p1, p2, p4) <= 0 &&
	  ccw(p3, p4, p1)*ccw(p3, p4, p2) <= 0);
}
double distance(Point a, Point b) {return abs(a-b);}

struct Segment {
  Point s, t;
  Segment(Point s=Point(), Point t=Point()):s(s), t(t){}
};
using Line = Segment;

bool intersect(Segment s1, Segment s2) {
  return intersect(s1.s, s1.t, s2.s, s2.t);
}
bool intersect(Segment s, Point p) {
  return abs(s.s-p)+abs(s.t-p)-abs(s.t-s.s) < eps;
}
double distanceLP(Line l, Point p) {
  return abs(cross(l.t-l.s, p-l.s)/abs(l.t-l.s));
}
double distanceSP(Segment s, Point p) {
  if(dot(s.t-s.s, p-s.s) < 0) return abs(p-s.s);
  if(dot(s.s-s.t, p-s.t) < 0) return abs(p-s.t);
  return distanceLP(s, p);
}
double distance(Segment s1, Segment s2) {
  if(intersect(s1, s2)) return 0;
  return min(min(distanceSP(s1, s2.s), distanceSP(s1, s2.t)),
	     min(distanceSP(s2, s1.s), distanceSP(s2, s1.t)));
}
Point crossPoint(Segment s1, Segment s2) {
  Vector base = s2.t-s2.s;
  double d1 = abs(cross(base, s1.s-s2.s));
  double d2 = abs(cross(base, s1.t-s2.s));
  double t = d1/(d1+d2);
  return s1.s+(s1.t-s1.s)*t;
}

bool merge(Segment& s1, Segment s2) {
  if(abs(cross(s1.t-s1.s, s2.t-s2.s)) > eps) return false;
  if(ccw(s1.s, s2.s, s1.t) == CCW ||
     ccw(s1.s, s2.s, s1.t) == CW) return false;
  if(ccw(s1.s, s1.t, s2.s) == FNT ||
     ccw(s2.s, s2.t, s1.s) == FNT) return false;
  s1 = Segment(min(s1.s, s2.s), max(s1.t, s2.t));
  return true;
}
void mergeSegments(vector<Segment>& segs) {
  for(int i = 0; i < (int)segs.size(); ++i) {
    if(segs[i].t < segs[i].s) swap(segs[i].s, segs[i].t);
  }
  for(int i = 0; i < (int)segs.size(); ++i) {
    for(int j = i+1; j < (int)segs.size(); ++j) {
      if(merge(segs[i], segs[j])) {
	segs[j--] = segs.back();
	segs.pop_back();
      }
    }
  }
}

struct edge {
  int to;
  double cost;
  int id;
  edge(){}
  edge(int to, double cost, int id):to(to), cost(cost), id(id){}
  bool operator<(const edge& e) {return lt(cost, e.cost);}
};
using Graph = vector<vector<edge> >;

vector<int> type;
map<Point, int> mp;
int id = 0;
double sum = 0;

Graph segmentArrangement(vector<Segment>& segs, vector<Point>& ps) {
  for(int i = 0; i < (int)segs.size(); ++i) {
    ps.push_back(segs[i].s);
    ps.push_back(segs[i].t);
    for(int j = i+1; j < (int)segs.size(); ++j) {
      if(intersect(segs[i], segs[j])) ps.push_back(crossPoint(segs[i], segs[j]));
    }
  }
  sort(ps.begin(), ps.end());
  ps.erase(unique(ps.begin(), ps.end()), ps.end());
  //cout<<"AFTER"<<endl;
  //for(int i = 0; i < (int)ps.size(); ++i) cout<<mp[ps[i]]<<" "<<ps[i].x<<" "<<ps[i].y<<endl;
  for(int i = 0; i < (int)ps.size(); ++i) type.push_back(mp[ps[i]]);
  Graph graph(ps.size());
  for(int i = 0; i < (int)segs.size(); ++i) {
    vector<pair<double, int> > ls;
    for(int j = 0; j < (int)ps.size(); ++j) {
      if(intersect(segs[i], ps[j])) {
	ls.emplace_back(norm(segs[i].s-ps[j]), j);
      }
    }
    sort(ls.begin(), ls.end());
    for(int j = 0; j+1 < (int)ls.size(); ++j) {
      int u = ls[j].second, v = ls[j+1].second;
      graph[u].emplace_back(v, distance(ps[u], ps[v]), id);
      graph[v].emplace_back(u, distance(ps[u], ps[v]), id);
      ++id;
      sum += distance(ps[u], ps[v]);
    }
    //sum += distance(segs[i].s, segs[i].t);
  }
  //cout<<sum<<endl;
  return graph;
}

int main() {
  int N, M;
  vector<Segment> segs;
  vector<Point> ps;

  cin >> N >> M;
  for(int i = 0; i < N; ++i) {
    Point s, t;
    cin >> s.x >> s.y >> t.x >> t.y;
    segs.emplace_back(s, t);
  }
  for(int i = 0; i < M+2; ++i) {
    Point p;
    cin >> p.x >> p.y;
    ps.push_back(p);
    if(i == M) mp[p] = 1;
    else if(i == M+1) mp[p] = 2;
    else mp[p] = 3;
  }
  //cout<<"BEFORE"<<endl;
  //for(auto& p : mp) cout << p.second<<" "<<p.first.x<<" "<<p.first.y<<endl;
  mergeSegments(segs);
  Graph graph = segmentArrangement(segs, ps);
  int s = -1, t = -1;
  for(int i = 0; i < (int)graph.size(); ++i) {
    if(type[i] == 1) s = i;
    else if(type[i] == 2) t = i;
  }
  assert(~s && ~t);

  queue<int> que;
  vector<bool> used(graph.size(), false);
  que.push(t);
  used[t] = true;
  //cout<<s<<" "<<t<<endl;
  while(!que.empty()) {
    int v = que.front(); que.pop();
    //cout<<v<<endl;
    if(v == s) {
      cout << -1 << endl;
      return 0;
    }
    if(type[v] == 3) continue;
    for(edge e : graph[v]) {
      if(used[e.to]) continue;
      used[e.to] = true;
      que.push(e.to);
    }
  }
  vector<bool> usedEdge(id, false);
  que.push(s);
  used[s] = true;
  while(!que.empty()) {
    int v = que.front(); que.pop();
    for(edge e : graph[v]) {
      if(usedEdge[e.id]) continue;
      sum -= e.cost;
      usedEdge[e.id] = true;
      if(used[e.to]) continue;
      used[e.to] = true;
      que.push(e.to);
    }
  }
  printf("%.12f\n", sum);

  return 0;
}



Measured memory_bytes: 6004