← Home
```go
package main

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

func main() {
	in := bufio.NewReader(os.Stdin)
	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	var n int
	fmt.Fscan(in, &n)

	castles := make([]castle, n)
	for i := 0; i < n; i++ {
		fmt.Fscan(in, &castles[i].a, &castles[i].b, &castles[i].c, &castles[i].d)
	}

	if solve(castles) {
		fmt.Fprintln(out, "YES")
	} else {
		fmt.Fprintln(out, "NO")
	}
}

type castle struct {
	a, b, c, d int
}

func solve(cs []castle) bool {
	n := len(cs)
	if n <= 1 {
		return true
	}

	// Try Vertical Cut
	sort.Slice(cs, func(i, j int) bool {
		return cs[i].a < cs[j].a
	})

	suffixMin := make([]int, n)
	suffixMin[n-1] = cs[n-1].a
	for i := n - 2; i >= 0; i-- {
		if cs[i].a < suffixMin[i+1] {
			suffixMin[i] = cs[i].a
		} else {
			suffixMin[i] = suffixMin[i+1]
		}
	}

	maxVal := -1
	for i := 0; i < n-1; i++ {
		if cs[i].c > maxVal {
			maxVal = cs[i].c
		}
		// If the max x-coordinate of the left set is <= min x-coordinate of the right set,
		// a vertical line separates them.
		if maxVal <= suffixMin[i+1] {
			return solve(cs[:i+1]) && solve(cs[i+1:])
		}
	}

	// Try Horizontal Cut
	sort.Slice(cs, func(i, j int) bool {
		return cs[i].b < cs[j].b
	})

	suffixMin[n-1] = cs[n-1].b
	for i := n - 2; i >= 0; i-- {
		if cs[i].b < suffixMin[i+1] {
			suffixMin[i] = cs[i].b
		} else {
			suffixMin[i] = suffixMin[i+1]
		}
	}

	maxVal = -1
	for i := 0; i < n-1; i++ {
		if cs[i].d > maxVal {
			maxVal = cs[i].d
		}
		// If the max y-coordinate of the bottom set is <= min y-coordinate of the top set,
		// a horizontal line separates them.
		if maxVal <= suffixMin[i+1] {
			return solve(cs[:i+1]) && solve(cs[i+1:])
		}
	}

	return false
}
```