package main
import (
"bufio"
"fmt"
"os"
"sort"
)
type Rect struct {
a, b, c, d int
}
func check(S []Rect) bool {
if len(S) <= 1 {
return true
}
sort.Slice(S, func(i, j int) bool {
if S[i].a != S[j].a {
return S[i].a < S[j].a
}
return S[i].c < S[j].c
})
maxC := S[0].c
splitIdx := -1
for i := 0; i < len(S)-1; i++ {
if S[i].c > maxC {
maxC = S[i].c
}
if S[i+1].a >= maxC {
splitIdx = i + 1
break
}
}
if splitIdx != -1 {
return check(S[:splitIdx]) && check(S[splitIdx:])
}
sort.Slice(S, func(i, j int) bool {
if S[i].b != S[j].b {
return S[i].b < S[j].b
}
return S[i].d < S[j].d
})
maxD := S[0].d
splitIdx = -1
for i := 0; i < len(S)-1; i++ {
if S[i].d > maxD {
maxD = S[i].d
}
if S[i+1].b >= maxD {
splitIdx = i + 1
break
}
}
if splitIdx != -1 {
return check(S[:splitIdx]) && check(S[splitIdx:])
}
return false
}
func main() {
var n int
reader := bufio.NewReader(os.Stdin)
if _, err := fmt.Fscan(reader, &n); err != nil {
return
}
rects := make([]Rect, n)
for i := 0; i < n; i++ {
fmt.Fscan(reader, &rects[i].a, &rects[i].b, &rects[i].c, &rects[i].d)
}
if check(rects) {
fmt.Println("YES")
} else {
fmt.Println("NO")
}
}