#pragma region template
// clang-format off
#if defined ONLINE_JUDGE
  #pragma GCC target("avx2")
  #pragma GCC optimize("tree-vectorize")
  #define here
  #define com(msg)
  #define watch(...)
  #define watchVec(vec)
  #define local(x)
  #define alter(x,y) y
  #define M_assert(expr) do{if(!expr) vector<int> MLE_(3e8, 0);} while(0)
  #define O_assert(expr) do{if(!expr) while(1) printf("Hello, world!\n");} while(0)
#elif defined LOCAL_JUDGE
  #pragma GCC target("avx2")
  #pragma GCC optimize("tree-vectorize")
  #define here
  #define com(msg)
  #define watch(...)
  #define watchVec(vec)
  #define local(x)
  #define alter(x,y) y
  #define M_assert(expr) assert(expr)
  #define O_assert(expr) assert(expr)
#else
  #define here cerr<<__func__<<"/"<<__LINE__<<": reached\n"
  #define com(msg) cerr<<"{ "<<msg<< " }\n"
  #define watch(...) observe(#__VA_ARGS__,__VA_ARGS__)
  #define watchVec(vec) do{cerr<<#vec<<": ";printv(#vec,vec);} while(0)
  #define local(x) do{x} while(0)
  #define alter(x,y) x
  #define M_assert(expr) assert(expr)
  #define O_assert(expr) assert(expr)
#endif

#include <bits/stdc++.h>
#include <boost/range/irange.hpp>
#include <boost/multiprecision/cpp_int.hpp>

#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define rep(i,n) for(int i=0;i<(n);i++)
#define rng(i,f,t,s) for(int i : boost::irange(f,t,s))
#define erng(i,f,t,s) for(int i : boost::irange(f,t+(s>0)-(s<0),s))
#define yes(n) cout<<((n)?YES:NO)<<"\n"
#define Sort(v) sort((v).begin(),(v).end())
#define rSort(v) sort((v).rbegin(),(v).rend())
#define Rev(v) reverse((v).begin(),(v).end())
#define Unique(v) (v).erase(unique((v).begin(),(v).end()),(v).end())
#define inarea(p,a,b) (0<=(p.first)&&0<=(p.second)&&(p.first)<(a)&&(p.second)<(b))
#define in_area(y,x,a,b) (0<=(y)&&0<=(x)&&(y)<(a)&&(x)<(b))
#define in_range(x,a,b) ((a)<=(x)&&(x)<(b))

using namespace std;
using ll    = long long;
using ld    = long double;
using pt    = pair<int, int>;
using ull   = unsigned long long;
using str   = string;
using vbl   = vector<bool>;
using dqbl  = deque<bool>;
using vint  = vector<int>;
using vll   = vector<long long>;
using vdb   = vector<double>;
using vld   = vector<long double>;
using vpt   = vector<pair<int, int>>;
using vstr  = vector<string>;
using vvdb  = vector<vector<double>>;
using vvbl  = vector<vector<bool>>;
using vdqbl = vector<deque<bool>>;
using vvint = vector<vector<int>>;
using vvll  = vector<vector<long long>>;
using Int   = boost::multiprecision::cpp_int;

constexpr int       INF   = 1e9;
constexpr long long LINF  = 1e18;
constexpr double    EPS   = 1e-9;
constexpr int       MOD   = 1000000007;
constexpr int       dy[]  = {1,0,-1,0,1,1,-1,-1};
constexpr int       dx[]  = {0,1,0,-1,-1,1,1,-1};
constexpr pt        dv[]  = { {1,0},{0,1},{-1,0},{0,-1},{1,-1},{1,1},{-1,1},{-1,-1} };

// --- functions for debugging --- //
template<class T>            void observe(const char *n,T &&v)         {cerr<<n<<": "<<v<<"\n";}
template<class S,class... T> void observe(const char *n,S &&v,T&&... w){const char *c=strchr(n+1,',');cerr.write(n,c-n)<<": "<<v<<" |";observe(c+1,w...);}
template<class T> void printv([[maybe_unused]] const char *n, const vector<T> &v){cerr<<"[ ";for(const T &x:v)cerr<<x<<" ";cerr<<"]\n";}
template<class T> void printv([[maybe_unused]] const char *n, const deque<T> &v) {cerr<<"[ ";for(const T &x:v)cerr<<x<<" ";cerr<<"]\n";}
template<class T> void printv([[maybe_unused]] const char *n, const set<T> &v)   {cerr<<"[ ";for(const T &x:v)cerr<<x<<" ";cerr<<"]\n";}
template<class P> void printv([[maybe_unused]] const char *n, const P &p){cerr<<"{ "<<p.first<<" "<<p.second<<" } ";}
template<class T> void printv(const char *n, const vector<vector<T>> &v){bool f=0;for(const vector<T> &x:v){if(f)cerr<<string(strlen(n)+2,' ');f=1;printv<T>("",x);}}
template<class T> void printv(const char *n, const vector<deque<T>> &v) {bool f=0;for(const deque<T> &x:v){if(f)cerr<<string(strlen(n)+2,' ');f=1;printv<T>("",x);}}
template<class S,class T> void printv([[maybe_unused]] const char *n, const map<S,T> &m) {cerr<<"[ ";for(const pair<S,T> &p:m)cerr<<"{ "<<p.first<<", "<<p.second<<" } ";cerr<<"]\n";}
template<class S,class T> void printv([[maybe_unused]] const char *n, const vector<pair<S,T>> &v){cerr<<"[ ";for(const pair<S,T> &p:v)printv<pair<S,T>>("",p);cerr<<"]\n";}
template<class S,class T> void printv([[maybe_unused]] const char *n, const deque<pair<S,T>> &v){cerr<<"[ ";for(const pair<S,T> &p:v)printv<pair<S,T>>("",p);cerr<<"]\n";}
// clang-format on
#pragma endregion
// mod

#pragma region lib_mint
/*
  class mint (mod int)
  requires: constexpr int MOD = *** (e.g. 1000000007)
*/
#ifndef lib_mint
#define lib_mint 1
namespace lib {
  template <class T = long long> constexpr T modinv(long long n, int mod = MOD) {
    int a = n, b = mod, u = 1, v = 0, t = 0;
    while (b > 0) {
      t = a / b;
      swap(a -= t * b, b);
      swap(u -= t * v, v);
    }
    return (T) u;
  }

  template <class T> constexpr int_fast32_t clamp_ll(T v) {
    if (0 <= v && v < MOD) return (int_fast32_t) v;
    if (MOD <= v && v < (MOD << 1)) return (int_fast32_t)(v - MOD);
    if (-MOD <= v && v < 0) return (int_fast32_t)(v + MOD);
    if (0 <= v)
      return (int_fast32_t)(v - v / MOD * MOD);
    else
      return (int_fast32_t)(v + (-v + MOD - 1) / MOD * MOD);
  }

  class mint {
    public:
    template <class T = int_fast32_t> constexpr mint(T v = 0) :
        val(clamp_ll(v)) {}

#define MINT_PREFIX_OP(o)        \
  constexpr mint &operator o() { \
    (this->val) o;               \
    this->clamp();               \
    return *this;                \
  }
    MINT_PREFIX_OP(++)
    MINT_PREFIX_OP(--)
#undef MINT_PREFIX_OP

#define MINT_POSTFIX_OP(o)         \
  constexpr mint operator o(int) { \
    mint ret = *this;              \
    o(*this);                      \
    return ret;                    \
  }
    MINT_POSTFIX_OP(++)
    MINT_POSTFIX_OP(--)
#undef MINT_POSTFIX_OP

#define MINT_UNARY_OP(o)              \
  constexpr mint operator o() const { \
    return mint(o(this->val));        \
  }
    MINT_UNARY_OP(+)
    MINT_UNARY_OP(-)
    MINT_UNARY_OP(~)
#undef MINT_UNARY_OP

    constexpr bool operator!() const {
      return !(this->val);
    }

#define MINT_BOOLEAN_OP(o)                    \
  constexpr bool operator o(mint rhs) const { \
    return (this->val o rhs.val);             \
  }
    MINT_BOOLEAN_OP(==)
    MINT_BOOLEAN_OP(!=)
    MINT_BOOLEAN_OP(<)
    MINT_BOOLEAN_OP(<=)
    MINT_BOOLEAN_OP(>)
    MINT_BOOLEAN_OP(>=)
    MINT_BOOLEAN_OP(&&)
    MINT_BOOLEAN_OP(||)
#undef MINT_BOOLEAN_OP

#define MINT_TEMP_BOOLEAN_OP(o)                               \
  template <class T> constexpr bool operator o(T rhs) const { \
    return (this->val o rhs);                                 \
  }
    MINT_TEMP_BOOLEAN_OP(==)
    MINT_TEMP_BOOLEAN_OP(!=)
    MINT_TEMP_BOOLEAN_OP(<)
    MINT_TEMP_BOOLEAN_OP(<=)
    MINT_TEMP_BOOLEAN_OP(>)
    MINT_TEMP_BOOLEAN_OP(>=)
    MINT_TEMP_BOOLEAN_OP(&&)
    MINT_TEMP_BOOLEAN_OP(||)
#undef MINT_TEMP_BOOLEAN_OP

#define MINT_COMPOUND_OP(o)                                   \
  [[maybe_unused]] constexpr mint &operator o##=(mint rhs) {  \
    this->val = clamp_ll((int_fast64_t) this->val o rhs.val); \
    return *this;                                             \
  }
    MINT_COMPOUND_OP(+)
    MINT_COMPOUND_OP(-)
    MINT_COMPOUND_OP(*)
    MINT_COMPOUND_OP(%)
    MINT_COMPOUND_OP(&)
    MINT_COMPOUND_OP(|)
    MINT_COMPOUND_OP(^)
    MINT_COMPOUND_OP(<<)
    MINT_COMPOUND_OP(>>)
#undef MINT_COMPOUND_OP

#define MINT_TEMP_COMPOUND_OP(o)                                            \
  template <class T>[[maybe_unused]] constexpr mint &operator o##=(T rhs) { \
    this->val = (*this o mint(rhs));                                        \
    this->clamp();                                                          \
    return *this;                                                           \
  }
    MINT_TEMP_COMPOUND_OP(+)
    MINT_TEMP_COMPOUND_OP(-)
    MINT_TEMP_COMPOUND_OP(*)
    MINT_TEMP_COMPOUND_OP(%)
    MINT_TEMP_COMPOUND_OP(&)
    MINT_TEMP_COMPOUND_OP(|)
    MINT_TEMP_COMPOUND_OP(^)
    MINT_TEMP_COMPOUND_OP(<<)
    MINT_TEMP_COMPOUND_OP(>>)
#undef MINT_TEMP_COMPOUND_OP

    template <class T>[[maybe_unused]] constexpr mint &operator/=(T divided_by) {
      assert(divided_by != 0);
      return *this *= modinv(divided_by);
    }

#define MINT_OP(o)                            \
  constexpr mint operator o(mint rhs) const { \
    return mint(*this) o## = rhs;             \
  }
    MINT_OP(+)
    MINT_OP(-)
    MINT_OP(*)
    MINT_OP(/)
    MINT_OP(%)
    MINT_OP(&)
    MINT_OP(|)
    MINT_OP(^)
    MINT_OP(<<)
    MINT_OP(>>)
#undef MINT_OP

#define MINT_TEMP_OP(o)                                       \
  template <class T> constexpr mint operator o(T rhs) const { \
    return *this o mint(rhs);                                 \
  }
    MINT_TEMP_OP(+)
    MINT_TEMP_OP(-)
    MINT_TEMP_OP(*)
    MINT_TEMP_OP(%)
    MINT_TEMP_OP(&)
    MINT_TEMP_OP(|)
    MINT_TEMP_OP(^)
    MINT_TEMP_OP(<<)
    MINT_TEMP_OP(>>)
#undef MINT_TEMP_OP

#define MINT_CAST_OP(t)               \
  constexpr operator t() const {      \
    return static_cast<t>(this->val); \
  }
    MINT_CAST_OP(bool)
    MINT_CAST_OP(char)
    MINT_CAST_OP(signed char)
    MINT_CAST_OP(unsigned char)
    MINT_CAST_OP(short int)
    MINT_CAST_OP(unsigned short int)
    MINT_CAST_OP(int)
    MINT_CAST_OP(unsigned int)
    MINT_CAST_OP(long int)
    MINT_CAST_OP(unsigned long int)
    MINT_CAST_OP(long long int)
    MINT_CAST_OP(unsigned long long int)
    MINT_CAST_OP(float)
    MINT_CAST_OP(double)
    MINT_CAST_OP(long double)
#undef MINT_CAST_OP
#ifdef BOOST_MP_CPP_INT_HPP
    operator boost::multiprecision::cpp_int() const {
      return static_cast<boost::multiprecision::cpp_int>(this->val);
    }
#endif

    constexpr mint inverse() {
      return modinv<mint>(this->val);
    }

    friend istream &operator>>(istream &, mint &);
    friend ostream &operator<<(ostream &, mint);

    private:
    int_fast32_t val;

    constexpr void clamp() {
      if (0 <= (this->val) && (this->val) < MOD) return;
      if (MOD <= (this->val) && (this->val) < (MOD << 1)) {
        (this->val) -= MOD;
        return;
      }
      if (-MOD <= (this->val) && (this->val) < 0) {
        (this->val) += MOD;
        return;
      }

      if (0 <= (this->val))
        (this->val) -= (this->val) / MOD * MOD;
      else
        (this->val) += (-(this->val) + MOD - 1) / MOD * MOD;
    }
  };

  istream &operator>>(istream &is, mint &m) {
    return is >> m.val;
  }
  ostream &operator<<(ostream &os, mint m) {
    return os << m.val;
  }

}  // namespace lib

template <class T> struct common_type<lib::mint, T> { using type = lib::mint; };
using mint   = lib::mint;
using vmint  = vector<mint>;
using vvmint = vector<vector<mint>>;
#endif
#pragma endregion

#pragma region lib_combination
namespace lib {
  /*
    Function that calculates nPr
    usage: nPr(5, 3)
  */
  template <class S, class T> common_type_t<S, long long> nPr(S n, T r) {
    using return_type = common_type_t<S, long long>;
    if (n < r || n < 0 || r < 0) return 0;
    return_type ret = 1;
    for (return_type i = n - r + 1; i <= n; i++) ret *= i;
    return ret;
  }

  /*
    Function that calculates nCr
    usage: nCr(5, 3)
  */
  template <class S, class T> common_type_t<S, long long> nCr(S n, T r) {
    using return_type = common_type_t<S, long long>;
    if (n < r || n < 0 || r < 0) return 0;
    S r_p = min(static_cast<S>(r), static_cast<S>(n - r));

    return_type ret = 1;
    for (return_type i = n - r_p + 1; i <= n; i++) ret *= i;
    for (return_type i = 2; i <= r_p; i++) ret /= i;
    return ret;
  }

  /*
    Function that calculates nHr
    usage: nHr(5, 3)
  */
  template <class S, class T> common_type_t<S, long long> nHr(S n, T r) {
    return nCr<S, T>(n + r - 1, r - 1);
  }

#ifdef lib_mint
  bool init_done   = false;
  constexpr int MX = 3500;
  static vector<mint> mod_fact(MX);
  static vector<mint> mod_fact_inv(MX);

  void mod_factorial_init() {
    if (init_done) return;
    mod_fact[0] = 1;
    for (int i = 1; i < MX; i++) mod_fact[i] = mod_fact[i - 1] * i;
    mod_fact_inv[MX - 1] = mod_fact[MX - 1].inverse();
    for (int i = MX - 1; i > 0; i--) mod_fact_inv[i - 1] = mod_fact_inv[i] * i;
    init_done = true;
  }

  /*
    Function that calculates nPr mod m
    usage: nPr(5, 3)
  */
  template <class T> mint nPr(mint n, T r) {
    if (!init_done) mod_factorial_init();
    if (n < r || n < 0 || r < 0) return 0;
    return mod_fact[n] * mod_fact_inv[n - r];
  }

  /*
    Function that calculates nCr mod m
    usage: nCr(5, 3)
  */
  template <class T> mint nCr(mint n, T r) {
    if (!init_done) mod_factorial_init();
    if (n < r || n < 0 || r < 0) return 0;
    return mod_fact[n] * mod_fact_inv[r] * mod_fact_inv[n - r];
  }

  /*
    Function that calculates nHr mod m
    usage: nHr(5, 3)
  */
  template <class T> mint nHr(mint n, T r) {
    if (!init_done) mod_factorial_init();
    if (n < r || n < 0 || r < 0) return 0;
    return mod_fact[n + r - 1] * mod_fact_inv[r - 1] * mod_fact_inv[n];
  }

  /*
    Function that calculates nPr mod m
    usage: nPr(5, 3)
  */
  template <class S, class T> mint nPr_mod(S n, T r) {
    if (!init_done) mod_factorial_init();
    if (n < r || n < 0 || r < 0) return 0;
    return mod_fact[n] * mod_fact_inv[n - r];
  }

  /*
    Function that calculates nCr mod m
    usage: nCr(5, 3)
  */
  template <class S, class T> mint nCr_mod(S n, T r) {
    if (!init_done) mod_factorial_init();
    if (n < r || n < 0 || r < 0) return 0;
    return mod_fact[n] * mod_fact_inv[r] * mod_fact_inv[n - r];
  }

  /*
    Function that calculates nHr mod m
    usage: nHr(5, 3)
  */
  template <class S, class T> mint nHr_mod(S n, T r) {
    return nCr_mod<S, T>(n + r - 1, r - 1);
  }
#endif
}  // namespace lib
#pragma endregion

void solve(int S) {
  mint ans;

  erng(len, 1, S / 3, 1) {
    ans += lib::nHr_mod(S - len * 3, len);
  }

  cout << ans << "\n";
}

// clang-format off
int main() {
  #pragma GCC diagnostic push
  #pragma GCC diagnostic ignored "-Wunused-result"
  int S;
  scanf("%d",&S);
  #pragma GCC diagnostic pop
  solve(S);
  exit(EXIT_SUCCESS);
}


Measured memory_bytes: 3824