Problem: <image>


As shown in the figure above, cut a convex polygon g by a line p1p2 and print the area of the cut polygon which is on the left-hand side of the line.

g is represented by a sequence of points p1, p2,..., pn where line segments connecting pi and pi+1 (1 ≤ i ≤ n−1) are sides of the convex polygon. The line segment connecting pn and p1 is also a side of the polygon.

Constraints

* 3 ≤ n ≤ 100
* 1 ≤ q ≤ 100
* -10000 ≤ xi, yi ≤ 10000
* -10000 ≤ p1x,p1y,p2x,p2y ≤ 10000
* No point in g will occur more than once.
* p1 ≠ p2

Input

The input is given in the following format:


g (the sequence of the points of the polygon)
q (the number of queries = the number of target lines)
1st query
2nd query
:
qth query


g is given as a sequence of points p1,..., pn in the following format:


n
x1 y1
x2 y2
:
xn yn


The first integer n is the number of points. The coordinate of the i-th point pi is given by two integers xi and yi. The coordinates of points are given in the order of counter-clockwise visit of them. Note that all interior angles of given convex polygons are less than or equal to 180.

For each query, a line represented by two points p1 and p2 is given. The coordinates of the points are given by four integers p1x, p1y, p2x and p2y.

Output

For each query, print the area of the cut polygon. The output values should be in a decimal fraction with an error less than 0.00001.

Example

Input

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


Output

2.00000000
4.00000000

Solution (in CPP):

Solution:
#include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <map>
#include <set>
#include <cmath>

#define REP(i,k,n) for(int i=k;i<n;i++)
#define rep(i,n) for(int i=0;i<n;i++)
#define INF 1<<30
#define pb push_back
#define mp make_pair
#define EPS 1e-8
#define equals(a,b) fabs((a) - (b)) < EPS

using namespace std;
typedef long long ll;
typedef pair<int,int> P;

struct Point {
	double x, y;

	Point(double x=0, double y=0) : x(x), y(y) {}

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

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

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

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

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

	bool operator==(const Point &o) const { return fabs(x-o.x) < EPS && fabs(y-o.y) < EPS; }
};

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

double dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }
double cross(Point a, Point b) { return a.x * b.y - a.y * b.x; }
double atan(Point p) { return atan2(p.y, p.x); }
double norm(Point p) { return p.x * p.x + p.y * p.y; }
double abs(Point p) { return sqrt(norm(p)); }
double distancePP(Point p, Point o) { return sqrt(norm(o - p)); }

int ccw(Point a, Point b, Point c) {
	b = b-a;
	c = c-a;

	if(cross(b, c) > 0.0) return +1;	//conter clockwise
	if(cross(b, c) < 0.0) return -1;	//clockwise
	if(dot(b, c) < 0.0) return +2;	//a on Seg(b,c)
	if(norm(b) < norm(c)) return -2;	//b on Seg(a,c)
	return 0;	//c on Seg(a,b)
}

double polygonArea(const vector<Point>& p) {
	int n = p.size();
	double ret = 0.0;
	for(int i = 0; i < n; ++i) {
		ret += cross(p[i], p[(i+1)%n]);
	}

	return abs(ret) / 2.0;
}

vector<Point> convex_hull(vector<Point> ps) {   
	int n = ps.size();
	sort(ps.begin(),ps.end());

	int k = 0;
	vector<Point> convex(n*2);

	rep(i, n) {
		while (k > 1 && ccw(convex[k-2], convex[k-1], ps[i]) == -1 ) {
			k--;
		}
		convex[ k++ ] = ps[i];
	}

	for(int i = n - 2, t = k; i >= 0; i--) {
		while (k > t && ccw(convex[k-2], convex[k-1], ps[i]) == -1 ) {
			k--;
		}
		convex[ k++ ] = ps[i];
	}

	convex.resize(k-1);
	return convex;
}

double convex_diameter(const vector<Point>& ps) {
	vector<Point> qs = convex_hull(ps);
	int n = qs.size();

	if(n == 2) return distancePP(qs[0], qs[1]);

	int i = 0, j = 0;
	rep(k, n) {
		if(!(qs[i] < qs[k])) i = k;
		if(qs[j] < qs[k]) j = k;
	}

	double ret = 0;
	int si = i, sj = j;
	while(i != sj || j != si) {
		ret = max(ret, distancePP(qs[i], qs[j]));
		if( cross(qs[(i+1)%n] - qs[i], qs[(j+1)%n] - qs[j]) < 0) {
			i = (i + 1) % n;
		} else {
			j = (j + 1) % n;
		}
	}
	return ret;
}

struct Line {
	Point a, b;

	Line() : a(Point(0, 0)), b(Point(0, 0)) {}

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

ostream& operator << (ostream& os, const Line& l) {
	os << "(" << l.a.x << ", " << l.a.y << ")-(" << l.b.x << "," << l.b.y << ")";
	return os;
}

struct Seg {
	Point a,b;

	Seg() : a(Point(0, 0)), b(Point(0, 0)) {}

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

ostream& operator << (ostream& os, const Seg& s) {
	os << "(" << s.a.x << ", " << s.a.y << ")-(" << s.b.x << "," << s.b.y << ")";
	return os;
}

bool isOrthogonal(Line l1, Line l2) { return equals(dot((l1.b - l1.a), (l2.b - l2.a)), 0.0); }

bool isParallel(Line l1, Line l2) { return equals(cross((l1.b - l1.a), (l2.b - l2.a)), 0.0); }

bool sameLine(Line l1, Line l2) { return abs(cross(l1.b - l1.a, l2.b - l1.a)) < EPS; }

bool isIntersectLL(Line l1, Line l2) { return !isParallel(l1, l2) || sameLine(l1, l2); }

bool isIntersectLS(Line l, Seg s) {
	return cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < 0;
}

bool isIntersectSS(Seg s1, Seg s2) { 
	return ccw(s1.a, s1.b, s2.a) * ccw(s1.a, s1.b, s2.b) <= 0 
		&& ccw(s2.a, s2.b, s1.a) * ccw(s2.a, s2.b, s1.b) <= 0;
}

double distanceLP(Line l, Point p) {
	return abs(cross(l.b - l.a, p - l.a)) / abs(l.b - l.a);
}

double distanceLS(Line l, Seg s) {
	if (isIntersectLS(l, s)) return 0.0;
	return min(distanceLP(l, s.a), distanceLP(l, s.b));
}

double distanceSP(Seg s, Point p) {
	if (dot(s.b - s.a, p - s.a) < 0.0) return abs(p - s.a);
	if (dot(s.a - s.b, p - s.b) < 0.0) return abs(p - s.b);
	return distanceLP(Line(s.a, s.b) , p);
}

double distanceSS(Seg s1, Seg s2) {
	if (isIntersectSS(s1, s2)) return 0.0;
	return min( min(distanceSP(s1, s2.a), distanceSP(s1, s2.b)), min(distanceSP(s2, s1.a), distanceSP(s2, s1.b)) );
}

// if isIntersectLL(l1, l2)
Point crossPointLL(Line l1, Line l2) {
	Point base = l2.b - l2.a;
	double d = abs(cross(base, l1.a - l2.a));
	double d2 = abs(cross(base, l1.b - l2.a));
	double t = d / (d + d2);
	return l1.a + (l1.b - l1.a) * t;
}

// if isIntersectLS(l, s)
Point crossPointLS(Line l, Seg s) { return crossPointLL(l, Line(s.a, s.b)); }

// if isIntersectSS(s1, s2)
Point crossPointSS(Seg s1, Seg s2) { return crossPointLL(Line(s1.a, s1.b), Line(s2.a, s2.b)); }

Point project(Line l, Point p) {
	Point base = l.b - l.a;
	double t = dot(base, p-l.a) / dot(base, base);
	return l.a + base * t;
}

Point reflect(Line l, Point p) {
	return p + (project(l, p) - p) * 2.0;
}

vector<Point> convex_cut(vector<Point>& p, Line& l) {
	int n = p.size();
	vector<Point> ret;
	rep(i, n) {
		Point a = p[i], b = p[(i+1)%n];
		if(ccw(l.a, l.b, a) != -1) ret.push_back(a);
		if(ccw(l.a, l.b, a) * ccw(l.a, l.b, b) == -1) {
			ret.push_back(crossPointLL(Line(a, b), l));
		}
	}
	return ret;
}


int main() {
	int n;
	cin >> n;

	vector<Point> v(n);
	rep(i, n) cin >> v[i].x >> v[i].y;

	int q;
	cin >> q;

	Line l;
	rep(i, q) {
		cin >> l.a.x >> l.a.y >> l.b.x >> l.b.y;

		vector<Point> ret = convex_cut(v, l);
		cout << fixed;
		cout.precision(20);
		cout << polygonArea(ret) << endl;
	}

	return 0;
}