#include <bits/stdc++.h>
using namespace std;
template<typename T> void umax(T &a, const T b) {a = max(a, b);}
template<typename T> void umin(T &a, const T b) {a = min(a, b);}
#define double long double
template <class T> int sgn(T x) { return (x > 0) - (x < 0); }
template<class T>
struct Point {
typedef Point P;
T x, y;
explicit Point(T x=0, T y=0) : x(x), y(y) {}
bool operator<(P p) const { return tie(x,y) < tie(p.x,p.y); }
bool operator==(P p) const { return tie(x,y)==tie(p.x,p.y); }
P operator+(P p) const { return P(x+p.x, y+p.y); }
P operator-(P p) const { return P(x-p.x, y-p.y); }
P operator*(T d) const { return P(x*d, y*d); }
P operator/(T d) const { return P(x/d, y/d); }
T dot(P p) const { return x*p.x + y*p.y; }
T cross(P p) const { return x*p.y - y*p.x; }
T cross(P a, P b) const { return (a-*this).cross(b-*this); }
T dist2() const { return x*x + y*y; }
double dist() const { return sqrt((double)dist2()); }
// angle to x=axis in interva l [=pi , pi ]
double angle() const { return atan2(y, x); }
P unit() const { return *this/dist(); } // makes d is t ()=1
P perp() const { return P(-y, x); } // rotates +90 degrees
P normal() const { return perp().unit(); }
// returns point rotated ’a ’ radians ccw around the origin
P rotate(double a) const {
return P(x*cos(a)-y*sin(a),x*sin(a)+y*cos(a)); }
friend ostream& operator<<(ostream& os, P p) {
return os << "(" << p.x << "," << p.y << ")"; }
};
template<class P> bool onSegment(P s, P e, P p) {
return p.cross(s, e) == 0 && (s - p).dot(e - p) <= 0;
}
template<class P> vector<P> segInter(P a, P b, P c, P d) {
auto oa = c.cross(d, a), ob = c.cross(d, b),
oc = a.cross(b, c), od = a.cross(b, d);
// Checks if intersection is single non-endpoint point.
if (sgn(oa) * sgn(ob) < 0 && sgn(oc) * sgn(od) < 0)
return {(a * ob - b * oa) / (ob - oa)};
set<P> s;
if (onSegment(c, d, a)) s.insert(a);
if (onSegment(c, d, b)) s.insert(b);
if (onSegment(a, b, c)) s.insert(c);
if (onSegment(a, b, d)) s.insert(d);
return {s.begin(), s.end()};
}
template<class P>
int segCountRay(vector<P> &p, P a, P e, bool strict = true) {
int cnt = 0, n = p.size();
for (int i = 0; i < n; ++i) {
P q = p[(i + 1) % n];
if (onSegment(p[i], q, a)) continue;
cnt += ((a.cross(e, p[i]) < 0 ? 1 : 0) - (a.cross(e, q) < 0 ? 1 : 0)) * a.cross(p[i], q) > 0;
}
return cnt;
}
template<class P>
pair<int, P> lineInter(P s1, P e1, P s2, P e2) {
auto d = (e1 - s1).cross(e2 - s2);
if (d == 0) return {-(s1.cross(e1, s2) == 0), P(0, 0)};
auto p = s2.cross(e1, e2), q = s2.cross(e2, s1);
return {1, (s1*p+e1*q)/d};
}
int main() {
cin.tie(0)->sync_with_stdio(false);
int N, M; cin >> N >> M;
vector<Point<double>> pts(N); for (auto &pt : pts) {
cin >> pt.x >> pt.y;
}
while (M--) {
Point<double> p, q; cin >> p.x >> p.y >> q.x >> q.y;
Point<double> v = q-p;
double ans = 0;
vector<pair<Point<double>, int>> pos;
for (int i = 0; i < N; ++i) {
int s1 = sgn(v.cross(pts[i]-p));
int s2 = sgn(v.cross(pts[(i+1)%N]-p));
if (s1 == s2) continue;
auto inter = lineInter(p, q, pts[i], pts[(i+1)%N]);
assert(inter.first == 1);
if (s1 > s2) pos.push_back({inter.second, s1 & s2 ? 2 : 1});
else pos.push_back({inter.second, s1 & s2 ? -2 : -1});
}
sort(pos.begin(), pos.end());
int sum = 0;
for (int i = 0; i+1 < pos.size(); ++i) {
sum += pos[i].second;
if (sum) ans += (pos[i+1].first-pos[i].first).dist();
}
cout << fixed << setprecision(8) << ans << '\n';
}
return 0;
}