Problem: In the International City of Pipe Construction, it is planned to repair the water pipe at a certain point in the water pipe network. The network consists of water pipe segments, stop valves and source point. A water pipe is represented by a segment on a 2D-plane and intersected pair of water pipe segments are connected at the intersection point. A stop valve, which prevents from water flowing into the repairing point while repairing, is represented by a point on some water pipe segment. In the network, just one source point exists and water is supplied to the network from this point.

Of course, while repairing, we have to stop water supply in some areas, but, in order to reduce the risk of riots, the length of water pipes stopping water supply must be minimized. What you have to do is to write a program to minimize the length of water pipes needed to stop water supply when the coordinates of end points of water pipe segments, stop valves, source point and repairing point are given.



Input

A data set has the following format:

> N M
>  xs1 ys1 xd1 yd1
>  ...
>  xsN ysN xdN ydN
>  xv1 yv1
>  ...
>  xvM yvM
>  xb yb
>  xc yc
>

The first line of the input contains two integers, N (1 ≤ N ≤ 300) and M (0 ≤ M ≤ 1,000) that indicate the number of water pipe segments and stop valves. The following N lines describe the end points of water pipe segments. The i-th line contains four integers, xsi, ysi, xdi and ydi that indicate the pair of coordinates of end points of i-th water pipe segment. The following M lines describe the points of stop valves. The i-th line contains two integers, xvi and yvi that indicate the coordinate of end points of i-th stop valve. The following line contains two integers, xb and yb that indicate the coordinate of the source point. The last line contains two integers, xc and yc that indicate the coordinate of the repairing point.

You may assume that any absolute values of coordinate integers are less than 1,000 (inclusive.) You may also assume each of the stop valves, the source point and the repairing point is always on one of water pipe segments and that that each pair among the stop valves, the source point and the repairing point are different. And, there is not more than one intersection between each pair of water pipe segments. Finally, the water pipe network is connected, that is, all the water pipes are received water supply initially.

Output

Print the minimal length of water pipes needed to stop water supply in a line. The absolute or relative error should be less than or 10-6. When you cannot stop water supply to the repairing point even though you close all stop valves, print "`-1`" in a line.

Examples

Input

1 2
0 0 10 0
1 0
9 0
0 0
5 0


Output

9.0


Input

5 3
0 4 2 4
0 2 2 2
0 0 2 0
0 0 0 4
2 0 2 4
0 2
1 0
2 2
1 4
2 1


Output

3.0


Input

2 1
0 0 0 4
0 2 2 2
1 2
0 1
0 3


Output

-1

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,k,n) for(int i = (k); i < (n); i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(a) a.begin(), a.end()
#define MS(m,v) memset(m,v,sizeof(m))
#define D10 fixed<<setprecision(10)
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-10;
template<class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template<class T> T &chmax(T &a, const T &b) { return a = max(a, b); }

/*--------------------template--------------------*/
typedef long double ld;
const ld PI = acos(-1.0);
bool eq(ld a, ld b) { return abs(a - b) < EPS; }
typedef complex<ld> Point;
typedef vector<Point> Polygon;

namespace std
{
	bool operator < (const Point& a, const Point& b)
	{
		return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
	}
}

struct Line
{
	Point a, b;
	Line(Point p, Point q) :a(p), b(q) {};
	Line(ld x1, ld y1, ld x2, ld y2) :a(Point(x1, y1)), b(Point(x2, y2)) {};
};

struct Circle
{
	Point p; ld r;
	Circle(Point a, ld b) :p(a), r(b) {};
};

ld dot(Point a, Point b)
{
	return real(conj(a)*b);
}

ld cross(Point a, Point b)
{
	return imag(conj(a)*b);
}

int ccw(Point a, Point b, Point c)
{
	b -= a; c -= a;
	if (cross(b, c) > EPS) return 1;    //counter cloclwise
	if (cross(b, c) < -EPS) return -1;  //cloclwise
	if (dot(b, c) < 0) return 2;        //c--a--b on line 
	if (norm(b) < norm(c)) return -2;   //a--b--c on line
	return 0;                           //a--c--b on line
}

bool isis_ll(Line l, Line m)
{
	return abs(cross(l.b - l.a, m.b - m.a)) > EPS;
}

bool isis_ls(Line l, Line s)
{
	return cross(l.b - l.a, s.a - l.a)*cross(l.b - l.a, s.b - l.a) < EPS;
}

bool isis_ss(Line s, Line 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);
}

bool isis_lp(Line l, Point p)
{
	return (abs(cross(l.b - p, l.a - p)) < EPS);
}

bool isis_sp(Line s, Point p)
{
	return (abs(s.a - p) + abs(s.b - p) - abs(s.b - s.a)) < EPS;
}

Point projection(Line l, Point p)
{
	Point base = l.b - l.a;
	ld r = dot(p - l.a, base) / norm(base);
	return l.a + base*r;
}

Point mirror(Line l, Point p)
{
	return Point(2, 0)*projection(l, p) - p;
}

ld dist_lp(Line l, Point p)
{
	return abs(p - projection(l, p));
}

ld dist_ll(Line l, Line m)
{
	return isis_ll(l, m) ? 0 : dist_lp(l, m.a);
}

ld dist_ls(Line l, Line s)
{
	if (isis_ls(l, s)) return 0;
	return min(dist_lp(l, s.a), dist_lp(l, s.b));
}

ld dist_sp(Line s, Point p)
{
	Point r = projection(s, p);
	if (isis_sp(s, r)) return abs(r - p);
	return min(abs(s.a - p), abs(s.b - p));
}

ld dist_ss(Line s, Line t)
{
	if (isis_ss(s, t)) return 0;
	return min(min(dist_sp(s, t.a), dist_sp(s, t.b)), min(dist_sp(t, s.a), dist_sp(t, s.b)));
}

Point is_ll(Line s, Line t)
{
	ld a = cross(s.b - s.a, t.b - t.a);
	ld b = cross(s.b - s.a, s.b - t.a);
	return t.a + b / a*(t.b - t.a);
}

vector<Point> is_cc(Circle c1, Circle c2)
{
	vector<Point> res;
	ld d = abs(c1.p - c2.p);
	ld rc = (d*d + pow(c1.r, 2) - pow(c2.r, 2)) / (2 * d);
	ld dfr = pow(c1.r, 2) - rc*rc;
	if (abs(dfr) < EPS) dfr = 0;
	if (dfr < 0.0) return res;
	ld rs = sqrt(dfr);
	Point diff = (c2.p - c1.p) / d;
	res.push_back(c1.p + diff*Point(rc, rs));
	if (dfr != 0.0) res.push_back(c1.p + diff*Point(rc, -rs));
	return res;
}

int isis_cc(Circle c1, Circle c2)
{
	ld d = abs(c1.p - c2.p);
	if (d - c1.r - c2.r < -EPS) return -2; //separate
	if (abs(d - c1.r - c2.r) < EPS) return -1; //circumscribe
	if (c1.r < c2.r) swap(c1, c2);
	if (abs(d - c1.r + c2.r) < EPS) return 1;//inscribe
	if (c1.r - d - c2.r > EPS) return 2;//involve
	else return 0;//intersect
}

bool isis_cl(Circle c, Line l)
{
	ld d = dist_lp(l, c.p);
	return d - c.r < -EPS;
}

vector<Point> is_cl(Circle c, Line l)
{
	vector<Point> res;
	ld d = dist_lp(l, c.p);
	if (d > c.r + EPS) return res;
	ld len = (d > c.r) ? 0 : sqrt(c.r*c.r - d*d);
	Point nor = (l.a - l.b) / abs(l.a - l.b);
	res.push_back(projection(l, c.p) + len*nor);
	if (abs(len) > EPS) res.push_back(projection(l, c.p - len*nor));
	return res;
}

vector<Point> is_cs(Circle c, Line s)
{
	vector<Point> v = is_cl(c, s), res;
	REP(i, v.size())
	{
		if (ccw(s.a, v[i], s.b) == -2) res.push_back(v[i]);
	}
	return res;
}

vector<Line> tangent_cp(Circle c, Point p)
{
	vector<Line> res;
	Point v = c.p - p;
	ld d = abs(v);
	ld l = sqrt(norm(v) - c.r * c.r);
	if (isnan(l)) { return res; }
	Point v1 = v * Point(l / d, c.r / d);
	Point v2 = v * Point(l / d, -c.r / d);
	res.push_back(Line(p, p + v1));
	if (l < EPS) return res;
	res.push_back(Line(p, p + v2));
	return res;
}

vector<Line> tangent_cc(Circle c1, Circle c2)
{
	vector<Line> res;
	if (abs(c1.p - c2.p) - (c1.r + c2.r) > -EPS)
	{
		Point center = (c1.p * c2.r + c2.p * c1.r) / (c1.r + c2.r);
		res = tangent_cp(c1, center);
	}
	if (abs(c1.r - c2.r) > EPS)
	{
		Point out = (-c1.p * c2.r + c2.p * c1.r) / (c1.r - c2.r);
		vector<Line> nres = tangent_cp(c1, out);
		res.insert(res.end(), nres.begin(), nres.end());
	}
	else
	{
		Point v = c2.p - c1.p; v /= abs(v);
		Point q1 = c1.p + v * Point(0, 1) * c1.r;
		Point q2 = c1.p + v * Point(0, -1) * c1.r;
		res.push_back(Line(q1, q1 + v));
		res.push_back(Line(q2, q2 + v));
	}
	return res;
}

typedef ld Weight;
struct Edge
{
	int from, to; Weight cost;
	bool operator < (const Edge& e) const { return cost < e.cost; }
	bool operator > (const Edge& e) const { return cost > e.cost; }
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;
void add_edge(Graph &g, int from, int to, Weight cost)
{
	g[from].push_back(Edge{ from, to, cost });
}
Graph segment_arrangement(const vector<Line> &s, const vector<Point> &p)
{
	int n = p.size(), m = s.size();
	Graph g(n);
	REP(i, m)
	{
		vector<pair<ld, int>> vec;
		REP(j, n) if (isis_sp(s[i], p[j]))
			vec.emplace_back(abs(s[i].a - p[j]), j);
		sort(ALL(vec));
		REP(j, vec.size() - 1)
		{
			int src = vec[j].second, dest = vec[j + 1].second;
			add_edge(g, src, dest, abs(p[src] - p[dest]));
			add_edge(g, dest, src, abs(p[src] - p[dest]));
		}
	}
	return g;
}


int main()
{
	int n, m;
	cin >> n >> m;
	vector<Line> pipe;  vector<Point> valve;
	REP(i, n)
	{
		ld x1, y1, x2, y2;
		cin >> x1 >> y1 >> x2 >> y2;
		pipe.push_back(Line(x1, y1, x2, y2));
	}
	REP(i, m)
	{
		ld x, y;
		cin >> x >> y;
		valve.emplace_back(Point(x, y));
	}
	Point src, repair;
	ld x, y; 
	cin >> x >> y;
	src = Point(x, y);
	cin >> x >> y;
	repair = Point(x, y);
	vector<Point> ps;
	ps.emplace_back(src);
	ps.emplace_back(repair);
	ps.insert(ps.end(),ALL(valve));
	REP(i, n)
	{
		ps.emplace_back(pipe[i].a);
		ps.emplace_back(pipe[i].b);
	}
	REP(i, n)REP(j, i)
	{
		if (isis_ss(pipe[i], pipe[j])) ps.emplace_back(is_ll(pipe[i], pipe[j]));
	}

	Graph g = segment_arrangement(pipe, ps);
	vector<bool> f(m, true);
	queue<int> que; que.push(1);
	set<int> st; st.insert(1);
	while (que.size())
	{
		int t = que.front();
		que.pop();
		REP(i, g[t].size())
		{
			int nx = g[t][i].to;
			if (st.count(nx)) continue;
			st.insert(nx);
			if (nx == 0)
			{
				puts("-1");
				return 0;
			}
			if (nx > 1 && nx < m + 2) f[nx - 2] = false;
			else que.push(nx);
		}
	}
	while (que.size()) que.pop();
	st.clear();
	que.push(0); st.insert(0);
	while (que.size())
	{
		int t = que.front();
		que.pop();
		REP(i, g[t].size())
		{
			int nx = g[t][i].to;
			if (st.count(nx)) continue;
			st.insert(nx);
			if (nx > 1 && nx < m + 2 && f[nx - 2] == false) continue;
			que.push(nx);
		}
	}
	ld ans = 0;
	REP(i, g.size())REP(j, g[i].size())
	{
		if (st.count(g[i][j].from) && st.count(g[i][j].to)) ans += g[i][j].cost;
	}
	ld sum = 0;
	REP(i, g.size())REP(j, g[i].size()) sum += g[i][j].cost;
	cout << D10 << sum/2 - ans/2 << endl;
	return 0;
}