#include <bits/stdc++.h>
using namespace std;

typedef complex<double> P;

const double eps = 1e-8;

bool equals(double a, double b) {
  return abs(a - b) < eps;
}

namespace std {
  bool operator < (const P &a, const P &b) {
    if(!equals(a.real(), b.real())) return a.real() < b.real();
    if(!equals(a.imag(), b.imag())) return a.imag() < b.imag();
    return false;
  }
}

double cross(P a, P b) {
  return a.real()*b.imag() - a.imag()*b.real();
}

double dot(P a, P b) {
  return a.real()*b.real() + a.imag()*b.imag();
}

bool isParallel(P a, P b) {
  return equals(cross(a, b), 0.0);
}

int ccw(P p, P a, P b) {
  a -= p;
  b -= p;
  if(cross(a, b) > eps) return 1;
  if(cross(a, b) < -eps) return -1;
  if(dot(a, b) < -eps) return 2;
  if(norm(b) - norm(a) > eps) return -2;
  return 0;
}

bool isIntersect(P a1, P a2, P b1, P b2) {
  return ( ccw(a1, a2, b1) * ccw(a1, a2, b2) <= 0 &&
	   ccw(b1, b2, a1) * ccw(b1, b2, a2) <= 0 );
}

P getCrossP(P a1, P a2, P b1, P b2) {
  P a = a2 - a1;
  P b = b2 - b1;
  return a1 + a * cross(b, b1 - a1) / cross(b, a);
}

///////////////////////////////////////////////////////////////////////////

struct Edge {
  int to; double w;
};

typedef vector<vector<Edge> > Graph;

int getId(P p, map<P, int> &m) {
  if(!m.count(p)) {
    int tmp = m.size();
    m[p] = tmp;
  }
  return m[p];
}

int getId(P p, map<P, int> &m, map<int, P> &r) {
  r[getId(p, m)] = p;
  return m[p];
}

void dfs(int v, const Graph &g, vector<int> &vis) {
  vis[v] = 1;
  for(int i = 0; i < g[v].size(); ++i) {
    int nv = g[v][i].to;
    if(vis[nv]) continue;
    dfs(nv, g, vis);
  }
}

int main() {
  int N, M;
  cin >> N >> M;
  vector<P> X(N), Y(N), Z(M);
  P src, dst;
  map<P, int> id;
  map<int, P> rid;

  for(int i = 0; i < N; ++i) {
    cin >> X[i].real() >> X[i].imag() >> Y[i].real() >> Y[i].imag();
    getId(X[i], id, rid);
    getId(Y[i], id, rid);
  }
  for(int i = 0; i < M; ++i) {
    cin >> Z[i].real() >> Z[i].imag();
    getId(Z[i], id, rid);
  }
  cin >> src.real() >> src.imag();
  getId(src, id, rid);
  cin >> dst.real() >> dst.imag();
  getId(dst, id, rid);

  for(int i = 0; i < N; ++i) {
    for(int j = i+1; j < N; ++j) {
      if(isParallel(X[i] - Y[i], X[j] - Y[j])) {
	//
      } else if(isIntersect(X[i], Y[i], X[j], Y[j])) {
	P p = getCrossP(X[i], Y[i], X[j], Y[j]);
	getId(p, id, rid);
      }
    }
  }

  int V = id.size();
  Graph G(V);

  for(int i = 0; i < N; ++i) {
    set<P> s;
    vector<pair<double, P> > v;
    s.insert(X[i]);
    s.insert(Y[i]);
    v.push_back(make_pair(0.0, X[i]));
    v.push_back(make_pair(norm(Y[i] - X[i]), Y[i]));
    for(int j = 0; j < N; ++j) {
      if(isParallel(X[i] - Y[i], X[j] - Y[j])) {
	//
      } else if(isIntersect(X[i], Y[i], X[j], Y[j])) {
	P p = getCrossP(X[i], Y[i], X[j], Y[j]);
	if(s.count(p)) continue;
	s.insert(p);
	v.push_back(make_pair(norm(p - X[i]), p));
      }
    }
    for(int j = 0; j < M; ++j) {
      if(ccw(X[i], Y[i], Z[j]) == 0 && !s.count(Z[j])) {
	s.insert(Z[j]);
	v.push_back(make_pair(norm(Z[j] - X[i]), Z[j]));
      }
    }

    if(ccw(X[i], Y[i], src) == 0 && !s.count(src)) {
      s.insert(src);
      v.push_back(make_pair(norm(src - X[i]), src));
    }
    if(ccw(X[i], Y[i], dst) == 0 && !s.count(dst)) {
      s.insert(dst);
      v.push_back(make_pair(norm(dst - X[i]), dst));
    }
    sort(v.begin(), v.end());
    for(int j = 0; j+1 < v.size(); ++j) {
      int a = getId(v[j].second, id);
      int b = getId(v[j+1].second, id);
      double w = abs(v[j].second - v[j+1].second);
      G[a].push_back((Edge){b, w});
      G[b].push_back((Edge){a, w});
    }
  }
  if(1){
    vector<int> vis(V);
    int res = 0;
    for(int i = 0; i < V; ++i) {
      if(!vis[i]) {
	dfs(i, G, vis);
	++res;
      }
    }
    assert(res == 1);
  }

  if(0) {
  cout << V << endl;
  for(int i = 0; i < V; ++i) {
    cout << rid[i] << ":";
    for(int j = 0; j < G[i].size(); ++j) {
      if(j) cout << ",";
      cout << rid[G[i][j].to];
    }
    cout << endl;
  }
  }

  try {
    vector<int> F(V), F2(V);
    for(int i = 0; i < M; ++i) {
      F[getId(Z[i], id)] = 1;
    }
    set<pair<int, int> > vis;
    queue<int> que;
    
    que.push(getId(dst, id));
    int isrc = getId(src, id);
    while(que.size()) {
      int v = que.front();
      que.pop();
      for(int i = 0; i < G[v].size(); ++i) {
	int nv = G[v][i].to;
	if(nv == isrc) throw 0;
	if(vis.count(make_pair(nv, v))) continue;
	vis.insert(make_pair(nv, v));
	vis.insert(make_pair(v, nv));
	if(F[nv]) {
	  F2[nv] = 1;
	  continue;
	}
	que.push(nv);
      }
    }
    double res = 0;
    que.push(isrc);
    while(que.size()) {
      int v = que.front();
      que.pop();
      for(int i = 0; i < G[v].size(); ++i) {
	int nv = G[v][i].to;
	if(vis.count(make_pair(nv, v))) continue;
	vis.insert(make_pair(nv, v));
	vis.insert(make_pair(v, nv));
	res += G[v][i].w;
	if(F2[nv]) continue;
	que.push(nv);
      }
    }
    res = -res;
    for(int i = 0; i < N; ++i) {
      res += abs(X[i] - Y[i]);
    }
    printf("%.10f\n", res);
  } catch(...) {
    printf("-1\n");
  }
  return 0;
}

Measured memory_bytes: 6544