#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(a.real() != b.real()) return a.real() < b.real();
    else return a.imag() < b.imag();
  }
}

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;

Graph segmentArrangement(const vector<P> &s1, const vector<P> &s2,
                         vector<P> &ps) {
  int m = s1.size();
  for(int i = 0; i < m; ++i) {
    ps.push_back(s1[i]);
    ps.push_back(s2[i]);
    for(int j = i+1; j < m; ++j) {
      if(equals(cross(s1[i] - s2[i], s1[j] - s2[j]), 0.0)) continue;
      if(!isIntersect(s1[i], s2[i], s1[j], s2[j])) continue;
      ps.push_back(getCrossP(s1[i], s2[i], s1[j], s2[j]));
    }
  }
  sort(ps.begin(), ps.end());
  ps.erase(unique(ps.begin(), ps.end()), ps.end());
  
  int n = ps.size();
  Graph g(n);
  for(int i = 0; i < m; ++i) {
    vector<pair<double, int> > v;
    for(int j = 0; j < n; ++j) {
      if(!ccw(s1[i], s2[i], ps[j])) {
        v.push_back(make_pair(norm(s1[i] - ps[j]), j));
      }
    }
    sort(v.begin(), v.end());
    for(int j = 0; j+1 < v.size(); ++j) {
      int a = v[j].second, b = v[j+1].second;
      double w = abs(ps[a] - ps[b]);
      g[a].push_back((Edge){b, w});
      g[b].push_back((Edge){a, w});
    }
  }
  return g;
}

///////////////////////////////////////////////////////////////////////////
 
int main() {
  int N, M; cin >> N >> M;
  vector<P> X(N), Y(N), Z(M);
  
  P src, dst;
  for(int i = 0; i < N; ++i) {
    cin >> X[i].real() >> X[i].imag() >> Y[i].real() >> Y[i].imag();
  }
  for(int i = 0; i < M; ++i) {
    cin >> Z[i].real() >> Z[i].imag();
  }
  cin >> src.real() >> src.imag();
  cin >> dst.real() >> dst.imag();

  vector<P> ps = Z;
  ps.push_back(src);
  ps.push_back(dst);
  Graph G = segmentArrangement(X, Y, ps);
  int V = G.size();

  map<P, int> id;
  for(int i = 0; i < ps.size(); ++i) {
    id[ps[i]], id[ps[i]] = id.size() - 1;
  }
  
  vector<int> F(V);
  for(int j = 0; j < M; ++j) F[id[Z[j]]] = 1;
  
  try {
    vector<int> F2(V);
    set<pair<int, int> > vis;
    queue<int> que;
    que.push(id[dst]);
    int isrc = id[src];
    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: 5960