#![allow(dead_code)]
#![allow(unused)]
use proconio::input;
#[macro_use]
extern crate lazy_static;

mod modulus {
    pub const MOD: i64 = 1000000007;
    
    use std::sync::RwLock;
    lazy_static! {
        pub(self) static ref NCR_MAXIMUM: RwLock<i32> = RwLock::new(0);
        pub(self) static ref FACTORIAL: RwLock<Vec<i64>> = RwLock::new(Vec::new());
        pub(self) static ref FACTORIAL_INVERSE: RwLock<Vec<i64>> = RwLock::new(Vec::new());
        pub(self) static ref INVERSE: RwLock<Vec<i64>> = RwLock::new(Vec::new());
    }
    
    use std::cmp;
    pub fn prepare_ncr(maximum_value: i32) {
        let mut ncr_maximum = NCR_MAXIMUM.write().unwrap();
        if(maximum_value < *ncr_maximum) { return };
        let maximum_value = cmp::max(2, maximum_value) as usize;
        let mut factorial = FACTORIAL.write().unwrap();
        factorial.resize(maximum_value, 0);
        let mut factorial_inverse = FACTORIAL_INVERSE.write().unwrap();
        factorial_inverse.resize(maximum_value, 0);
        let mut inverse = INVERSE.write().unwrap();
        inverse.resize(maximum_value, 0);
        if(*ncr_maximum <= 2) {
            factorial[0] = 1; factorial[1] = 1;
            factorial_inverse[0] = 1; factorial_inverse[1] = 1;
            inverse[1] = 1;
        }
        for i in cmp::max(2, *ncr_maximum as usize)..maximum_value {
            factorial[i] = factorial[i - 1] * i as i64 % MOD;
            inverse[i] = MOD - inverse[(MOD % i as i64) as usize] * (MOD / i as i64) % MOD;
            factorial_inverse[i] = factorial_inverse[i - 1] * inverse[i] % MOD;
        }
        *ncr_maximum = maximum_value as i32;
    }
    pub fn ncr(n: i32, r: i32) -> ModNumber {
        if(n < r || n < 0 || r < 0)  { return ModNumber::new(0); }
        let ncr_maximum = NCR_MAXIMUM.read().unwrap();
        let factorial = FACTORIAL.read().unwrap();
        let factorial_inverse = FACTORIAL_INVERSE.read().unwrap();
        let inverse = INVERSE.read().unwrap();
        let n = n as usize; let r = r as usize;
        return ModNumber::new(factorial[n] * (factorial_inverse[r] * factorial_inverse[n - r] % MOD) % MOD);
    }

    #[derive(Copy, Clone)]
    pub struct ModNumber {
        pub(self) num: i64
    }

    impl ModNumber {
        pub fn new(n: i64) -> ModNumber {
            ModNumber{num: n % MOD}
        }
        pub fn to_i64(&self) -> i64 {
            self.num
        }
    }

    impl std::ops::Add for ModNumber {
        type Output = Self;
        fn add(self, other: Self) -> Self {
            Self{ num: (self.num + other.num)}
        }
    }
    impl std::ops::AddAssign for ModNumber {
        fn add_assign(&mut self, other: Self) {
            self.num += other.num;
            self.num %= MOD;
        }
    }
    impl std::ops::Sub for ModNumber {
        type Output = Self;
        fn sub(self, other: Self) -> Self {
            Self{ num: if self.num < other.num { self.num - other.num + MOD } else { self.num - other.num }}
        }
    }
    impl std::ops::SubAssign for ModNumber {
        fn sub_assign(&mut self, other: Self) {
            if self.num < other.num {
                self.num += MOD;
            }
            self.num -= other.num;
            self.num %= MOD;
        }
    }
    impl std::fmt::Display for ModNumber {
        fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
            write!(f, "{}", self.num)
        }
    }

}

fn main() {
    input!{ s: i32 }
    let mut rest = s % 3;
    modulus::prepare_ncr(2000);
    let mut result = modulus::ModNumber::new(0);
    let mut length = s / 3;
    while length >= 1 {
        result += modulus::ncr(rest + length - 1, length - 1);
        length -= 1; rest += 3;
    }
    println!("{}", result);
}


Measured memory_bytes: 2200