← Home
package main

import (
	"bufio"
	"fmt"
	"math/big"
	"os"
)

type Point struct {
	x, y int64
}

type RPoint struct {
	xNum, yNum, den *big.Int
}

func bi(v int64) *big.Int {
	return big.NewInt(v)
}

func scaled(v int64, den *big.Int) *big.Int {
	return new(big.Int).Mul(bi(v), den)
}

func orient(a, b, c Point) int {
	v := (b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x)
	if v < 0 {
		return -1
	}
	if v > 0 {
		return 1
	}
	return 0
}

func onSeg(a, b, c Point) bool {
	if orient(a, b, c) != 0 {
		return false
	}
	if a.x > b.x {
		a.x, b.x = b.x, a.x
	}
	if a.y > b.y {
		a.y, b.y = b.y, a.y
	}
	return a.x <= c.x && c.x <= b.x && a.y <= c.y && c.y <= b.y
}

func segIntersect(a, b, c, d Point) bool {
	o1 := orient(a, b, c)
	o2 := orient(a, b, d)
	o3 := orient(c, d, a)
	o4 := orient(c, d, b)

	if o1 == 0 && onSeg(a, b, c) {
		return true
	}
	if o2 == 0 && onSeg(a, b, d) {
		return true
	}
	if o3 == 0 && onSeg(c, d, a) {
		return true
	}
	if o4 == 0 && onSeg(c, d, b) {
		return true
	}
	return o1*o2 < 0 && o3*o4 < 0
}

func between(a, b, x *big.Int) bool {
	if a.Cmp(b) <= 0 {
		return a.Cmp(x) <= 0 && x.Cmp(b) <= 0
	}
	return b.Cmp(x) <= 0 && x.Cmp(a) <= 0
}

func orientIQR(a Point, q RPoint, c Point) int {
	ax := scaled(a.x, q.den)
	ay := scaled(a.y, q.den)
	vx := new(big.Int).Sub(q.xNum, ax)
	vy := new(big.Int).Sub(q.yNum, ay)
	left := new(big.Int).Mul(vx, bi(c.y-a.y))
	right := new(big.Int).Mul(vy, bi(c.x-a.x))
	return new(big.Int).Sub(left, right).Sign()
}

func orientIIQ(a, b Point, q RPoint) int {
	ax := scaled(a.x, q.den)
	ay := scaled(a.y, q.den)
	vx := new(big.Int).Sub(q.xNum, ax)
	vy := new(big.Int).Sub(q.yNum, ay)
	left := new(big.Int).Mul(bi(b.x-a.x), vy)
	right := new(big.Int).Mul(bi(b.y-a.y), vx)
	return new(big.Int).Sub(left, right).Sign()
}

func onSegIQR(a Point, q RPoint, c Point) bool {
	ax := scaled(a.x, q.den)
	ay := scaled(a.y, q.den)
	cx := scaled(c.x, q.den)
	cy := scaled(c.y, q.den)
	return between(ax, q.xNum, cx) && between(ay, q.yNum, cy)
}

func onSegIIQ(a, b Point, q RPoint) bool {
	ax := scaled(a.x, q.den)
	ay := scaled(a.y, q.den)
	bx := scaled(b.x, q.den)
	by := scaled(b.y, q.den)
	return between(ax, bx, q.xNum) && between(ay, by, q.yNum)
}

func segIntersectIQR(a Point, q RPoint, c, d Point) bool {
	o1 := orientIQR(a, q, c)
	o2 := orientIQR(a, q, d)
	o3 := orientIIQ(c, d, q)
	o4 := orient(c, d, a)

	if o1 == 0 && onSegIQR(a, q, c) {
		return true
	}
	if o2 == 0 && onSegIQR(a, q, d) {
		return true
	}
	if o3 == 0 && onSegIIQ(c, d, q) {
		return true
	}
	if o4 == 0 && onSeg(c, d, a) {
		return true
	}
	return o1*o2 < 0 && o3*o4 < 0
}

func reflectionPoint(v, p, a, b Point) (RPoint, bool) {
	dx := b.x - a.x
	dy := b.y - a.y

	cv := dx*(v.y-a.y) - dy*(v.x-a.x)
	cp := dx*(p.y-a.y) - dy*(p.x-a.x)

	if cv == 0 || cp == 0 || (cv > 0) != (cp > 0) {
		return RPoint{}, false
	}

	dotv := dx*(v.x-a.x) + dy*(v.y-a.y)
	dotp := dx*(p.x-a.x) + dy*(p.y-a.y)
	s := dx*dx + dy*dy

	n := dotv*cp + dotp*cv
	d := s * (cv + cp)

	if d < 0 {
		d = -d
		n = -n
	}

	if n < 0 || n > d {
		return RPoint{}, false
	}

	den := bi(d)
	xNum := new(big.Int).Add(new(big.Int).Mul(bi(a.x), den), new(big.Int).Mul(bi(dx), bi(n)))
	yNum := new(big.Int).Add(new(big.Int).Mul(bi(a.y), den), new(big.Int).Mul(bi(dy), bi(n)))

	return RPoint{xNum: xNum, yNum: yNum, den: den}, true
}

func main() {
	in := bufio.NewReader(os.Stdin)

	var v, p, w1, w2, m1, m2 Point
	fmt.Fscan(in, &v.x, &v.y)
	fmt.Fscan(in, &p.x, &p.y)
	fmt.Fscan(in, &w1.x, &w1.y, &w2.x, &w2.y)
	fmt.Fscan(in, &m1.x, &m1.y, &m2.x, &m2.y)

	if !segIntersect(v, p, w1, w2) && !segIntersect(v, p, m1, m2) {
		fmt.Print("YES")
		return
	}

	q, ok := reflectionPoint(v, p, m1, m2)
	if ok && !segIntersectIQR(v, q, w1, w2) && !segIntersectIQR(p, q, w1, w2) {
		fmt.Print("YES")
		return
	}

	fmt.Print("NO")
}