#![allow(unused_imports)]

use std::cmp;
use std::cmp::{max, min, Ordering};
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
use std::io::stdin;
use std::ops::*;
use std::process::exit;
use std::str::FromStr;

/// `i`が素数 <=> `self.0[i]`
#[derive(Debug)]
pub struct Prime(Vec<bool>);
impl Prime {
    /// エラストテネスの篩を用いて`n`より小さい素数を調べます
    /// 大体`O(n log log n)`なはず
    ///
    /// AtCoder Language Test 202001 コードテスト上で
    /// 10^8が限界 <- 十分
    pub fn init(n: usize) -> Self {
        let mut sieve = vec![true; n];
        sieve[0] = false;
        sieve[1] = false;
        let mut i = 2;
        while i * i <= n {
            if sieve[i] {
                for x in (2..).map(|x| x * i).take_while(|x| *x < n) {
                    sieve[x] = false
                }
            }
            i += 1;
        }
        Prime(sieve)
    }
    pub fn len(&self) -> usize {
        self.0.len()
    }
    pub fn is_empty(&self) -> bool {
        self.0.len() == 0
    }
    /// 前計算によるテーブルを用いて素因数分解をします
    ///
    /// 返り値は`Vec<(素因数, 指数)>`の形式
    ///
    /// 十分に大きいテーブルを渡してください
    ///
    /// # Panic
    /// `self`の最大値が`n`より大きいときパニックする
    ///
    /// ```
    /// let table = Prime::init(10);
    /// assert_eq!(table.factorization(9), vec![(3, 2)]); // ok!
    /// // assert_eq!(table.factorization(10), vec![(2, 1), (5, 1)]); // panic! Because table.len() <= n
    /// ```
    pub fn factorization(&self, n: usize) -> Vec<(usize, usize)> {
        assert!(self.len() > n);
        let mut res = Vec::new();
        let ps = self.primes();
        let mut n = n;
        for p in ps {
            let mut count = 0;
            while n % p == 0 {
                n /= p;
                count += 1;
            }
            if count > 0 {
                res.push((p, count));
            }
        }
        if n > 1 {
            res.push((n, 1));
        }
        res
    }
    pub fn primes(&self) -> Vec<usize> {
        self.0
            .iter()
            .enumerate()
            .filter(|t| *t.1)
            .map(|x| x.0)
            .collect()
    }
    /// `n`が素数かどうかをテーブルを用いて判定します
    ///
    /// `O(1)`
    ///
    /// # Panic
    /// `n >= self.0.len()`のとき、panicします。
    pub fn is_prime(&self, n: usize) -> bool {
        assert!(n < self.len());
        self.0[n]
    }
}
/// 素因数分解をします。
///
/// 呼び出すごとに新しく篩を作るので
/// 複数回を呼び出すときは計算量が増大します
/// 初期化したPrime構造体に対してメゾットを呼んでください。
/// (その代わりにパニックしません)
pub fn factorization(n: usize) -> Vec<(usize, usize)> {
    let mut res = Vec::new();
    let ps = Prime::init(n).primes();
    let mut n = n;
    for p in ps {
        let mut count = 0;
        while n % p == 0 {
            n /= p;
            count += 1;
        }
        if count > 0 {
            res.push((p, count));
        }
    }
    if n > 1 {
        res.push((n, 1));
    }
    res
}
// /// Find the first factor (other than 1) of a number
// fn firstfac(x: u64) -> u64 {
//     if x % 2 == 0 {
//         return 2;
//     };
//     for n in (3..).step_by(2).take_while(|m| m * m <= x) {
//         if x % n == 0 {
//             return n;
//         };
//     }
//     x
// }
// /// 試し割りによる素数判定です
// ///
// /// `O(√n)`
// pub fn is_prime(n: u64) -> bool {
//     if n <= 1 {
//         return false;
//     }
//     firstfac(n) == n
// }

const MOD: usize = 1000000007;

fn main() {
    let n: usize = input();
    let t = Prime::init(1005);

    let mut ff = HashMap::new();
    for i in 1..n + 1 {
        let f = t.factorization(i);
        for (k, v) in f {
            let h = ff.entry(k).or_insert(1);
            *h += v;
        }
    }

    let mut ans = 1;
    for v in ff.values() {
        ans *= *v;
        ans %= MOD;
    }

    println!("{}", ans);
}

pub fn input<T: FromStr>() -> T {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    buf.trim().parse().ok().unwrap()
}

pub fn input_vec<T: FromStr>() -> Vec<T> {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    buf.trim()
        .split_whitespace()
        .map(|x| x.parse().ok().unwrap())
        .collect::<Vec<_>>()
}

pub fn input_lines<T: FromStr>(l: usize) -> Vec<T> {
    let mut res = Vec::new();
    for _i in 0..l {
        res.push(input());
    }
    res
}

pub fn input_lines_two<T: FromStr, U: FromStr>(l: usize) -> Vec<(T, U)> {
    let mut res = Vec::new();
    for _i in 0..l {
        res.push(input_two());
    }
    res
}

pub fn input_lines_three<T: FromStr, U: FromStr, V: FromStr>(l: usize) -> Vec<(T, U, V)> {
    let mut res = Vec::new();
    for _i in 0..l {
        res.push(input_three());
    }
    res
}

pub fn input_two<T: FromStr, U: FromStr>() -> (T, U) {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    let s: Vec<&str> = buf.split_whitespace().collect();
    (
        s[0].parse::<T>().ok().unwrap(),
        s[1].parse::<U>().ok().unwrap(),
    )
}

pub fn input_three<T: FromStr, U: FromStr, V: FromStr>() -> (T, U, V) {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    let s: Vec<&str> = buf.split_whitespace().collect();
    (
        s[0].parse::<T>().ok().unwrap(),
        s[1].parse::<U>().ok().unwrap(),
        s[2].parse::<V>().ok().unwrap(),
    )
}

pub fn input_four<T: FromStr, U: FromStr, V: FromStr, W: FromStr>() -> (T, U, V, W) {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    let s: Vec<&str> = buf.split_whitespace().collect();
    (
        s[0].parse().ok().unwrap(),
        s[1].parse().ok().unwrap(),
        s[2].parse().ok().unwrap(),
        s[3].parse().ok().unwrap(),
    )
}


Measured memory_bytes: 4352