← Home
package main

import (
	"bufio"
	"fmt"
	"math/bits"
	"os"
	"sort"
)

const MOD int64 = 1000000007

func modPow(a, e int64) int64 {
	res := int64(1)
	for e > 0 {
		if e&1 == 1 {
			res = (res * a) % MOD
		}
		a = (a * a) % MOD
		e >>= 1
	}
	return res
}

func main() {
	in := bufio.NewReader(os.Stdin)
	var n int
	fmt.Fscan(in, &n)

	k := bits.Len(uint(n)) - 1

	spf := make([]int, n+1)
	primes := make([]int, 0)
	for i := 2; i <= n; i++ {
		if spf[i] == 0 {
			spf[i] = i
			primes = append(primes, i)
		}
		for _, p := range primes {
			if p > spf[i] || i*p > n {
				break
			}
			spf[i*p] = p
		}
	}
	omega := make([]int, n+1)
	for i := 2; i <= n; i++ {
		omega[i] = omega[i/spf[i]] + 1
	}

	cands := make([]int, 0)
	for i := 2; i <= n; i++ {
		if omega[i] == k {
			cands = append(cands, i)
		}
	}
	if len(cands) == 0 {
		fmt.Println(0)
		return
	}

	maxFact := n
	fact := make([]int64, maxFact+1)
	invfact := make([]int64, maxFact+1)
	fact[0] = 1
	for i := 1; i <= maxFact; i++ {
		fact[i] = (fact[i-1] * int64(i)) % MOD
	}
	invfact[maxFact] = modPow(fact[maxFact], MOD-2)
	for i := maxFact - 1; i >= 0; i-- {
		invfact[i] = (invfact[i+1] * int64(i+1)) % MOD
	}

	type Edge struct {
		child int
		D     int
	}
	type Node struct {
		val      int
		om       int
		mult     int
		U        int
		children []Edge
	}

	var total int64 = 0

	for _, p1 := range cands {
		// factorize p1
		ps := make([]int, 0)
		es := make([]int, 0)
		tmp := p1
		for tmp > 1 {
			p := spf[tmp]
			cnt := 0
			for tmp%p == 0 {
				tmp /= p
				cnt++
			}
			ps = append(ps, p)
			es = append(es, cnt)
		}
		// generate divisors
		nodes := make([]Node, 0)
		idxOf := make(map[int]int)
		var gen func(pos int, cur int, om int)
		gen = func(pos int, cur int, om int) {
			if pos == len(ps) {
				idxOf[cur] = len(nodes)
				nodes = append(nodes, Node{val: cur, om: om})
				return
			}
			v := 1
			for e := 0; e <= es[pos]; e++ {
				gen(pos+1, cur*v, om+e)
				v *= ps[pos]
			}
		}
		gen(0, 1, 0)

		// fill mult and U
		baseMult := n / p1
		for i := range nodes {
			nodes[i].mult = n / nodes[i].val
			nodes[i].U = nodes[i].mult - baseMult - (k - nodes[i].om)
			if nodes[i].U < 0 {
				nodes[i].U = 0
			}
		}
		// build children edges
		for i := range nodes {
			v := nodes[i].val
			for _, p := range ps {
				if v%p == 0 {
					cv := v / p
					cidx := idxOf[cv]
					D := nodes[cidx].mult - nodes[i].mult
					nodes[i].children = append(nodes[i].children, Edge{child: cidx, D: D})
				}
			}
		}
		// sort by om ascending
		order := make([]int, len(nodes))
		for i := range order {
			order[i] = i
		}
		sort.Slice(order, func(i, j int) bool {
			return nodes[order[i]].om < nodes[order[j]].om
		})

		ans := make([][]int64, len(nodes))
		for _, idx := range order {
			node := &nodes[idx]
			U := node.U
			curAns := make([]int64, U+1)
			if node.val == 1 {
				for s := 0; s <= U; s++ {
					curAns[s] = fact[s]
				}
			} else {
				for _, e := range node.children {
					childAns := ans[e.child]
					D := e.D
					var prev int64 = 0
					for s := 0; s <= U; s++ {
						prev += (childAns[s+D-1] * invfact[s]) % MOD
						if prev >= MOD {
							prev -= MOD
						}
						add := (int64(D) * fact[s]) % MOD
						add = (add * prev) % MOD
						curAns[s] += add
						if curAns[s] >= MOD {
							curAns[s] -= MOD
						}
					}
				}
			}
			ans[idx] = curAns
		}
		topIdx := idxOf[p1]
		total += ans[topIdx][0]
		if total >= MOD {
			total -= MOD
		}
	}

	fmt.Println(total % MOD)
}