```go
package main
import (
"bufio"
"fmt"
"os"
"sort"
)
type Point struct {
x, y int
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanWords)
readInt := func() int {
scanner.Scan()
s := scanner.Bytes()
v := 0
for _, c := range s {
v = v*10 + int(c-'0')
}
return v
}
out := bufio.NewWriter(os.Stdout)
defer out.Flush()
const MAXN = 100005
min_X := make([]int, MAXN)
max_X := make([]int, MAXN)
for i := range min_X {
min_X[i] = 1e9
max_X[i] = -1e9
}
for {
scanner.Scan()
s := scanner.Bytes()
if len(s) == 0 {
break
}
N := 0
for _, c := range s {
N = N*10 + int(c-'0')
}
M := readInt()
if N == 0 && M == 0 {
break
}
min_y := int(1e9)
max_y := int(-1e9)
for i := 0; i < M; i++ {
x := readInt()
y := readInt()
if x < min_X[y] {
min_X[y] = x
}
if x > max_X[y] {
max_X[y] = x
}
if y < min_y {
min_y = y
}
if y > max_y {
max_y = y
}
}
var points []Point
for y := min_y; y < max_y; y++ {
if min_X[y] > max_X[y] || min_X[y+1] > max_X[y+1] {
continue
}
left := min_X[y]
if min_X[y+1] > left {
left = min_X[y+1]
}
right := max_X[y]
if max_X[y+1] < right {
right = max_X[y+1]
}
right -= 1
if left <= right {
points = append(points, Point{left, y})
if left != right {
points = append(points, Point{right, y})
}
}
}
for y := min_y; y <= max_y; y++ {
min_X[y] = 1e9
max_X[y] = -1e9
}
sort.Slice(points, func(i, j int) bool {
if points[i].x == points[j].x {
return points[i].y < points[j].y
}
return points[i].x < points[j].x
})
crossProduct := func(p1, p2, p3 Point) int64 {
return int64(p2.x-p1.x)*int64(p3.y-p2.y) - int64(p2.y-p1.y)*int64(p3.x-p2.x)
}
var upper []Point
for _, p := range points {
for len(upper) >= 2 {
if crossProduct(upper[len(upper)-2], upper[len(upper)-1], p) >= 0 {
upper = upper[:len(upper)-1]
} else {
break
}
}
upper = append(upper, p)
}
var lower []Point
for i := len(points) - 1; i >= 0; i-- {
p := points[i]
for len(lower) >= 2 {
if crossProduct(lower[len(lower)-2], lower[len(lower)-1], p) >= 0 {
lower = lower[:len(lower)-1]
} else {
break
}
}
lower = append(lower, p)
}
var hull []Point
if len(upper) > 0 {
hull = append(hull, upper[:len(upper)-1]...)
}
if len(lower) > 0 {
hull = append(hull, lower[:len(lower)-1]...)
}
fmt.Fprintf(out, "%d\n", len(hull))
for _, p := range hull {
fmt.Fprintf(out, "%d %d\n", p.x, p.y)
}
}
}
```