← Home
#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;
}