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 <bits/stdc++.h>
#define EPS 1e-10
#define PI 3.141592653589793238
#define equals(a,b) (fabs((a)-(b)) < EPS)
#define rep(i,n) for(int i=0;i<n;++i)
typedef long long ll;
using namespace std;

static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;

// 点
struct Point {
    double x,y;
    Point(){}
    Point(double x, double y) : x(x),y(y){}
    Point operator+(Point p) {return Point(x+p.x, y+p.y);}
    Point operator-(Point p) {return Point(x-p.x, y-p.y);}
    Point operator*(double k){return Point(x*k,y*k);}
    Point operator/(double k){return Point(x/k,y/k);}
    double norm(){return x*x+y*y;}
    double abs(){sqrt(norm());}
    bool operator == (const Point &p) const {return equals(x,p.x)&&equals(y,p.y);}
    bool operator < (const Point &p) const {
        return x!=p.x?x<p.x:y<p.y;
        //grid-point only
        //return !equals(x,p.x)?x<p.x:!equals(y,p.y)?y<p.y:0;
    }

};

typedef Point P;
typedef vector<Point> Polygon;

double norm(P a){return a.x*a.x+a.y*a.y;}
double abs(P a){return sqrt(norm(a));}

// 線分
struct Segment {
    Point p1,p2;
    Segment(){}
    Segment(Point p1, Point p2):p1(p1),p2(p2){}
};

typedef Segment Line;

struct Circle {
    Point c;
    double r;
    Circle(){}
    Circle(Point c, double r):c(c),r(r){}
};

// 法線ベクトル
Point normal(Point p){return Point(-p.y,p.x);}

// 内積
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;}
// 2直線の直行判定
bool is_orthogonal(Point a1, Point a2, Point b1, Point b2) {
    return equals(dot(a1-a2, b1-b2), 0.0);
}
// 2直線の平行判定
bool is_parallel(Point a1, Point a2, Point b1, Point b2) {
    return equals(cross(a1-a2, b1-b2), 0.0);
}
// 点cが直線ab上にあるかないか
bool is_point_on_INF_line(Point a, Point b, Point c) {
    return equals(cross(b-a,c-a), 0.0);
}
// 点cが線分ab上にあるかないか
bool is_point_on_LIMITED_line(Point a, Point b, Point c) {
    return (Point(a-c).abs()+Point(c-b).abs() < Point(a-b).abs() + EPS);
}
// 直線と点の距離
double distance_l_p(Point a, Point b, Point c) {return abs(cross(b-a, c-a)) / (b-a).abs();}

// 点a,bを端点とする線分と点cとの距離
double distance_ls_p(Point a, Point b, Point c) {
    if (dot(b-a, c-a) < EPS) return (c-a).abs();
    if (dot(a-b, c-b) < EPS) return (c-b).abs();
    return abs(cross(b-a, c-a)) / (b-a).abs();
}

// 点が線分のどちら側にあるかを計算
int ccw(Point p0,Point p1,Point p2) {
    P a = p1-p0;
    P b = p2-p0;
    if(cross(a,b) > EPS) return COUNTER_CLOCKWISE;
    if(cross(a,b) < -EPS) return CLOCKWISE;
    if(dot(a,b) < -EPS) return ONLINE_BACK;
    if(a.norm()<b.norm()) return ONLINE_FRONT;
    return ON_SEGMENT;
}

// a1,a2を端点とする線分とb1,b2を端点とする線分の交差判定
bool intersectSS(Point p1, Point p2, Point p3, Point p4) {
    return (ccw(p1,p2,p3)*ccw(p1,p2,p4) <= 0&&ccw(p3,p4,p1)*ccw(p3,p4,p2) <= 0 );
}

// a1,a2を端点とする線分とb1,b2を端点とする線分の交差判定
bool intersectSS(Segment s1, Segment s2) {
    return intersectSS(s1.p1,s1.p2,s2.p1,s2.p2);
}

// 直線と点の距離
double getDistanceLP(Line l, Point p) {
    return abs(cross(l.p2-l.p1,p-l.p1)/abs(l.p2-l.p1));
}

// 線分と点の距離
double getDistanceSP(Segment s,Point p){
    if(dot(s.p2-s.p1,p-s.p1) < 0.0 ) return abs(p-s.p1);
    if(dot(s.p1-s.p2,p-s.p2) < 0.0 ) return abs(p-s.p2);
    return getDistanceLP(s,p);
}

// 線分と線分の距離
double getDistanceSS(Segment s1,Segment s2){
    if(intersectSS(s1,s2)) return 0.0;
    return min(min(getDistanceSP(s1,s2.p1),getDistanceSP(s1,s2.p2)),
    min(getDistanceSP(s2,s1.p1),getDistanceSP(s2,s1.p2)));
}

// a1,a2を端点とする線分とb1,b2を端点とする線分の交点計算
// 前提として交差していることが必要
P getCrossPointSS(P a1, P a2, P b1, P b2) {
    P b = b2-b1;
    double d1 = abs(cross(b, a1-b1));
    double d2 = abs(cross(b, a2-b1));
    double t = d1/(d1+d2);
    return a1+(a2-a1)*t;
}

// a1,a2を通る直線とb1,b2を通る直線の交点計算
// 前提として平行でないことが必要
Point getCrossPointLL(Line l1,Line l2){
    double a=cross(l1.p2-l1.p1,l2.p2-l2.p1);
    double b=cross(l1.p2-l1.p1,l1.p2-l2.p1);
    if(abs(a)<EPS&&abs(b)<EPS) return l2.p1;
    return l2.p1+(l2.p2-l2.p1)*(b/a);
}

// 射影
Point project(Segment s, Point p) {
    Point base = s.p2-s.p1;
    double r = dot(p-s.p1,base)/norm(base);
    return s.p1+base*r;
}

double area(Polygon s){
    double res=0;
    for(int i=0;i<(int)s.size();i++){
        res+=cross(s[i],s[(i+1)%s.size()])/2.0;
    }
    return res;
}

bool isConvex(Polygon p){
    bool f=1;
    int n=p.size();
    for(int i=0;i<n;i++){
        int t=ccw(p[(i+n-1)%n],p[i],p[(i+1)%n]);
        f&=t!=CLOCKWISE;
    }
    return f;
}

// IN:2 ON:1 OUT:0
int contains(Polygon g,Point p){
    int n=g.size();
    bool x=false;
    for(int i=0;i<n;i++){
        Point a=g[i]-p,b=g[(i+1)%n]-p;
        if(fabs(cross(a,b)) < EPS && dot(a,b) < EPS) return 1;
        if(a.y>b.y) swap(a,b);
        if(a.y < EPS && EPS < b.y && cross(a,b) > EPS ) x = !x;
    }
    return (x?2:0);
}

bool sort_x(Point a,Point b){
    return a.x!=b.x?a.x<b.x:a.y<b.y;
}

bool sort_y(Point a,Point b){
    return a.y!=b.y?a.y<b.y:a.x<b.x;
}

Polygon convex_hull(Polygon ps){
    int n=ps.size();
    sort(ps.begin(),ps.end(),sort_y);
    int k=0;
    Polygon qs(n*2);
    for(int i=0;i<n;i++){
        while(k>1&&cross(qs[k-1]-qs[k-2],ps[i]-qs[k-1])<0) k--;
        qs[k++]=ps[i];
    }
    for(int i=n-2,t=k;i>=0;i--){
        while(k>t&&cross(qs[k-1]-qs[k-2],ps[i]-qs[k-1])<0) k--;
        qs[k++]=ps[i];
    }
    qs.resize(k-1);
    return qs;
}

double diameter(Polygon s){
    Polygon p=s;
    int n=p.size();
    if(n==2) return abs(p[0]-p[1]);
    int i=0,j=0;
    for(int k=0;k<n;k++){
        if(p[i]<p[k]) i=k;
        if(!(p[j]<p[k])) j=k;
    }
    double res=0;
    int si=i,sj=j;
    while(i!=sj||j!=si){
        res=max(res,abs(p[i]-p[j]));
        if(cross(p[(i+1)%n]-p[i],p[(j+1)%n]-p[j])<0.0){
        i=(i+1)%n;
        }else{
        j=(j+1)%n;
        }
    }
    return res;
}

Polygon convexCut(Polygon p,Line l){
    Polygon q;
    for(int i=0;i<(int)p.size();i++){
        Point a=p[i],b=p[(i+1)%p.size()];
        if(ccw(l.p1,l.p2,a)!=-1) q.push_back(a);
        if(ccw(l.p1,l.p2,a)*ccw(l.p1,l.p2,b)<0)
        q.push_back(getCrossPointLL(Line(a,b),l));
    }
    return q;
}

int main(int argc, char const *argv[]) {
    int n;cin>>n;
    Polygon pl;
    rep(i,n) {
        double x,y;cin>>x>>y;
        pl.push_back(Point(x,y));
    }
    int q;cin>>q;
    rep(i,q) {
        double x0,y0,x1,y1;cin>>x0>>y0>>x1>>y1;
        Line l(Point(x0,y0), Point(x1,y1));
        cout << fixed << setprecision(10);
        cout << area(convexCut(pl,l)) << endl;
    }
    return 0;
}