#include<bits/stdc++.h>

using namespace std;

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

inline bool eq(double a, double b)
{
  return abs(b - a) < EPS;
}

struct Point
{
  double x, y;

  Point() {};

  Point(double x, double y) : x(x), y(y) {};

  Point operator+(const Point &b) const { return Point(x + b.x, y + b.y); }

  Point operator-(const Point &b) const { return Point(x - b.x, y - b.y); }

  Point operator*(const double b) const { return Point(x * b, y * b); }

  Point operator*(const Point &b) const { return Point(x * b.x - y * b.y, x * b.y + y * b.x); }

  Point operator/(const double b) const { return Point(x / b, y / b); }

  bool operator<(const Point &b) const { return x != b.x ? x < b.x : y < b.y; }

  bool operator==(const Point &b) const { return eq(x, b.x) && eq(y, b.y); }

  double norm() { return x * x + y * y; }

  double arg() { return atan2(x, y); }

  double abs() { return sqrt(norm()); }

  Point rotate(double theta) { return Point(cos(theta) * x - sin(theta) * y, sin(theta) * x + cos(theta) * y); }

  Point rotate90() { return Point(-y, x); }

  friend ostream &operator<<(ostream &os, Point &p) { return os << "(" << p.x << "," << p.y << ")"; }

  friend istream &operator>>(istream &is, Point &a) { return is >> a.x >> a.y; }
};


double cross(const Point &a, const Point &b)
{
  return a.x * b.y - a.y * b.x;
}

double dot(const Point &a, const Point &b)
{
  return a.x * b.x + a.y * b.y;
}

int ccw(const Point &a, Point b, Point c)
{
  b = b - a, c = c - a;
  if(cross(b, c) > EPS) return +1;
  if(cross(b, c) < -EPS) return -1;
  if(dot(b, c) < 0) return +2;
  if(b.norm() < c.norm()) return -2;
  return 0;
}

struct Segment
{
  Point a, b;

  Segment() {};

  Segment(Point a, Point b) : a(a), b(b) {};

  friend ostream &operator<<(ostream &os, Segment &p) { return os << "(" << p.a.x << "," << p.a.y << ") to (" << p.b.x << "," << p.b.y << ")"; }

  friend istream &operator>>(istream &is, Segment &a) { return is >> a.a.x >> a.a.y >> a.b.x >> a.b.y; }
};

bool Intersect(const Segment &s, const Point &p)
{
  return ccw(s.a, s.b, p) == 0;
}

bool Intersect(const Segment &s, const Segment &t)
{
  return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 &&
         ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

Point Crosspoint(const Segment &l, const Segment &m)
{
  double A = cross(l.b - l.a, m.b - m.a);
  double B = cross(l.b - l.a, l.b - m.a);
  if(abs(A) < EPS && abs(B) < EPS) return m.a; // same line
  return m.a + (m.b - m.a) * B / A;
}

vector< vector< int > > SegmentArrangement(vector< Segment > &segs, vector< Point > &ps)
{
  vector< vector< int > > g;
  const int N = (int) segs.size();
  for(int i = 0; i < N; i++) {
    ps.emplace_back(segs[i].a);
    ps.emplace_back(segs[i].b);
    for(int j = i + 1; j < N; j++) {
      const Point p1 = segs[i].b - segs[i].a;
      const Point p2 = segs[j].b - segs[j].a;
      if(cross(p1, p2) == 0) continue;
      if(Intersect(segs[i], segs[j])) {
        ps.emplace_back(Crosspoint(segs[i], segs[j]));
      }
    }
  }
  sort(begin(ps), end(ps));
  ps.erase(unique(begin(ps), end(ps)), end(ps));

  const int M = (int) ps.size();
  g.resize(M);
  for(int i = 0; i < N; i++) {
    vector< int > vec;
    for(int j = 0; j < M; j++) {
      if(Intersect(segs[i], ps[j])) {
        vec.emplace_back(j);
      }
    }
    for(int j = 1; j < vec.size(); j++) {
      g[vec[j - 1]].push_back(vec[j]);
      g[vec[j]].push_back(vec[j - 1]);
    }
  }
  return (g);
}

int main()
{
  cin.tie(0);
  ios::sync_with_stdio(false);

  int N, M;
  cin >> N >> M;
  vector< Segment > segs(N);
  for(auto &s : segs) cin >> s;
  vector< Point > stop(M);
  for(auto &p : stop) cin >> p;
  Point s, t;
  cin >> s >> t;
  vector< Point > ps(stop);
  ps.emplace_back(s);
  ps.emplace_back(t);
  auto g = SegmentArrangement(segs, ps);

  queue< int > que;
  vector< bool > v(g.size(), false), u(g.size(), false), isstop(g.size(), false);
  for(auto &p : stop) {
    isstop[lower_bound(begin(ps), end(ps), p) - begin(ps)] = true;
  }
  int S = lower_bound(begin(ps), end(ps), s) - begin(ps);
  int T = lower_bound(begin(ps), end(ps), t) - begin(ps);
  que.emplace(T);
  v[T] = true;

  while(!que.empty()) {
    int p = que.front();
    que.pop();
    if(p == S) {
      cout << -1 << endl;
      return (0);
    }
    for(auto &to : g[p]) {
      if(v[to] || isstop[to]) continue;
      v[to] = true;
      que.emplace(to);
    }
  }

  que.emplace(S);
  u[S] = true;
  double ret = 0.0;

  while(!que.empty()) {
    int p = que.front();
    que.pop();
    for(auto &to : g[p]) {
      if(v[to]) continue;
      ret -= (ps[to] - ps[p]).abs();
      if(u[to]) continue;
      que.emplace(to);
      u[to] = true;
    }
  }
  ret *= 0.5;
  for(auto &seg : segs) ret += (seg.a - seg.b).abs();
  cout << fixed << setprecision(12) << ret << endl;
}

Measured memory_bytes: 4036