```go
package main
import (
"bufio"
"container/heap"
"fmt"
"os"
"sort"
)
type Event struct {
x int
h int
typ int
}
type IntHeap []int
func (h IntHeap) Len() int { return len(h) }
func (h IntHeap) Less(i, j int) bool { return h[i] > h[j] }
func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *IntHeap) Push(x interface{}) {
*h = append(*h, x.(int))
}
func (h *IntHeap) Pop() interface{} {
old := *h
n := len(old)
x := old[n-1]
*h = old[:n-1]
return x
}
func main() {
in := bufio.NewReader(os.Stdin)
out := bufio.NewWriter(os.Stdout)
defer out.Flush()
var n int
fmt.Fscan(in, &n)
events := make([]Event, 0, 2*n)
for i := 0; i < n; i++ {
var h, l, r int
fmt.Fscan(in, &h, &l, &r)
events = append(events, Event{l, h, 1})
events = append(events, Event{r, h, -1})
}
sort.Slice(events, func(i, j int) bool {
return events[i].x < events[j].x
})
h := &IntHeap{}
heap.Init(h)
removed := make(map[int]int)
getMax := func() int {
for h.Len() > 0 {
top := (*h)[0]
if cnt, ok := removed[top]; ok && cnt > 0 {
heap.Pop(h)
removed[top]--
if removed[top] == 0 {
delete(removed, top)
}
} else {
return top
}
}
return 0
}
critical := make([][2]int, 0)
currH := 0
i := 0
for i < len(events) {
x := events[i].x
for i < len(events) && events[i].x == x {
if events[i].typ == 1 {
heap.Push(h, events[i].h)
} else {
removed[events[i].h]++
}
i++
}
newH := getMax()
if newH != currH {
critical = append(critical, [2]int{x, newH})
currH = newH
}
}
fmt.Fprintln(out, 2*len(critical))
if len(critical) > 0 {
fmt.Fprintln(out, critical[0][0], 0)
fmt.Fprintln(out, critical[0][0], critical[0][1])
prevH := critical[0][1]
for j := 1; j < len(critical); j++ {
x, h := critical[j][0], critical[j][1]
fmt.Fprintln(out, x, prevH)
fmt.Fprintln(out, x, h)
prevH = h
}
}
}
```