```go
package main
import (
"bufio"
"fmt"
"os"
)
type Pair struct {
a, b int
}
func main() {
in := bufio.NewReaderSize(os.Stdin, 1<<20)
var n int
fmt.Fscan(in, &n)
comp := make([]bool, n+1)
primes := make([]int, 0)
for i := 2; i <= n; i++ {
if !comp[i] {
primes = append(primes, i)
if i*i <= n {
for j := i * i; j <= n; j += i {
comp[j] = true
}
}
}
}
used := make([]bool, n+1)
pairs := make([]Pair, 0, n/2)
for idx := len(primes) - 1; idx >= 0; idx-- {
p := primes[idx]
if p == 2 {
continue
}
v := make([]int, 0)
for x := p; x <= n; x += p {
if !used[x] {
v = append(v, x)
}
}
if len(v)%2 == 1 {
if 2*p > n {
continue
}
u := make([]int, 0, len(v)-1)
removed := false
skip := 2 * p
for _, x := range v {
if !removed && x == skip {
removed = true
continue
}
u = append(u, x)
}
v = u
}
for i := 0; i+1 < len(v); i += 2 {
a, b := v[i], v[i+1]
used[a] = true
used[b] = true
pairs = append(pairs, Pair{a, b})
}
}
evens := make([]int, 0)
for x := 2; x <= n; x += 2 {
if !used[x] {
evens = append(evens, x)
}
}
for i := 0; i+1 < len(evens); i += 2 {
pairs = append(pairs, Pair{evens[i], evens[i+1]})
}
out := bufio.NewWriterSize(os.Stdout, 1<<20)
fmt.Fprintln(out, len(pairs))
for _, p := range pairs {
fmt.Fprintln(out, p.a, p.b)
}
out.Flush()
}
```