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

using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

constexpr int INF = 1e9;
using ld = long double;
using weight = ld;

struct edge {
    int from, to;
    weight cost;
};

using edges = vector<edge>;
using graph = vector<edges>;

void add_edge(graph& g, int from, int to, weight cost) {
    g[from].push_back(edge{from, to, cost});
    g[to].push_back(edge{to, from, cost});
}

using ld = long double;

constexpr ld eps = 1e-12;
constexpr ld pi = std::acos(-1.0);


namespace geometry2d {


using point = std::complex<long double>;
using polygon = std::vector<point>;


bool eq(long double a, long double b) {
    return (std::abs(a-b) < eps);
}

long double dot(point a, point b) {
    return std::real(std::conj(a) * b);
}

long double cross(point a, point b) {
    return std::imag(std::conj(a) * b);
}


class segment {
public:
    segment()
        : a(point(0, 0)),
          b(point(0, 0))
    {}
    segment(point a_, point b_)
        : a(a_), b(b_)
    {}

    point a, b;
};

class line {
public:
    line()
        : a(point(0, 0)), b(point(0, 0))
    {}
    line(point a_, point b_)
        : a(a_), b(b_)
    {}
    line(segment s)
        : a(s.a), b(s.b)
    {}

    point a, b;
};


int ccw(point a, point b, point c) {
    b -= a; c -= a;
    if(cross(b, c) > eps)           return 1;  // a -> b -> c : counterclockwise
    if(cross(b, c) < -eps)          return -1; // a -> b -> c : clockwise
    if(dot(b, c) < 0)               return 2;  // c -> a -> b : line
    if(std::norm(b) < std::norm(c)) return -2; // a -> b -> c : line
    return 0;                                  // a -> c -> b : line
}


bool isis_ll(line l, line m) {
    return !eq(cross(l.b - l.a, m.b - m.a), 0);
}

bool isis_ls(line l, segment s) {
    return (cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < eps);
}

bool isis_lp(line l, point p) {
    return (std::abs(cross(l.b - p, l.a - p)) < eps);
}

bool isis_sp(segment s, point p) {
    return (std::abs(s.a - p) + std::abs(s.b - p) - std::abs(s.b - s.a) < eps);
}

bool isis_ss(segment s, 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 proj(line l, point p) {
    long double t = dot(p - l.a, l.a - l.b) / std::norm(l.a - l.b);
    return l.a + t * (l.a - l.b);
}

point is_ll(line s, line t) {
    point sv = s.b - s.a, tv = t.b - t.a;
    assert(cross(sv, tv) != 0);
    return s.a + sv * cross(tv, t.a - s.a) / cross(tv, sv);
}

point is_ss(segment s1, segment s2) {
    assert(isis_ss(s1, s2));
    point sv = s1.b - s1.a, tv = s2.b - s2.a;
    if(cross(sv, tv) == 0) {
        if(std::abs(s1.a - s2.a) < eps || std::abs(s1.a - s2.b) < eps) {
            return s1.a;
        } else {
            return s1.b;
        }
    } else {
        return is_ll(line(s1), line(s2));
    }
}

long double dist_lp(line l, point p) {
    return std::abs(p - proj(l, p));
}

long double dist_ll(line l, line m) {
    return isis_ll(l, m) ? 0 : dist_lp(l, m.a);
}

long double dist_ls(line l, segment s) {
    return isis_ls(l, s) ? 0 : std::min(dist_lp(l, s.a), dist_lp(l, s.b));
}

long double dist_sp(segment s, point p) {
    point r = proj(line(s), p);
    return isis_sp(s, r) ? std::abs(r - p) : std::min(std::abs(s.a - p), std::abs(s.b - p));
}

long double dist_ss(segment s, segment t) {
    if(isis_ss(s, t)) return 0;
    long double d1 = std::min(dist_sp(s, t.a), dist_sp(s, t.b));
    long double d2 = std::min(dist_sp(t, s.a), dist_sp(t, s.b));
    return std::min(d1, d2);
}

std::vector<point> unique(std::vector<point> ps) {
    std::sort(std::begin(ps), std::end(ps), [](auto const& a, auto const& b) -> bool {
        return (std::real(a - b) * 1.347589 + std::imag(a - b)) > 0;
    });
    std::vector<point> res;
    for(auto& p : ps) {
        if(res.empty() || abs(res.back() - p) > eps) {
            res.push_back(p);
        }
    }
    return res;
}

graph segment_arrangement(std::vector<segment> const& s, std::vector<point> const& p) {
    int m = s.size();
    int n = p.size();
    graph g(n);
    for(int i = 0; i < m; ++i) {
        std::vector<pair<ld, int>> v;
        for(int j = 0; j < n; ++j) {
            if(isis_sp(s[i], p[j])) {
                v.emplace_back(std::abs(s[i].a - p[j]), j);
            }
        }
        std::sort(std::begin(v), std::end(v));
        for(int j = 0; j < (int)v.size() - 1; ++j) {
            int src = v[j].second, dest = v[j + 1].second;
            add_edge(g, src, dest, std::abs(p[src] - p[dest]));
        }
    }
    return g;
}

} // namespace geometry2d

using namespace geometry2d;


int main() {
    int N, M;
    cin >> N >> M;
    vector<segment> s(N);
    ld res = 0;
    for(int i = 0; i < N; ++i) {
        ld x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;
        s[i].a = point(x1, y1);
        s[i].b = point(x2, y2);
        res += abs(s[i].a - s[i].b);
    }

    vector<point> sp;
    vector<point> p;
    for(int i = 0; i < M; ++i) {
        ld x, y;
        cin >> x >> y;
        sp.emplace_back(x, y);
        p.emplace_back(x, y);
    }
    for(int i = 0; i < N; ++i) {
        p.push_back(s[i].a);
        p.push_back(s[i].b);
        for(int j = i + 1; j < N; ++j) {
            if(isis_ss(s[i], s[j])) {
                p.push_back(is_ss(s[i], s[j]));
            }
        }
    }
    ld sx, sy, rx, ry;
    cin >> sx >> sy >> rx >> ry;
    p.emplace_back(sx, sy);
    p.emplace_back(rx, ry);
    p = unique(p);
    vector<bool> stop(p.size());
    int source, dest;
    for(int i = 0; i < (int)p.size(); ++i) {
        for(int j = 0; j < (int)sp.size(); ++j) {
            if(abs(p[i] - sp[j]) < eps) {
                stop[i] = true;
            }
        }
        if(abs(p[i] - point(sx, sy)) < eps) {
            source = i;
        }
        if(abs(p[i] - point(rx, ry)) < eps) {
            dest = i;
        }
    }
    auto g = segment_arrangement(s, p);
    queue<int> que;
    que.push(dest);
    vector<int> vis(p.size());
    vis[dest] = 1;
    while(!que.empty()) {
        int v = que.front();
        que.pop();
        for(auto& e : g[v]) {
            if(vis[e.to]) {
                continue;
            }
            vis[e.to] = 1;
            if(!stop[e.to]) {
                que.push(e.to);
            }
        }
    }
    if(vis[source]) {
        cout << -1 << endl;
        return 0;
    }

    que.push(source);
    vis[source] = 2;
    set<pii> used;
    while(!que.empty()) {
        int v = que.front();
        que.pop();
        for(auto& e : g[v]) {
            assert(0 <= e.to && e.to < g.size());
            if(used.count(make_pair(v, e.to)) == 0) {
                res -= e.cost;
                used.insert(make_pair(v, e.to));
                used.insert(make_pair(e.to, v));
            }
            if(vis[e.to]) {
                continue;
            }
            vis[e.to] = 2;
            que.push(e.to);
        }
    }
    cout << fixed << setprecision(10) << res << endl;
}


Measured memory_bytes: 7908