#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T, class U>
using Pa = pair<T, U>;
template <class T>
using vec = vector<T>;
template <class T>
using vvec = vector<vec<T>>;
using R = long double;
using P = complex<R>;
const R eps = 1e-9, PI = acos(-1);
bool equal(R a, R b) { return abs(b - a) < eps; }
bool equal0(R a) { return equal(a, 0.0); }
bool equal(P a, P b) {
  return equal(a.real(), b.real()) && equal(a.imag(), b.imag());
}
P operator*(const P& p, const R& d) { return P(p.real() * d, p.imag() * d); }
namespace std {
bool operator<(const P& a, const P& b) {
  return abs(a.real() - b.real()) > eps ? a.real() < b.real()
                                        : a.imag() < b.imag();
}
};  // namespace std
istream& operator>>(istream& is, P& p) {
  R a, b;
  is >> a >> b;
  p = P(a, b);
  return is;
}
ostream& operator<<(ostream& os, P& p) {
  os << fixed << setprecision(10) << p.real() << " " << p.imag();
  return os;
}
double dot(P a, P b) { return (conj(a) * b).real(); }
double cross(P a, P b) { return (conj(a) * b).imag(); }
struct L {
  P a, b;
  L(){};
  L(P a, P b) : a(a), b(b) {}
  L(R A, R B, R C) {
    if (equal(A, 0))
      a = P(0, C / B), b = P(1, C / B);
    else if (equal(B, 0))
      b = P(C / A, 0), b = P(C / A, 1);
    else
      a = P(0, C / B), b = P(C / A, 0);
  }
};
struct S : L {
  S() {}
  S(P a, P b) : L(a, b) {}
};
using Polygon = vec<P>;
P crosspoint(L l1, L l2);
P rotate(P p, R theta);
struct C {
  P p;
  R r;
  C(P p, R r) : p(p), r(r) {}
  C(P a, P b, P c) {
    P d1 = rotate(P(b - a), PI / 2), m1 = (a + b) * 0.5;
    L l1(m1, m1 + d1);
    P d2 = rotate(P(c - b), PI / 2), m2 = (b + c) * 0.5;
    L l2(m2, m2 + d2);
    p = crosspoint(l1, l2);
    r = abs(a - p);
  }
};
P rotate(P p, R theta) {
  return P(cos(theta) * p.real() - sin(theta) * p.imag(),
           sin(theta) * p.real() + cos(theta) * p.imag());
}
P rotate(P p1, P p2, R theta) { return p1 + rotate(p2 - p1, theta); }
R get_angle(P a, P b, P c) {
  P v(b - a), w(c - b);
  R alpha = atan2(v.imag(), v.real()), beta = atan2(w.imag(), w.real());
  if (alpha > beta) swap(alpha, beta);
  R theta = beta - alpha;
  return min(theta, 2 * PI - theta);
}
R get_signed_angle(P a, P b, P c) { return arg((c - b) * conj(a - b)); }
P projection(L l, P p) {
  R t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
  return l.a + (l.a - l.b) * t;
}
P projection(S l, P p) {
  R t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
  return l.a + (l.a - l.b) * t;
}
int ccw(P p0, P p1, P p2) {
  p1 -= p0, p2 -= p0;
  if (cross(p1, p2) > eps) return 1;
  if (cross(p1, p2) < -eps) return -1;
  if (dot(p1, p2) < 0) return 2;
  if (norm(p1) < norm(p2)) return -2;
  return 0;
}
bool is_parallel(L l1, L l2) { return equal0(cross(l1.b - l1.a, l2.b - l2.a)); }
bool is_parallel(S l1, L l2) { return equal0(cross(l1.b - l1.a, l2.b - l2.a)); }
bool is_orthogonal(L l1, L l2) { return equal0(dot(l1.b - l1.a, l2.b - l2.a)); }
P reflection(L l, P p) {
  P pj = projection(l, p);
  return pj * 2.0 - p;
}
R dist(L l, P p);
R dist(P a, P b);
bool is_online(L l, P p) { return abs(ccw(l.a, l.b, p)) != 1; }
bool is_onsegment(S s, P p) { return ccw(s.a, s.b, p) == 0; }
bool intersect(S s, S 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 intersect(L l, S s) {
  return cross(l.a - l.b, s.a - l.b) * cross(l.a - l.b, s.b - l.b) <= eps;
}
P crosspoint(L l1, L l2) {
  R a = cross(l1.b - l1.a, l2.b - l2.a);
  R b = cross(l1.b - l1.a, l1.b - l2.a);
  if (equal0(abs(a)) && equal0(abs(b))) return l2.a;
  return l2.a + (l2.b - l2.a) * b / a;
}
P crosspoint(S s1, S s2) { return crosspoint(L(s1), L(s2)); }
R dist(P a, P b) { return abs(a - b); }
R dist(L l, P p) { return abs(p - projection(l, p)); }
R dist(L l1, L l2) { return is_parallel(l1, l2) ? 0 : dist(l1, l2.a); }
R dist(S s, P p) {
  P r = projection(s, p);
  if (is_onsegment(s, r)) return abs(r - p);
  return min(dist(s.a, p), dist(s.b, p));
}
R dist(S s1, S s2) {
  if (intersect(s1, s2)) return 0;
  return min({dist(s1, s2.a), dist(s1, s2.b), dist(s2, s1.a), dist(s2, s1.b)});
}
R area(Polygon& v) {
  int n = v.size();
  R res = 0;
  for (int i = 0; i + 2 < n; i++) {
    res += cross(v[i + 1] - v[0], v[i + 2] - v[0]);
  }
  return res / 2;
}
bool is_convex(Polygon& v) {
  int n = v.size();
  for (int i = 0; i < n; i++) {
    P a = v[i % n], b = v[(i + 1) % n], c = v[(i + 2) % n];
    if (cross(b - a, c - a) < -eps) return false;
  }
  return true;
}
enum { OUT, ON, IN };
int contains(Polygon& v, P p) {
  bool in = false;
  int n = v.size();
  for (int i = 0; i < n; i++) {
    P a = v[i] - p, b = v[(i + 1) % n] - p;
    if (a.imag() > b.imag()) swap(a, b);
    if (a.imag() <= 0 && 0 < b.imag() && cross(a, b) < 0) in = !in;
    if (is_onsegment(S(a, b), P(0, 0))) return ON;
  }
  return in ? IN : OUT;
}
R solve(Polygon& v, L li) {
  vec<Pa<P, int>> ls;
  int n = v.size();
  if (li.b < li.a) swap(li.a, li.b);
  R dx = li.b.real() - li.a.real();
  R dy = li.b.imag() - li.a.imag();
  if (equal0(dx)) {
    li.b += P(0, 2e5);
    li.a -= P(0, 2e5);
  } else {
    R ly = 2e5 * dy / dx;
    li.b += P(2e5, ly);
    li.a -= P(2e5, ly);
  }
  R res = 0;
  for (int i = 0; i < n; i++) {
    S border(v[i], v[(i + 1) % n]);
    if (!intersect(li, border)) continue;
    if (is_parallel(border, li)) {
      ls.push_back({v[i], 0});
      ls.push_back({v[(i + 1) % n], 0});
    } else {
      P p = crosspoint(L(border), li);
      R c = cross(li.b - li.a, v[(i + 1) % n] - v[i]);
      if (c > 0)
        ls.push_back({p, (is_online(li, v[i]) || is_online(li, v[(i + 1) % n]))
                             ? 1
                             : 2});
      else
        ls.push_back({p, (is_online(li, v[i]) || is_online(li, v[(i + 1) % n]))
                             ? -1
                             : -2});
    }
  }
  if (equal(li.a.real(), li.b.real()))
    sort(ls.begin(), ls.end(), [&](Pa<P, int>& p, Pa<P, int>& q) {
      return p.first.imag() < q.first.imag();
    });
  else
    sort(ls.begin(), ls.end(), [&](Pa<P, int>& p, Pa<P, int>& q) {
      return p.first.real() < q.first.real();
    });
  int m = ls.size();
  int val = 0;
  for (int i = 0; i < m - 1; i++) {
    val += ls[i].second;
    if (val) res += dist(ls[i + 1].first, ls[i].first);
  }
  return res;
}
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int N, M;
  cin >> N >> M;
  Polygon v;
  P li;
  for (int i = 0; i < N; i++) {
    P p;
    cin >> p;
    v.push_back(p);
  }
  Polygon v2;
  for (int i = 0; i < N; i++) {
    if (!is_parallel(S(v[(i - 1 + N) % N], v[i]), S(v[i], v[(i + 1) % N])))
      v2.push_back(v[i]);
  }
  N = v2.size();
  for (int i = 0; i < M; i++) {
    P p, q;
    cin >> p >> q;
    L li(p, q);
    R res = solve(v, li);
    cout << fixed << setprecision(10) << res << "\n";
  }
}
