← Home
package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"sort"
	"strconv"
)

type Point struct {
	x, y float64
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	readFloat := func() float64 {
		scanner.Scan()
		f, _ := strconv.ParseFloat(scanner.Text(), 64)
		return f
	}

	readInt := func() int {
		scanner.Scan()
		i, _ := strconv.Atoi(scanner.Text())
		return i
	}

	if !scanner.Scan() {
		return
	}
	n, _ := strconv.Atoi(scanner.Text())
	m := readInt()

	origV := make([]Point, n)
	Vx := make([]int64, n)
	Vy := make([]int64, n)

	for i := 0; i < n; i++ {
		origV[i].x = readFloat()
		origV[i].y = readFloat()
		Vx[i] = int64(math.Round(origV[i].x * 100))
		Vy[i] = int64(math.Round(origV[i].y * 100))
	}

	for i := 0; i < m; i++ {
		origA := Point{readFloat(), readFloat()}
		origB := Point{readFloat(), readFloat()}

		Ax := int64(math.Round(origA.x * 100))
		Ay := int64(math.Round(origA.y * 100))
		Bx := int64(math.Round(origB.x * 100))
		By := int64(math.Round(origB.y * 100))

		a := Ay - By
		b := Bx - Ax
		c := Ax*By - Bx*Ay

		E := make([]int64, n)
		for j := 0; j < n; j++ {
			E[j] = a*Vx[j] + b*Vy[j] + c
		}

		L := math.Hypot(origB.x-origA.x, origB.y-origA.y)
		ux := (origB.x - origA.x) / L
		uy := (origB.y - origA.y) / L

		var pts []float64

		for j := 0; j < n; j++ {
			if E[j] == 0 {
				p := (origV[j].x-origA.x)*ux + (origV[j].y-origA.y)*uy
				pts = append(pts, p)
			}
			j1 := (j + 1) % n
			if (E[j] > 0 && E[j1] < 0) || (E[j] < 0 && E[j1] > 0) {
				t := float64(E[j]) / float64(E[j]-E[j1])
				Qx := origV[j].x + t*(origV[j1].x-origV[j].x)
				Qy := origV[j].y + t*(origV[j1].y-origV[j].y)
				p := (Qx-origA.x)*ux + (Qy-origA.y)*uy
				pts = append(pts, p)
			}
		}

		sort.Float64s(pts)

		totalLength := 0.0

		for j := 0; j < len(pts)-1; j++ {
			p1 := pts[j]
			p2 := pts[j+1]
			if p2-p1 < 1e-11 {
				continue
			}
			mp := (p1 + p2) / 2.0

			onBoundary := false
			for k := 0; k < n; k++ {
				k1 := (k + 1) % n
				if E[k] == 0 && E[k1] == 0 {
					pk := (origV[k].x-origA.x)*ux + (origV[k].y-origA.y)*uy
					pk1 := (origV[k1].x-origA.x)*ux + (origV[k1].y-origA.y)*uy
					minp := math.Min(pk, pk1)
					maxp := math.Max(pk, pk1)
					if mp > minp+1e-7 && mp < maxp-1e-7 {
						onBoundary = true
						break
					}
				}
			}

			if onBoundary {
				totalLength += (p2 - p1)
			} else {
				Mx := origA.x + mp*ux
				My := origA.y + mp*uy

				inside := false
				for k := 0; k < n; k++ {
					k1 := (k + 1) % n
					xi, yi := origV[k].x, origV[k].y
					xj, yj := origV[k1].x, origV[k1].y

					if (yi > My) != (yj > My) {
						intersect := xi + (My-yi)*(xj-xi)/(yj-yi)
						if Mx < intersect {
							inside = !inside
						}
					}
				}

				if inside {
					totalLength += (p2 - p1)
				}
			}
		}

		fmt.Printf("%.10f\n", totalLength)
	}
}