#include <bits/stdc++.h>
using namespace std;
#define lli long long int
#define pb push_back
#define mp make_pair
#define mod 1000000007

lli n;
vector<lli> dp;

lli bhardo(lli i) {
  if (dp[i] != -1)
    return dp[i];
  lli ans = 0;
  for (lli j = 3; j <= i; j++) {
    ans = (ans + bhardo(i - j)) % mod;
  }
  dp[i] = ans;
  return dp[i];
}

int main() {
  cin >> n;
  if (n < 3) {
    cout << 0;
    return 0;
  }
  dp = vector<lli>(n + 1, -1);
  dp[0] = 1;
  dp[1] = 0;
  dp[2] = 0;
  dp[3] = 1;
  dp[4] = 1;
  dp[5] = 1;
  // lli ans=0;
  // for(lli i=3;i<=n;i++)
  // {
  //     ans=ans+dp[n-i];
  // }
  cout << bhardo(n);
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define lli long long int
#define pb push_back
#define mp make_pair
#define mod 1000000007

lli n;
vector<lli> dp;

lli bhardo(lli i) {
  if (dp[i] != -1)
    return dp[i];
  lli ans = 0;
  for (lli j = 3; j <= i; j++) {
    ans = (ans + bhardo(i - j)) % mod;
  }
  dp[i] = ans;
  return dp[i];
}

int main() {
  cin >> n;
  if (n < 3) {
    cout << 0;
    return 0;
  }
  dp = vector<lli>(n + 1, -1);
  if (n <= 5) {
    cout << 1;
    return 0;
  }
  dp[0] = 1;
  dp[1] = 0;
  dp[2] = 0;
  dp[3] = 1;
  dp[4] = 1;
  dp[5] = 1;
  cout << bhardo(n);
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pii;
typedef tuple<ll, ll, ll> ti;

#define REP(a, b, c) for (ll a = b; a < (c); a++)
#define PER(a, b, c) for (ll a = b; a >= (c); a--)

inline ll ii() {
  ll x;
  cin >> x;
  return x;
}
inline string is() {
  string x;
  cin >> x;
  return x;
}
inline ld id() {
  ld x;
  cin >> x;
  return x;
}
inline void oi(ll x) { cout << x; }
inline void od(ld x) { cout << fixed << setprecision(10) << x; }
inline void os(string x) { cout << x; }
inline void oe() { cout << endl; }
inline void oie(ll x) {
  oi(x);
  oe();
}
inline void ode(ld x) {
  od(x);
  oe();
}
inline void ose(string x) {
  os(x);
  oe();
}
inline void maxin(ll &a, ll b) { a = max(a, b); }
inline void minin(ll &a, ll b) { a = min(a, b); }

ll m[1123][2123];
ll mod = 1e9 + 7;

int main() {
  ll S = ii();
  ll ret = 0;
  m[0][0] = 1;
  REP(i, 0, 667) {
    REP(k, 0, S) {
      if (m[i][k] == 0)
        continue;
      for (ll j = 3; k + j <= S; j++) {
        if (k + j == S) {
          ret += m[i][k];
          ret %= mod;
        } else {
          m[i + 1][k + j] += m[i][k];
          m[i + 1][k + j] %= mod;
        }
      }
    }
  }
  oie(ret);

  return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pii;
typedef tuple<ll, ll, ll> ti;

#define REP(a, b, c) for (ll a = b; a < (c); a++)
#define PER(a, b, c) for (ll a = b; a >= (c); a--)

inline ll ii() {
  ll x;
  cin >> x;
  return x;
}
inline string is() {
  string x;
  cin >> x;
  return x;
}
inline ld id() {
  ld x;
  cin >> x;
  return x;
}
inline void oi(ll x) { cout << x; }
inline void od(ld x) { cout << fixed << setprecision(10) << x; }
inline void os(string x) { cout << x; }
inline void oe() { cout << endl; }
inline void oie(ll x) {
  oi(x);
  oe();
}
inline void ode(ld x) {
  od(x);
  oe();
}
inline void ose(string x) {
  os(x);
  oe();
}
inline void maxin(ll &a, ll b) { a = max(a, b); }
inline void minin(ll &a, ll b) { a = min(a, b); }

ll m[1123][2123];
ll mod = 1e9 + 7;

int main() {
  ll S = ii();
  ll ret = 0;
  m[0][0] = 1;
  REP(i, 0, 667) {
    ll s = 0;
    REP(k, 0, S - 3 + 1) {
      s += m[i][k];
      if (k + 3 == S) {
        ret += s;
        ret %= mod;
      } else {
        m[i + 1][k + 3] += s;
        m[i + 1][k + 3] %= mod;
      }
    }
  }
  oie(ret);

  return 0;
}


#include <algorithm>
#include <cassert>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using ll = long long;
const int mod = 1e9 + 7;

#define read_int(X)                                                            \\
  ll X;                                                                        \\
  scanf("%lld\\n", &X);

#define read_two_int(X, Y)                                                     \\
  ll X, Y;                                                                     \\
  scanf("%lld %lld\\n", &X, &Y);

#define read_three_int(X, Y, Z)                                                \\
  ll X, Y, Z;                                                                  \\
  scanf("%lld %lld %lld\\n", &X, &Y, &Z);

#define read_four_int(X, Y, Z, W)                                              \\
  ll X, Y, Z, W;                                                               \\
  scanf("%lld %lld %lld %lld\\n", &X, &Y, &Z, &W);

vector<vector<ll>> dp(2000, vector<ll>(2000, -1));
ll search(ll rest, ll n) {
  if (dp[rest][n] != -1)
    return dp[rest][n];

  if (n == 1) {
    dp[rest][n] = 1;
    return 1;
  }

  if (n == 2) {
    dp[rest][n] = rest + 1;
    return rest + 1;
  }

  ll ans = 0;
  for (ll i = 0; i <= rest; i++) {
    ans += search(rest - i, n - 2) * (i + 1);
    ans %= mod;
  }
  dp[rest][n] = ans;
  return ans;
}

int main() {
  ll S;
  scanf("%lld", &S);

  ll ans = 0;
  for (ll i = 1; i <= S / 3; i++) {
    ll rest = S - i * 3;
    ans += search(rest, i);
    ans %= mod;
  }

  printf("%lld\\n", ans);
}

#include <algorithm>
#include <cassert>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using ll = long long;
const int mod = 1e9 + 7;

#define read_int(X)                                                            \\
  ll X;                                                                        \\
  scanf("%lld\\n", &X);

#define read_two_int(X, Y)                                                     \\
  ll X, Y;                                                                     \\
  scanf("%lld %lld\\n", &X, &Y);

#define read_three_int(X, Y, Z)                                                \\
  ll X, Y, Z;                                                                  \\
  scanf("%lld %lld %lld\\n", &X, &Y, &Z);

#define read_four_int(X, Y, Z, W)                                              \\
  ll X, Y, Z, W;                                                               \\
  scanf("%lld %lld %lld %lld\\n", &X, &Y, &Z, &W);

vector<vector<ll>> dp(2000, vector<ll>(2000, -1));
ll search(ll rest, ll n) {
  if (dp[rest][n] != -1)
    return dp[rest][n];

  if (n == 1) {
    dp[rest][n] = 1;
    return 1;
  }

  if (n == 2) {
    dp[rest][n] = rest + 1;
    return rest + 1;
  }

  ll ans = 0;
  ll left = n / 2;
  for (ll i = 0; i <= rest; i++) {
    ans += search(rest - i, left) * search(i, n - left);
    ans %= mod;
  }
  dp[rest][n] = ans;
  return ans;
}

int main() {
  ll S;
  scanf("%lld", &S);

  ll ans = 0;
  for (ll i = 1; i <= S / 3; i++) {
    ll rest = S - i * 3;
    ans += search(rest, i);
    ans %= mod;
  }

  printf("%lld\\n", ans);
}


#include <bits/stdc++.h>

#define fi first
#define se second
#define pb push_back

#define limit (int)(1e6 + 5)
#define mod (long long int)(1e9 + 7)

using namespace std;
using lli = long long int;
using ulli = unsigned long long int;
using ld = long double;

lli dp[2000][667];
int s;

lli fa(int in, int ps) {
  // cout << in << " " << ps << "\\n";
  if (ps == s) {
    return 1;
  }

  if (s - ps < 3) {
    dp[ps][s] = 0;
    return 0;
  }

  if (dp[ps][in] != -1) {
    return dp[ps][in];
  }

  dp[ps][in] = 0;

  for (int i = 3; i <= s; ++i) {
    if (i + ps > s) {
      break;
    }

    dp[ps][in] += fa(in + 1, ps + i);
    dp[ps][in] %= mod;
  }

  return dp[ps][in];
}

int main() {
  // ios_base::sync_with_stdio(false);cin.tie(NULL);
  cin >> s;

  for (int i = 0; i <= s; ++i) {
    for (int j = 0; j <= s / 3; ++j) {
      dp[i][j] = -1;
    }
  }

  fa(0, 0);

  cout << dp[0][0];
  return 0;
}

#include <bits/stdc++.h>

#define fi first
#define se second
#define pb push_back

#define limit (int)(1e6 + 5)
#define mod (long long int)(1e9 + 7)

using namespace std;
using lli = long long int;
using ulli = unsigned long long int;
using ld = long double;

lli dp[2001];
int s;

lli fa(int ps) {
  // cout << in << " " << ps << "\\n";
  if (ps == 0) {
    return 1;
  }

  if (ps < 3) {
    // dp[ps] = 0;
    return 0;
  }

  if (dp[ps] != -1) {
    return dp[ps];
  }

  dp[ps] = 0;

  for (int i = 3; i <= ps; ++i) {
    dp[ps] += fa(ps - i);
    dp[ps] %= mod;
  }

  return dp[ps];
}

int main() {
  // ios_base::sync_with_stdio(false);cin.tie(NULL);
  cin >> s;

  if (s < 3) {
    cout << 0;
    return 0;
  }

  for (int i = 0; i <= s; ++i) {
    dp[i] = -1;
  }

  fa(s);

  cout << dp[s];
  return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define pb push_back
#define sz(v) (int)v.size()
#define all(v) v.begin(), v.end()
#define dbg(x) cerr << #x << " is " << x << "\\n";

using ll = long long;
using ii = pair<ll, ll>;

const int S = 2005;
const int N = 670;
const int MOD = 1e9 + 7;

ll dp[N][S];
int main() {
  int s;
  scanf("%d", &s);
  dp[0][0] = 1;
  for (int i = 1; i < N; i++) {
    for (int j = 3; j <= s; j++) {
      for (int k = 3; k <= j; k++) {
        dp[i][j] += dp[i - 1][j - k];
        if (dp[i][j] >= MOD)
          dp[i][j] -= MOD;
      }
    }
  }
  ll ans = 0;
  for (int i = 0; i < N; i++) {
    ans += dp[i][s];
    if (ans >= MOD)
      ans -= MOD;
  }
  printf("%lld\\n", ans);
  return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define pb push_back
#define sz(v) (int)v.size()
#define all(v) v.begin(), v.end()
#define dbg(x) cerr << #x << " is " << x << "\\n";

using ll = long long;
using ii = pair<ll, ll>;

const int S = 2005;
const int N = 670;
const int MOD = 1e9 + 7;

ll dp[N][S];
int main() {
  int s;
  scanf("%d", &s);
  dp[0][0] = 1;
  for (int i = 1; i < N; i++) {
    for (int j = 3; j <= s; j++) {
      // dp[i][j] = dp[i - 1][j - 3] + dp[i - 1][j - 4] + ... + dp[i - 1][0]
      // dp[i][j - 1] = dp[i - 1][j - 4] + dp[i - 1][j - 5] + ... + dp[i - 1][0]
      // dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 3];

      dp[i][j] = dp[i][j - 1] + dp[i - 1][j - 3];
      if (dp[i][j] >= MOD)
        dp[i][j] -= MOD;

      // for(int k = 3; k <= j; k++) {
      //   dp[i][j] += dp[i - 1][j - k];
      //   if(dp[i][j] >= MOD) dp[i][j] -= MOD;
      // }
    }
  }
  ll ans = 0;
  for (int i = 0; i < N; i++) {
    ans += dp[i][s];
    if (ans >= MOD)
      ans -= MOD;
  }
  printf("%lld\\n", ans);
  return 0;
}


#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;
  vector<long> dp(N + 1, 0);
  dp.at(1) = 0;
  dp.at(2) = 0;
  dp.at(3) = 1;
  dp.at(4) = 1;
  dp.at(5) = 1;
  for (int i = 6; i <= N; i++) {
    // int l=i/2;
    for (int j = 3; j <= i - 3; j++) {
      dp.at(i) += dp.at(i - j);
      dp.at(i) %= 1000000007;
    }
    dp.at(i)++;
  }
  cout << dp.at(N) << endl;
}

#include <bits/stdc++.h>
using namespace std;

int main() {
  int N;
  cin >> N;
  vector<long> dp(N + 1, 0);
  for (int i = 3; i <= N; i++) {
    // int l=i/2;
    for (int j = 3; j <= i - 3; j++) {
      dp.at(i) += dp.at(i - j);
      dp.at(i) %= 1000000007;
    }
    dp.at(i)++;
  }
  cout << dp.at(N) << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
using ll = long long;

static const ll Max = 2005;

ll DP[Max];

void init() {
  for (ll i = 0; i < Max; i++)
    DP[i] = -1;
}
ll Inf = 1e9 + 7;

ll factorial(int n) {
  if (DP[n] != -1)
    return DP[n];
  if (n == 0)
    return DP[n] = 1;
  if (n == 1)
    return DP[n] = 1;
  DP[n] = factorial(n - 1) * (ll)n;
  return DP[n];
}

int main() {
  init();
  int s;
  cin >> s;
  ll ans = 0;

  for (int i = 1; i <= (s / 3); i++) {
    ans += factorial(s - 2 * i - 1) / (factorial(s - 3 * i) * factorial(i - 1));
    ans %= Inf;
  }
  cout << ans << endl;
  return 0;
}

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; i++)
#define repl(i, l, r) for (int i = l; i < r; i++)
using namespace std;
using ll = long long;
static const ll MOD = 1e9 + 7;
static const int inf = 1e9 + 10;
static const ll INF = 4e18 + 10;
const int dx[9] = {1, 0, -1, 0, 1, -1, -1, 1, 0};
const int dy[9] = {0, 1, 0, -1, 1, 1, -1, -1, 0};

const int Max = 2005;
int A[Max];

int solve(int n) {
  if (A[n] != -1)
    return A[n];
  if (n == 0)
    return A[n] = 1;
  if (n < 3)
    return A[n] = 0;
  if (n == 3)
    return A[n] = 1;
  A[n] = solve(n - 3) + solve(n - 1);
  A[n] %= MOD;
  return A[n];
}

int main() {
  rep(i, Max) A[i] = -1;
  int n;
  cin >> n;
  cout << solve(n) << endl;
  return 0;
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define ENDL '\\n'
#define sz(a) (int)(a.size())
#define all(a) begin(a), end(a)
#define deb(a) cout << #a << ": " << a << ENDL
#define fore(i, a, b) for (int i(a), ThkMk(b); i < ThkMk; ++i)
#define _                                                                      \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(0);                                                                  \\
  cout.tie(0);

using namespace std;

typedef long long lli;
typedef long double ld;
typedef pair<lli, lli> ii;
typedef vector<lli> vi;

const int MAX = 2005;

lli dp[MAX][MAX];

lli n;

lli MOD = 1e9 + 7;

lli solve(lli u, lli v) {
  if (v < 0)
    return 0;
  if (v == 0)
    return 1;
  lli &ans = dp[u][v];
  if (ans != -1)
    return ans;
  ans = 0;
  fore(i, 3, v + 1) ans = (ans + solve(u + 1, v - i)) % MOD;
  return ans;
}

int main() {
  _ fore(i, 0, MAX) fore(j, 0, MAX) dp[i][j] = -1;
  cin >> n;
  cout << solve(0, n) << ENDL;
  return 0;
}

#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define ENDL '\\n'
#define sz(a) (int)(a.size())
#define all(a) begin(a), end(a)
#define deb(a) cout << #a << ": " << a << ENDL
#define fore(i, a, b) for (int i(a), ThkMk(b); i < ThkMk; ++i)
#define _                                                                      \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(0);                                                                  \\
  cout.tie(0);

using namespace std;

typedef long long lli;
typedef long double ld;
typedef pair<lli, lli> ii;
typedef vector<lli> vi;

const int MAX = 2005;

lli dp[MAX];

lli n;

lli MOD = 1e9 + 7;

lli solve(lli v) {
  if (v < 0)
    return 0;
  if (v == 0)
    return 1;
  lli &ans = dp[v];
  if (ans != -1)
    return ans;
  ans = 0;
  fore(i, 3, v + 1) ans = (ans + solve(v - i)) % MOD;
  return ans;
}

int main() {
  _ fore(j, 0, MAX) dp[j] = -1;
  cin >> n;
  cout << solve(n) << ENDL;
  return 0;
}


#include <bits/stdc++.h>

using namespace std;
using ll = long long;
using vl = vector<ll>;
using pll = pair<ll, ll>;

#define rep(i, n) for (ll i = 0, xxx_rep_end = (n); i < xxx_rep_end; ++i)
#define all(x) (x).begin(), (x).end()

template <class T1, class T2> inline bool chmax(T1 &a, const T2 &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T1, class T2> inline bool chmin(T1 &a, const T2 &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

constexpr ll INF = 0x3f3f3f3f3f3f3f3fLL;
constexpr ll mod = 1000000007;

int main() {
  ll S;
  cin >> S;
  vector<ll> vec(S + 1);
  vec[0] = 0;
  vec[1] = 0;
  vec[2] = 0;
  vec[3] = 1;
  vec[4] = 1;
  vec[5] = 1;
  for (int i = 6; i <= S; ++i) {
    ll tmp = 1;
    for (int j = 3; j <= i - 3; ++j) {
      tmp += vec[j];
      tmp %= mod;
    }
    vec[i] = tmp;
  }

  cout << vec[S] << endl;
}

#include <bits/stdc++.h>

using namespace std;
using ll = long long;
using vl = vector<ll>;
using pll = pair<ll, ll>;

#define rep(i, n) for (ll i = 0, xxx_rep_end = (n); i < xxx_rep_end; ++i)
#define all(x) (x).begin(), (x).end()

template <class T1, class T2> inline bool chmax(T1 &a, const T2 &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T1, class T2> inline bool chmin(T1 &a, const T2 &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

constexpr ll INF = 0x3f3f3f3f3f3f3f3fLL;
constexpr ll mod = 1000000007;

int main() {
  ll S;
  cin >> S;
  vector<ll> vec(2001);
  vec[0] = 0;
  vec[1] = 0;
  vec[2] = 0;
  vec[3] = 1;
  vec[4] = 1;
  vec[5] = 1;
  for (int i = 6; i <= S; ++i) {
    ll tmp = 1;
    for (int j = 3; j <= i - 3; ++j) {
      tmp += vec[j];
      tmp %= mod;
    }
    vec[i] = tmp;
  }

  cout << vec[S] << endl;
}


#include <bits/stdc++.h>
#include <math.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
const ll mod = 1000000007;
const ll INF = 1001001001;
const ll LINF = 1001001001001001001;

vector<ll> ans(2001, INF);

ll f(ll x) {
  if (ans.at(x) != INF)
    return ans.at(x);
  if (x < 3) {
    ans.at(x) = 0;
    return 0;
  }
  ll ret = 0;
  for (int i = 3; i <= x; i++) {
    ret += f(x - i);
  }
  return ret;
}

int main() {
  ans.at(0) = 1;
  ll s;
  cin >> s;
  cout << f(s) << endl;
}

#include <bits/stdc++.h>
#include <math.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
const ll mod = 1000000007;
const ll INF = 1001001001;
const ll LINF = 1001001001001001001;

vector<ll> ans(2001, 0);

int main() {
  ans.at(0) = 1;
  ll s;
  cin >> s;
  for (int i = 3; i <= s; i++) {
    ll x = 0;
    for (int j = 0; j <= i - 3; j++) {
      x = (x + ans.at(j)) % mod;
    }
    ans.at(i) = x;
  }
  cout << ans.at(s) << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
int dp[2001][2001];
long long mod = 1000000007;
int factorial(int n) {
  if (n <= 1)
    return 1;
  long long fact = 1;
  for (int i = 2; i <= n; i++) {
    fact = (fact * (long long)i);
    fact %= mod;
  }
  return fact;
}
int countSequence(int arr[], int n, int sum, vector<int> output) {
  if (sum == 0) {
    int len = output.size();
    map<int, int> m;
    int ans = factorial(len);
    for (int i = 0; i < output.size(); i++)
      m[output[i]]++;
    long long mult = 1;
    for (auto it : m) {
      int a = factorial(it.second);
      mult = (mult * a) % mod;
    }
    ans = (ans / mult) % mod;
    return ans;
  }
  if (n == 0 and sum > 0)
    return 0;
  if (dp[n][sum] != -1)
    return dp[n][sum];
  int ans;
  if (arr[0] > sum)
    ans = countSequence(arr + 1, n - 1, sum, output);
  else {
    int c1 = countSequence(arr + 1, n - 1, sum, output);
    vector<int> out = output;
    out.push_back(arr[0]);
    int c2 = countSequence(arr, n, sum - arr[0], out);
    ans = c1 + c2;
  }
  ans %= mod;
  dp[n][sum] = ans;
  return ans;
}
int main() {
  int s;
  cin >> s;
  int size = s - 3 + 1;
  int arr[size];
  int start = 3;
  for (int i = 0; i < size; i++) {
    arr[i] = start;
    start++;
  }

  vector<int> output;
  memset(dp, -1, sizeof(dp));
  int ans = countSequence(arr, size, s, output);
  cout << ans;
}

#include <bits/stdc++.h>
#define ll long long
using namespace std;
long long mod = 1000000007;

int countSequence(int sum) {
  ll dp[2001];
  dp[0] = 1;
  dp[1] = 0;
  dp[2] = 0;
  dp[3] = 1;
  for (int i = 4; i <= sum; i++) {
    ll total = 0;
    for (int j = 3; j <= i; j++) {
      total = (total + dp[i - j]) % mod;
    }
    dp[i] = total;
  }
  return dp[sum];
}
int main() {
  int s;
  cin >> s;
  int size = s - 3 + 1;
  int arr[size];
  int start = 3;
  for (int i = 0; i < size; i++) {
    arr[i] = start;
    start++;
  }

  int ans = countSequence(s);
  cout << ans;
}


#define MOD 1000000007

#if 1
//------------------------------------------------------------
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;

template <class T> struct Entry {
  static void Run() { T().Run(); }
};
struct MyMain;

#if defined(TEST)
#include "test.hpp"
extern istream &mis;
extern ostream &mos;
#else
istream &mis = cin;
ostream &mos = cout;
signed main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cout << fixed << setprecision(16);
  Entry<MyMain>::Run();
  return 0;
}
#endif

//------------------------------------------------------------
using ll = long long;
#define int ll

#define FOR(i, s, e) for (ll i = ll(s); i < ll(e); ++i)
#define RFOR(i, s, e) for (ll i = ll(e) - 1; i >= ll(s); --i)
#define REP(i, n) for (ll i = 0, i##_size = ll(n); i < i##_size; ++i)
#define RREP(i, n) for (ll i = ll(n) - 1; i >= 0; --i)

#define INF INT64_MAX

//------------------------------------------------------------
template <class T> struct arr : public vector<T> {
  arr() {}
  arr(initializer_list<T> il) : vector<T>(il) {}
  explicit arr(ll n, T v = T()) : vector<T>(n, v) {}

  T &operator()(int i) { return (*this)[i]; }
  T const &operator()(int i) const { return (*this)[i]; }
  void init(ll n, T v = T()) {
    this->clear();
    this->resize(n, v);
  }
  ll sz() const { return (ll)this->size(); }
  void pb(T v) { this->push_back(v); }
  void sort() { std::sort(this->begin(), this->end()); }
  void sort(function<bool(T, T)> p) {
    std::sort(this->begin(), this->end(), p);
  }
  void rsort() { std::sort(this->begin(), this->end(), greater<T>()); }
  void reverse() { std::reverse(this->begin(), this->end()); }
  void unique_erase() {
    this->erase(std::unique(this->begin(), this->end()), this->end());
  }
  bool next_permutation() {
    return std::next_permutation(this->begin(), this->end());
  }

  // これ以下はソート済み前提
  int lower_bound(T const &v, function<bool(T, T)> p) {
    return std::lower_bound(this->begin(), this->end(), v, p) - this->begin();
  }
  int lower_bound(T const &v) {
    return std::lower_bound(this->begin(), this->end(), v) - this->begin();
  }

  int upper_bound(T const &v, function<bool(T, T)> p) {
    return std::upper_bound(this->begin(), this->end(), v, p) - this->begin();
  }
  int upper_bound(T const &v) {
    return std::upper_bound(this->begin(), this->end(), v) - this->begin();
  }

  int find_nearest(T const &v) {
    int i = this->lower_bound(v);
    if (i >= sz()) {
      --i;
    } else if ((*this)[i] != v) {
      int p = i - 1;
      if (p >= 0) {
        int id = abs((*this)[i] - v);
        int pd = abs((*this)[p] - v);
        if (pd < id) {
          i = p;
        }
      }
    }
    return i;
  }

  // 見つからなければ-1
  int find(T const &v) {
    int i = this->lower_bound(v);
    if (i >= sz()) {
      return -1;
    }
    if ((*this)[i] != v) {
      return -1;
    }
    return i;
  }
};
using ints = arr<ll>;

template <class T> struct que : public queue<T> {
  ll sz() const { return (ll)this->size(); }
  T popfront() {
    T v = this->front();
    this->pop();
    return v;
  }
};

template <class A, class B> struct pr {
  union {
    A a;
    A key;
    A first;
    A x;
  };
  union {
    B b;
    B value;
    B second;
    B y;
  };

  pr() : a(A()), b(B()){};
  pr(A a_, B b_) : a(a_), b(b_) {}
  pr(pr const &r) : a(r.a), b(r.b){};
  pr(pair<A, B> const &r) : a(r.first), b(r.second){};

  bool operator==(pr const &r) const { return a == r.a && b == r.b; }
  bool operator!=(pr const &r) const { return !((*this) == r); }
  bool operator<(pr const &r) const {
    if (a == r.a) {
      return b < r.b;
    }
    return a < r.a;
  }

  pr operator+(pr v) const { return pr(x, y) += v; }
  pr operator-(pr v) const { return pr(x, y) -= v; }

  pr &operator+=(pr v) {
    x += v.x;
    y += v.y;
    return *this;
  }
  pr &operator-=(pr v) {
    x -= v.x;
    y -= v.y;
    return *this;
  }

  void flip() { swap(x, y); }

  friend istream &operator>>(istream &is, pr &p) {
    is >> p.a >> p.b;
    return is;
  }
  friend ostream &operator<<(ostream &os, pr const &p) {
    os << p.a << " " << p.b;
    return os;
  }
};
using pint = pr<ll, ll>;
using pints = arr<pint>;

template <class A, class B, class C> struct tr {
  union {
    A a;
    A first;
    A x;
  };
  union {
    B b;
    B second;
    B y;
  };
  union {
    C c;
    C third;
    C z;
  };

  tr() : a(A()), b(B()), c(C()){};
  tr(A a_, B b_, C c_) : a(a_), b(b_), c(c_) {}
  tr(tr const &r) : a(r.a), b(r.b), c(r.c){};

  bool operator==(tr const &r) const {
    return a == r.a && b == r.b && c == r.c;
  }
  bool operator!=(tr const &r) const { return !((*this) == r); }
  bool operator<(tr const &r) const {
    if (a == r.a) {
      if (b == r.b) {
        return c < r.c;
      }
      return b < r.b;
    }
    return a < r.a;
  }

  tr operator+(tr v) const { return tr(x, y, z) += v; }
  tr operator-(tr v) const { return tr(x, y, z) -= v; }

  tr &operator+=(tr v) {
    x += v.x;
    y += v.y;
    z += v.z;
    return *this;
  }
  tr &operator-=(tr v) {
    x -= v.x;
    y -= v.y;
    z -= v.z;
    return *this;
  }

  friend istream &operator>>(istream &is, tr &p) {
    is >> p.a >> p.b >> p.c;
    return is;
  }
  friend ostream &operator<<(ostream &os, tr const &p) {
    os << p.a << " " << p.b << " " << p.c;
    return os;
  }
};
using tint = tr<ll, ll, ll>;
using tints = arr<tint>;

template <class K, class V> struct dic : public map<K, V> {
  bool get(K const &k, V *v) {
    auto it = this->find(k);
    if (it != this->end()) {
      *v = it->second;
      return true;
    }
    return false;
  }
};

template <class T> struct arr2 {
  vector<vector<T>> m_vec;
  int m_width;
  int m_height;

  arr2() : m_width(0), m_height(0) {}
  arr2(int w, int h, T const &value = T()) : m_width(w), m_height(h) {
    m_vec.resize(h, vector<T>(w, value));
  }
  arr2(arr2 const &r) {
    m_vec = r.m_vec;
    m_width = r.m_width;
    m_height = r.m_height;
  }
  arr2(arr2 &&r) {
    m_vec = move(r.m_vec);
    m_width = r.m_width;
    m_height = r.m_height;
  }
  arr2 &operator=(arr2 const &r) {
    m_vec = r.m_vec;
    m_width = r.m_width;
    m_height = r.m_height;
    return *this;
  }
  arr2 &operator=(arr2 &&r) {
    m_vec = move(r.m_vec);
    m_width = r.m_width;
    m_height = r.m_height;
    return *this;
  }

  bool operator==(arr2 const &r) const { return m_vec = r.m_vec; }

  bool operator<(arr2 const &r) const {
    if (m_width != r.m_width) {
      return m_width < r.m_width;
    }
    if (m_height != r.m_height) {
      return m_height < r.m_height;
    }
    REP(y, m_height) {
      REP(x, m_width) {
        if ((*this)(x, y) != r(x, y)) {
          return (*this)(x, y) < r(x, y);
        }
      }
    }
    return false;
  }

  pint size() const { return pint(m_width, m_height); }
  int width() const { return m_width; }
  int height() const { return m_height; }

  void init(int w, int h, T const &value = T()) {
    m_vec.clear();
    m_vec.resize(h, vector<T>(w, value));
    m_width = w;
    m_height = h;
  }
  void init(pint size, T const &value = T()) { init(size.x, size.y, value); }
  T &operator()(int x, int y) { return m_vec[y][x]; }
  T const &operator()(int x, int y) const { return m_vec[y][x]; }

  T &operator()(pint p) { return m_vec[p.y][p.x]; }
  T const &operator()(pint p) const { return m_vec[p.y][p.x]; }

  T &operator[](pint p) { return m_vec[p.y][p.x]; }
  T const &operator[](pint p) const { return m_vec[p.y][p.x]; }

  bool isIn(int x, int y) const {
    return x >= 0 && x < m_width && y >= 0 && y < m_height;
  }
  bool isIn(pint p) const { return isIn(p.x, p.y); }
  bool isOut(int x, int y) const {
    return x < 0 || x >= m_width || y < 0 || y >= m_height;
  }
  bool isOut(pint p) const { return isOut(p.x, p.y); }

  struct iterator {
  private:
    arr2<T> *owner;

  public:
    pint pt;

    iterator(arr2<T> *owner_, pint pt_) : owner(owner_), pt(pt_) {}

    bool operator==(iterator const &r) const { return pt == r.pt; }
    bool operator!=(iterator const &r) const { return !((*this) == r); }
    void operator++() {
      ++pt.x;
      if (pt.x >= owner->width()) {
        ++pt.y;
        pt.x = 0;
      }
    }
    T &operator*() { return (*owner)(pt); }
  };
  iterator begin() { return iterator(this, pint(0, 0)); }
  iterator end() { return iterator(this, pint(0, height())); }

  void disp(ostream &os) {
    REP(y, m_height) {
      REP(x, m_width) { os << setw(2) << (*this)(x, y) << " "; }
      os << endl;
    }
    os << endl;
  }
};

const pints around4 = {pint(-1, 0), pint(0, -1), pint(1, 0), pint(0, 1)};

//------------------------------------------------------------
template <class T> void chmin(T &a, T b) {
  if (b < a) {
    a = b;
  }
}
template <class T> void chmax(T &a, T b) {
  if (b > a) {
    a = b;
  }
}

constexpr int gcd(int a, int b) {
  if (a < 0) {
    a = -a;
  }
  if (b < 0) {
    b = -b;
  }
  if (a == 0) {
    return b;
  }
  if (b == 0) {
    return a;
  }

  while (int c = a % b) {
    a = b;
    b = c;
  }
  return b;
}

constexpr int lcm(int a, int b) { return a / gcd(a, b) * b; }

//------------------------------------------------------------
template <int M> struct modint {
  int raw;

  modint() { raw = 0; }
  modint(int v) {
    if (v < 0) {
      raw = (v % M) + M;
    } else if (v >= M) {
      raw = v % M;
    } else {
      raw = v;
    }
  }
  modint operator+(modint v) const { return modint(raw) += v; }
  modint operator-(modint v) const { return modint(raw) -= v; }
  modint operator*(modint v) const { return modint(raw) *= v; }

  modint &operator+=(modint v) {
    raw += v.raw;
    if (raw >= M) {
      raw -= M;
    }
    return *this;
  }
  modint &operator-=(modint v) {
    raw -= v.raw;
    if (raw < 0) {
      raw += M;
    }
    return *this;
  }
  modint &operator*=(modint v) {
    raw = (raw * v.raw) % M;
    return *this;
  }
  modint pow(int n) const { return modint::pow(raw, n); }
  static modint pow(int a, int n) {
    if (n < 0) {
      // not support
      abort();
    }

    int r = 1;
    while (n) {
      if (n & 1) {
        r = (r * a) % M;
      }
      a = (a * a) % M;
      n >>= 1;
    }
    return modint(r);
  }

  modint inv() const {
    int a = raw;
    int b = M;
    int u = 1;
    int v = 0;
    while (b) {
      int t = a / b;
      a -= t * b;
      u -= t * v;
      swap(a, b);
      swap(u, v);
    }
    u %= M;
    if (u < 0) {
      u += M;
    }
    return u;
  }

  friend istream &operator>>(istream &is, modint &m) {
    int v;
    is >> v;
    m = modint(v);
    return is;
  }
  friend ostream &operator<<(ostream &os, modint const &m) {
    return os << m.raw;
  }
};
using mint = modint<MOD>;
using mints = arr<mint>;

//------------------------------------------------------------

struct OutputStream {
  template <class T>
  friend OutputStream &operator<<(OutputStream &s, T const &v) {
    mos << v << '\\n';
    return s;
  }
} out;

struct PrintStream {
  stringstream ss;

  template <class T> friend PrintStream &operator<<(PrintStream &s, T &&v) {
    s.ss << v << ' ';
    return s;
  }

  PrintStream &operator<<(PrintStream &(*manip)(PrintStream &)) {
    return (*manip)(*this);
  }
} prn;

PrintStream &endl(PrintStream &s) {
  string str = s.ss.str();
  s.ss = stringstream();
  if (str.empty() == false) {
    str.pop_back();
  }
  mos << str << '\\n';
  return s;
}

//------------------------------------------------------------
template <class T> void input(T &value) { mis >> value; }
void input(int &value, int add) {
  mis >> value;
  value += add;
}
template <class A, class B> void input(pr<A, B> &value) {
  mis >> value.a >> value.b;
}
template <class A, class B> void input(pr<A, B> &value, int addA, int addB) {
  mis >> value.a >> value.b;
  value.a += addA;
  value.b += addB;
}
template <class A, class B, class C> void input(tr<A, B, C> &value) {
  mis >> value.a >> value.b >> value.c;
}
template <class A, class B, class C>
void input(tr<A, B, C> &value, int addA, int addB, int addC) {
  mis >> value.a >> value.b >> value.c;
  value.a += addA;
  value.b += addB;
  value.c += addC;
}
template <class T, class... ARGS>
void input(arr<T> &value, int N, ARGS &&...args) {
  value.init(N);
  REP(i, N) { input(value[i], forward<ARGS>(args)...); }
}
template <class T, class... ARGS>
void input(arr2<T> &value, int H, int W, ARGS &&...args) {
  value.init(W, H);
  REP(y, H) {
    REP(x, W) { input(value(x, y), forward<ARGS>(args)...); }
  }
}
template <class K, class V, class... ARGS>
void input(dic<K, V> &value, int N, ARGS &&...args) {
  REP(i, N) {
    pair<K, V> pr;
    input(pr.first);
    input(pr.second, forward<ARGS>(args)...);
    value.insert(pr);
  }
}

template <class T> struct inputHolder {
  T value;
  template <class... ARGS> inputHolder(ARGS &&...args) {
    input(value, forward<ARGS>(args)...);
  }
  operator T() { return value; }
};

template <class T, class Tuple, size_t... Index>
T MakeFromTupleImpl(Tuple &&t, index_sequence<Index...>) {
  return T(get<Index>(forward<Tuple>(t))...);
}
template <class T, class Tuple> T MakeFromTuple(Tuple &&t) {
  return MakeFromTupleImpl<T>(
      forward<Tuple>(t),
      make_index_sequence<tuple_size<remove_reference_t<Tuple>>::value>{});
}
template <class... ARGS> struct inputWithParam {
  tuple<ARGS...> param;
  inputWithParam() {}
  explicit inputWithParam(tuple<ARGS...> &&param_) : param(param_) {}
  operator int() { return MakeFromTuple<inputHolder<int>>(param); }
  operator double() { return MakeFromTuple<inputHolder<double>>(param); }
  operator string() { return MakeFromTuple<inputHolder<string>>(param); }
  operator char() { return MakeFromTuple<inputHolder<char>>(param); }
  template <class A, class B> operator pr<A, B>() {
    return MakeFromTuple<inputHolder<pr<A, B>>>(param);
  }
  template <class A, class B, class C> operator tr<A, B, C>() {
    return MakeFromTuple<inputHolder<tr<A, B, C>>>(param);
  }
  template <class T> operator arr<T>() {
    return MakeFromTuple<inputHolder<arr<T>>>(param);
  }
  template <class A, class B> operator dic<A, B>() {
    return MakeFromTuple<inputHolder<dic<A, B>>>(param);
  }
  template <class T> operator arr2<T>() {
    return MakeFromTuple<inputHolder<arr2<T>>>(param);
  }
};
struct inputObject {
  operator int() { return inputWithParam<>(); }
  operator double() { return inputWithParam<>(); }
  operator string() { return inputWithParam<>(); }
  operator char() { return inputWithParam<>(); }
  template <class A, class B> operator pr<A, B>() { return inputWithParam<>(); }
  template <class A, class B, class C> operator tr<A, B, C>() {
    return inputWithParam<>();
  }
  template <class... ARGS> inputWithParam<ARGS...> operator()(ARGS &&...args) {
    inputWithParam<ARGS...> withParam(forward_as_tuple(args...));
    return withParam;
  }
} in;

//------------------------------------------------------------
#endif

struct MyMain {
  int S = in;

  void Run() {
    arr2<mint> dp(S + 1, S + 1);
    dp(0, S) = 1;
    FOR(x, 1, (S / 3) + 3) {
      REP(by, S + 1) {
        FOR(cy, 3, S + 1) {
          mint count = dp(x - 1, by);
          int y = by - cy;
          if (y < 0) {
            continue;
          }
          dp(x, y) += count;
        }
      }
    }

    mint ans = 0;
    FOR(x, 1, S + 1) { ans += dp(x, 0); }

    out << ans;
  }
};

#define MOD 1000000007

#if 1
//------------------------------------------------------------
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;

template <class T> struct Entry {
  static void Run() { T().Run(); }
};
struct MyMain;

#if defined(TEST)
#include "test.hpp"
extern istream &mis;
extern ostream &mos;
#else
istream &mis = cin;
ostream &mos = cout;
signed main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cout << fixed << setprecision(16);
  Entry<MyMain>::Run();
  return 0;
}
#endif

//------------------------------------------------------------
using ll = long long;
#define int ll

#define FOR(i, s, e) for (ll i = ll(s); i < ll(e); ++i)
#define RFOR(i, s, e) for (ll i = ll(e) - 1; i >= ll(s); --i)
#define REP(i, n) for (ll i = 0, i##_size = ll(n); i < i##_size; ++i)
#define RREP(i, n) for (ll i = ll(n) - 1; i >= 0; --i)

#define INF INT64_MAX

//------------------------------------------------------------
template <class T> struct arr : public vector<T> {
  arr() {}
  arr(initializer_list<T> il) : vector<T>(il) {}
  explicit arr(ll n, T v = T()) : vector<T>(n, v) {}

  T &operator()(int i) { return (*this)[i]; }
  T const &operator()(int i) const { return (*this)[i]; }
  void init(ll n, T v = T()) {
    this->clear();
    this->resize(n, v);
  }
  ll sz() const { return (ll)this->size(); }
  void pb(T v) { this->push_back(v); }
  void sort() { std::sort(this->begin(), this->end()); }
  void sort(function<bool(T, T)> p) {
    std::sort(this->begin(), this->end(), p);
  }
  void rsort() { std::sort(this->begin(), this->end(), greater<T>()); }
  void reverse() { std::reverse(this->begin(), this->end()); }
  void unique_erase() {
    this->erase(std::unique(this->begin(), this->end()), this->end());
  }
  bool next_permutation() {
    return std::next_permutation(this->begin(), this->end());
  }

  // これ以下はソート済み前提
  int lower_bound(T const &v, function<bool(T, T)> p) {
    return std::lower_bound(this->begin(), this->end(), v, p) - this->begin();
  }
  int lower_bound(T const &v) {
    return std::lower_bound(this->begin(), this->end(), v) - this->begin();
  }

  int upper_bound(T const &v, function<bool(T, T)> p) {
    return std::upper_bound(this->begin(), this->end(), v, p) - this->begin();
  }
  int upper_bound(T const &v) {
    return std::upper_bound(this->begin(), this->end(), v) - this->begin();
  }

  int find_nearest(T const &v) {
    int i = this->lower_bound(v);
    if (i >= sz()) {
      --i;
    } else if ((*this)[i] != v) {
      int p = i - 1;
      if (p >= 0) {
        int id = abs((*this)[i] - v);
        int pd = abs((*this)[p] - v);
        if (pd < id) {
          i = p;
        }
      }
    }
    return i;
  }

  // 見つからなければ-1
  int find(T const &v) {
    int i = this->lower_bound(v);
    if (i >= sz()) {
      return -1;
    }
    if ((*this)[i] != v) {
      return -1;
    }
    return i;
  }
};
using ints = arr<ll>;

template <class T> struct que : public queue<T> {
  ll sz() const { return (ll)this->size(); }
  T popfront() {
    T v = this->front();
    this->pop();
    return v;
  }
};

template <class A, class B> struct pr {
  union {
    A a;
    A key;
    A first;
    A x;
  };
  union {
    B b;
    B value;
    B second;
    B y;
  };

  pr() : a(A()), b(B()){};
  pr(A a_, B b_) : a(a_), b(b_) {}
  pr(pr const &r) : a(r.a), b(r.b){};
  pr(pair<A, B> const &r) : a(r.first), b(r.second){};

  bool operator==(pr const &r) const { return a == r.a && b == r.b; }
  bool operator!=(pr const &r) const { return !((*this) == r); }
  bool operator<(pr const &r) const {
    if (a == r.a) {
      return b < r.b;
    }
    return a < r.a;
  }

  pr operator+(pr v) const { return pr(x, y) += v; }
  pr operator-(pr v) const { return pr(x, y) -= v; }

  pr &operator+=(pr v) {
    x += v.x;
    y += v.y;
    return *this;
  }
  pr &operator-=(pr v) {
    x -= v.x;
    y -= v.y;
    return *this;
  }

  void flip() { swap(x, y); }

  friend istream &operator>>(istream &is, pr &p) {
    is >> p.a >> p.b;
    return is;
  }
  friend ostream &operator<<(ostream &os, pr const &p) {
    os << p.a << " " << p.b;
    return os;
  }
};
using pint = pr<ll, ll>;
using pints = arr<pint>;

template <class A, class B, class C> struct tr {
  union {
    A a;
    A first;
    A x;
  };
  union {
    B b;
    B second;
    B y;
  };
  union {
    C c;
    C third;
    C z;
  };

  tr() : a(A()), b(B()), c(C()){};
  tr(A a_, B b_, C c_) : a(a_), b(b_), c(c_) {}
  tr(tr const &r) : a(r.a), b(r.b), c(r.c){};

  bool operator==(tr const &r) const {
    return a == r.a && b == r.b && c == r.c;
  }
  bool operator!=(tr const &r) const { return !((*this) == r); }
  bool operator<(tr const &r) const {
    if (a == r.a) {
      if (b == r.b) {
        return c < r.c;
      }
      return b < r.b;
    }
    return a < r.a;
  }

  tr operator+(tr v) const { return tr(x, y, z) += v; }
  tr operator-(tr v) const { return tr(x, y, z) -= v; }

  tr &operator+=(tr v) {
    x += v.x;
    y += v.y;
    z += v.z;
    return *this;
  }
  tr &operator-=(tr v) {
    x -= v.x;
    y -= v.y;
    z -= v.z;
    return *this;
  }

  friend istream &operator>>(istream &is, tr &p) {
    is >> p.a >> p.b >> p.c;
    return is;
  }
  friend ostream &operator<<(ostream &os, tr const &p) {
    os << p.a << " " << p.b << " " << p.c;
    return os;
  }
};
using tint = tr<ll, ll, ll>;
using tints = arr<tint>;

template <class K, class V> struct dic : public map<K, V> {
  bool get(K const &k, V *v) {
    auto it = this->find(k);
    if (it != this->end()) {
      *v = it->second;
      return true;
    }
    return false;
  }
};

template <class T> struct arr2 {
  vector<vector<T>> m_vec;
  int m_width;
  int m_height;

  arr2() : m_width(0), m_height(0) {}
  arr2(int w, int h, T const &value = T()) : m_width(w), m_height(h) {
    m_vec.resize(h, vector<T>(w, value));
  }
  arr2(arr2 const &r) {
    m_vec = r.m_vec;
    m_width = r.m_width;
    m_height = r.m_height;
  }
  arr2(arr2 &&r) {
    m_vec = move(r.m_vec);
    m_width = r.m_width;
    m_height = r.m_height;
  }
  arr2 &operator=(arr2 const &r) {
    m_vec = r.m_vec;
    m_width = r.m_width;
    m_height = r.m_height;
    return *this;
  }
  arr2 &operator=(arr2 &&r) {
    m_vec = move(r.m_vec);
    m_width = r.m_width;
    m_height = r.m_height;
    return *this;
  }

  bool operator==(arr2 const &r) const { return m_vec = r.m_vec; }

  bool operator<(arr2 const &r) const {
    if (m_width != r.m_width) {
      return m_width < r.m_width;
    }
    if (m_height != r.m_height) {
      return m_height < r.m_height;
    }
    REP(y, m_height) {
      REP(x, m_width) {
        if ((*this)(x, y) != r(x, y)) {
          return (*this)(x, y) < r(x, y);
        }
      }
    }
    return false;
  }

  pint size() const { return pint(m_width, m_height); }
  int width() const { return m_width; }
  int height() const { return m_height; }

  void init(int w, int h, T const &value = T()) {
    m_vec.clear();
    m_vec.resize(h, vector<T>(w, value));
    m_width = w;
    m_height = h;
  }
  void init(pint size, T const &value = T()) { init(size.x, size.y, value); }
  T &operator()(int x, int y) { return m_vec[y][x]; }
  T const &operator()(int x, int y) const { return m_vec[y][x]; }

  T &operator()(pint p) { return m_vec[p.y][p.x]; }
  T const &operator()(pint p) const { return m_vec[p.y][p.x]; }

  T &operator[](pint p) { return m_vec[p.y][p.x]; }
  T const &operator[](pint p) const { return m_vec[p.y][p.x]; }

  bool isIn(int x, int y) const {
    return x >= 0 && x < m_width && y >= 0 && y < m_height;
  }
  bool isIn(pint p) const { return isIn(p.x, p.y); }
  bool isOut(int x, int y) const {
    return x < 0 || x >= m_width || y < 0 || y >= m_height;
  }
  bool isOut(pint p) const { return isOut(p.x, p.y); }

  struct iterator {
  private:
    arr2<T> *owner;

  public:
    pint pt;

    iterator(arr2<T> *owner_, pint pt_) : owner(owner_), pt(pt_) {}

    bool operator==(iterator const &r) const { return pt == r.pt; }
    bool operator!=(iterator const &r) const { return !((*this) == r); }
    void operator++() {
      ++pt.x;
      if (pt.x >= owner->width()) {
        ++pt.y;
        pt.x = 0;
      }
    }
    T &operator*() { return (*owner)(pt); }
  };
  iterator begin() { return iterator(this, pint(0, 0)); }
  iterator end() { return iterator(this, pint(0, height())); }

  void disp(ostream &os) {
    REP(y, m_height) {
      REP(x, m_width) { os << setw(2) << (*this)(x, y) << " "; }
      os << endl;
    }
    os << endl;
  }
};

const pints around4 = {pint(-1, 0), pint(0, -1), pint(1, 0), pint(0, 1)};

//------------------------------------------------------------
template <class T> void chmin(T &a, T b) {
  if (b < a) {
    a = b;
  }
}
template <class T> void chmax(T &a, T b) {
  if (b > a) {
    a = b;
  }
}

constexpr int gcd(int a, int b) {
  if (a < 0) {
    a = -a;
  }
  if (b < 0) {
    b = -b;
  }
  if (a == 0) {
    return b;
  }
  if (b == 0) {
    return a;
  }

  while (int c = a % b) {
    a = b;
    b = c;
  }
  return b;
}

constexpr int lcm(int a, int b) { return a / gcd(a, b) * b; }

//------------------------------------------------------------
template <int M> struct modint {
  int raw;

  modint() { raw = 0; }
  modint(int v) {
    if (v < 0) {
      raw = (v % M) + M;
    } else if (v >= M) {
      raw = v % M;
    } else {
      raw = v;
    }
  }
  modint operator+(modint v) const { return modint(raw) += v; }
  modint operator-(modint v) const { return modint(raw) -= v; }
  modint operator*(modint v) const { return modint(raw) *= v; }

  modint &operator+=(modint v) {
    raw += v.raw;
    if (raw >= M) {
      raw -= M;
    }
    return *this;
  }
  modint &operator-=(modint v) {
    raw -= v.raw;
    if (raw < 0) {
      raw += M;
    }
    return *this;
  }
  modint &operator*=(modint v) {
    raw = (raw * v.raw) % M;
    return *this;
  }
  modint pow(int n) const { return modint::pow(raw, n); }
  static modint pow(int a, int n) {
    if (n < 0) {
      // not support
      abort();
    }

    int r = 1;
    while (n) {
      if (n & 1) {
        r = (r * a) % M;
      }
      a = (a * a) % M;
      n >>= 1;
    }
    return modint(r);
  }

  modint inv() const {
    int a = raw;
    int b = M;
    int u = 1;
    int v = 0;
    while (b) {
      int t = a / b;
      a -= t * b;
      u -= t * v;
      swap(a, b);
      swap(u, v);
    }
    u %= M;
    if (u < 0) {
      u += M;
    }
    return u;
  }

  friend istream &operator>>(istream &is, modint &m) {
    int v;
    is >> v;
    m = modint(v);
    return is;
  }
  friend ostream &operator<<(ostream &os, modint const &m) {
    return os << m.raw;
  }
};
using mint = modint<MOD>;
using mints = arr<mint>;

//------------------------------------------------------------

struct OutputStream {
  template <class T>
  friend OutputStream &operator<<(OutputStream &s, T const &v) {
    mos << v << '\\n';
    return s;
  }
} out;

struct PrintStream {
  stringstream ss;

  template <class T> friend PrintStream &operator<<(PrintStream &s, T &&v) {
    s.ss << v << ' ';
    return s;
  }

  PrintStream &operator<<(PrintStream &(*manip)(PrintStream &)) {
    return (*manip)(*this);
  }
} prn;

PrintStream &endl(PrintStream &s) {
  string str = s.ss.str();
  s.ss = stringstream();
  if (str.empty() == false) {
    str.pop_back();
  }
  mos << str << '\\n';
  return s;
}

//------------------------------------------------------------
template <class T> void input(T &value) { mis >> value; }
void input(int &value, int add) {
  mis >> value;
  value += add;
}
template <class A, class B> void input(pr<A, B> &value) {
  mis >> value.a >> value.b;
}
template <class A, class B> void input(pr<A, B> &value, int addA, int addB) {
  mis >> value.a >> value.b;
  value.a += addA;
  value.b += addB;
}
template <class A, class B, class C> void input(tr<A, B, C> &value) {
  mis >> value.a >> value.b >> value.c;
}
template <class A, class B, class C>
void input(tr<A, B, C> &value, int addA, int addB, int addC) {
  mis >> value.a >> value.b >> value.c;
  value.a += addA;
  value.b += addB;
  value.c += addC;
}
template <class T, class... ARGS>
void input(arr<T> &value, int N, ARGS &&...args) {
  value.init(N);
  REP(i, N) { input(value[i], forward<ARGS>(args)...); }
}
template <class T, class... ARGS>
void input(arr2<T> &value, int H, int W, ARGS &&...args) {
  value.init(W, H);
  REP(y, H) {
    REP(x, W) { input(value(x, y), forward<ARGS>(args)...); }
  }
}
template <class K, class V, class... ARGS>
void input(dic<K, V> &value, int N, ARGS &&...args) {
  REP(i, N) {
    pair<K, V> pr;
    input(pr.first);
    input(pr.second, forward<ARGS>(args)...);
    value.insert(pr);
  }
}

template <class T> struct inputHolder {
  T value;
  template <class... ARGS> inputHolder(ARGS &&...args) {
    input(value, forward<ARGS>(args)...);
  }
  operator T() { return value; }
};

template <class T, class Tuple, size_t... Index>
T MakeFromTupleImpl(Tuple &&t, index_sequence<Index...>) {
  return T(get<Index>(forward<Tuple>(t))...);
}
template <class T, class Tuple> T MakeFromTuple(Tuple &&t) {
  return MakeFromTupleImpl<T>(
      forward<Tuple>(t),
      make_index_sequence<tuple_size<remove_reference_t<Tuple>>::value>{});
}
template <class... ARGS> struct inputWithParam {
  tuple<ARGS...> param;
  inputWithParam() {}
  explicit inputWithParam(tuple<ARGS...> &&param_) : param(param_) {}
  operator int() { return MakeFromTuple<inputHolder<int>>(param); }
  operator double() { return MakeFromTuple<inputHolder<double>>(param); }
  operator string() { return MakeFromTuple<inputHolder<string>>(param); }
  operator char() { return MakeFromTuple<inputHolder<char>>(param); }
  template <class A, class B> operator pr<A, B>() {
    return MakeFromTuple<inputHolder<pr<A, B>>>(param);
  }
  template <class A, class B, class C> operator tr<A, B, C>() {
    return MakeFromTuple<inputHolder<tr<A, B, C>>>(param);
  }
  template <class T> operator arr<T>() {
    return MakeFromTuple<inputHolder<arr<T>>>(param);
  }
  template <class A, class B> operator dic<A, B>() {
    return MakeFromTuple<inputHolder<dic<A, B>>>(param);
  }
  template <class T> operator arr2<T>() {
    return MakeFromTuple<inputHolder<arr2<T>>>(param);
  }
};
struct inputObject {
  operator int() { return inputWithParam<>(); }
  operator double() { return inputWithParam<>(); }
  operator string() { return inputWithParam<>(); }
  operator char() { return inputWithParam<>(); }
  template <class A, class B> operator pr<A, B>() { return inputWithParam<>(); }
  template <class A, class B, class C> operator tr<A, B, C>() {
    return inputWithParam<>();
  }
  template <class... ARGS> inputWithParam<ARGS...> operator()(ARGS &&...args) {
    inputWithParam<ARGS...> withParam(forward_as_tuple(args...));
    return withParam;
  }
} in;

//------------------------------------------------------------
#endif

struct MyMain {
  int S = in;

  void Run() {
    arr2<mint> dp(S + 1, S + 1);
    dp(0, S) = 1;
    int maxY = S;
    FOR(x, 1, (S / 3) + 3) {
      int newMaxY = 0;
      REP(by, maxY + 1) {
        FOR(cy, 3, by + 1) {
          mint count = dp(x - 1, by);
          int y = by - cy;
          if (y < 0) {
            break;
          }
          dp(x, y) += count;
          chmax(newMaxY, y);
        }
      }
      maxY = newMaxY;
    }

    mint ans = 0;
    FOR(x, 1, S + 1) { ans += dp(x, 0); }

    out << ans;
  }
};


#include <bits/stdc++.h>
using namespace std;
const int N = 2e2 + 2, Mod = 1e9 + 7;
long long int dp[N];
int s;
long long calc(long long sum) {
  // cout<<1;
  if (sum == s)
    return 1;
  if (sum > s)
    return 0;
  long long &ret = dp[sum];
  if (ret != -1)
    return ret;
  ret = 0;
  bool z = 0, n = 0;
  for (int i = 3; i <= s; i++) {

    ret += calc(sum + i) % Mod;
    ret %= Mod;
  }
  return ret %= Mod;
}
int main() {
  cin >> s;
  memset(dp, -1, sizeof dp);
  cout << calc(0);
  // cout<<2;
}

#include <bits/stdc++.h>
using namespace std;
const int N = 2e3 + 2, Mod = 1e9 + 7;
long long int dp[N];
int s;
long long calc(long long sum) {
  // cout<<1;
  if (sum == s)
    return 1;
  if (sum > s)
    return 0;
  long long &ret = dp[sum];
  if (ret != -1)
    return ret;
  ret = 0;
  bool z = 0, n = 0;
  for (int i = 3; i <= s; i++) {

    ret += calc(sum + i) % Mod;
    ret %= Mod;
  }
  return ret %= Mod;
}
int main() {
  cin >> s;
  memset(dp, -1, sizeof dp);
  cout << calc(0);
  // cout<<2;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
const int mod = 1e9 + 7;
int main() {
  int n;
  cin >> n;
  vector<ll> dp(n + 1);
  dp[0] = 1;
  dp[1] = 0;
  dp[2] = 0;
  dp[3] = 1;
  for (int i = 4; i <= n; i++) {
    for (int j = 3; j <= i; j++) {
      dp[i] = (dp[i] + dp[i - j]) % mod;
    }
  }
  cout << dp[n];
}

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
const int mod = 1e9 + 7;
int main() {
  int n;
  cin >> n;
  vector<ll> dp(n + 1);
  if (n < 3) {
    cout << "0";
    return 0;
  }
  dp[0] = 1;
  dp[1] = 0;
  dp[2] = 0;
  dp[3] = 1;
  for (int i = 4; i <= n; i++) {
    for (int j = 3; j <= i; j++) {
      dp[i] = (dp[i] + dp[i - j]) % mod;
    }
  }
  cout << dp[n];
}


#include <algorithm>
#include <bits/stdc++.h>
#include <iostream>
#include <stdlib.h>
using namespace std;

#define INF 1e9
#define PI 3.141592653589793238
#define N 1000000010
#define mod 1000000007
#define REP(inc, bgn, end) for (int inc = bgn; inc < end; inc++)
typedef long long ll;

int main() {
  ll sum;
  cin >> sum;
  ll ary[sum];
  REP(i, 0, sum + 1) ary[i] = 0;
  ary[0] = 1;
  ary[3] = 1;
  ary[4] = 1;
  ary[5] = 1;
  for (int i = 6; i <= sum; i++) {
    for (int j = i - 3; j >= 0; j--) {
      ary[i] += ary[j];
      ary[i] %= mod;
    }
  }

  ll ans = ary[sum];
  cout << ans << endl;

  return 0;
}

#include <algorithm>
#include <bits/stdc++.h>
#include <iostream>
#include <stdlib.h>
using namespace std;

#define INF 1e9
#define PI 3.141592653589793238
#define N 1000000010
#define mod 1000000007
#define REP(inc, bgn, end) for (int inc = bgn; inc < end; inc++)
typedef long long ll;

int main() {
  ll sum;
  cin >> sum;
  ll ary[3000];
  for (int i = 0; i <= sum; i++)
    ary[i] = 0;
  ary[0] = 1;
  ary[1] = 0;
  ary[2] = 0;
  ary[3] = 1;
  ary[4] = 1;
  ary[5] = 1;
  for (int i = 6; i <= sum; i++) {
    for (int j = i - 3; j >= 0; j--) {
      ary[i] += ary[j];
      ary[i] %= mod;
    }
  }

  ll ans = ary[sum];
  cout << ans << endl;

  return 0;
}


#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;
const ll mod = 1000000007;
const int INF = 1001001001;

ll pow_mod(ll x, ll y) {
  ll res = 1;
  for (ll i = 0; i < y; i++)
    res = res * x % mod;
  return res;
}

ll combination(int n, int k) {
  if (k == 0 || n == k)
    return 1;
  return combination(n - 1, k) + combination(n - 1, k - 1);
}

int main() {
  int s;
  cin >> s;

  if (s < 3) {
    cout << 0 << endl;
    return 0;
  }

  ll ans = 0;
  for (int i = 0; i < s / 3; i++) {
    int n = i + 1;
    int x = s - 3 * n;
    ans = (ans + combination(x + n - 1, x)) % mod;
  }
  cout << ans % mod << endl;
  return 0;
}

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;
const ll mod = 1000000007;
const int INF = 1001001001;

ll pow_mod(ll x, ll y) {
  ll res = 1;
  for (ll i = 0; i < y; i++)
    res = res * x % mod;
  return res;
}

int main() {
  int s;
  cin >> s;

  if (s < 3) {
    cout << 0 << endl;
    return 0;
  }

  vector<ll> dp(s + 1, 0);
  dp[0] = 1;
  for (int i = 3; i <= s; i++)
    dp[i] = (dp[i - 1] + dp[i - 3]) % mod;
  cout << dp[s] << endl;
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll M = 1e9 + 7;

unordered_map<ll, ll> f;
unordered_map<string, ll> dp;

ll fact(ll n) {
  if (n == 0)
    return 1;
  if (f.find(n) != f.end())
    return f[n];

  return f[n] = (n * fact(n - 1)) % M;
}

ll mmi(ll n, ll b = M - 2) {
  if (b == 0)
    return 1;
  ll ans = mmi(n, b / 2);
  ans = (ans * ans) % M;
  if (b & 1)
    ans = (ans * n) % M;
  return ans;
}

ll find(ll n, unordered_map<ll, ll> &map, ll dig = 1) {
  if (n < 3)
    return 0;
  map[n]++;
  ll ans = 1, count = 0;
  string state;
  state += to_string(n) + " " + to_string(dig);
  for (auto p : map) {
    if (p.second)
      ans *= fact(p.second);
    ans %= M;
  }
  count += fact(dig) * mmi(ans);
  state += " " + to_string(ans);
  if (dp.find(state) != dp.end())
    return dp[state];

  count %= M;
  ll half = n / 2;
  for (ll i = 3; i <= half; i++) {
    map[i]++;
    count += find(n - i, map, dig + 1);
    count %= M;
    map[i]--;
  }
  map[n]--;
  return dp[state] = count;
}

int main() {
  ll n;
  cin >> n;
  ll ans = 0;
  unordered_map<ll, ll> map;
  ans += find(n, map);
  cout << ans << endl;
  return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll M = 1e9 + 7;
vector<ll> dp;
int main() {
  ll n;
  cin >> n;
  dp.resize(n + 1);
  for (ll i = 3; i <= n; i++) {
    dp[i] += 1;
    for (ll j = 3; j <= i - 3; j++) {
      dp[i] += dp[j];
      dp[i] %= M;
    }
  }
  cout << dp[n] << endl;
  return 0;
}


#include <iostream>
#include <vector>

using namespace std;
const int MOD = 1e9 + 7;
// DP
vector<long long> memo;

long long dp(int S) {
  if (memo[S] != -1)
    return memo[S];
  if (S < 3)
    return memo[S] = 0;
  if (S == 0)
    return memo[S] = 1;

  long long res = 0;
  for (long long i = 3; i <= S; i++) {
    res = (res + dp(S - i)) % MOD;
  }
  return memo[S] = res;
}
int main() {
  int S;
  cin >> S;
  memo.resize(S + 1, -1);
  memo[0] = memo[3] = 1;
  memo[2] = memo[1] = 0;
  cout << dp(S) << '\\n';
  return 0;
}

#include <iostream>
#include <vector>

using namespace std;
const int MOD = 1e9 + 7;
// DP
vector<long long> memo;

long long dp(int S) {
  if (memo[S] != -1)
    return memo[S];
  if (S == 0 || S == 3)
    return memo[S] = 1;
  if (S < 3)
    return memo[S] = 0;

  long long res = 0;
  for (long long i = 3; i <= S; i++) {
    res = (res + dp(S - i)) % MOD;
  }
  return memo[S] = res;
}
int main() {
  int S;
  cin >> S;
  memo.resize(S + 1, -1LL);
  cout << dp(S) << '\\n';
  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long

const int mod = 1e9 + 7;
ll go(int n) {
  if (n == 0)
    return 1;
  if (n == 1 || n == 2)
    return 0;
  return go(n - 1) + go(n - 3) % mod;
}
int main() {
  ios_base::sync_with_stdio(false), cin.tie(0);

  int n;
  cin >> n;
  cout << go(n) << " ";
}

#include <bits/stdc++.h>
using namespace std;
#define ll long long

const int mod = 1e9 + 7;
ll dp[2007];
int N;
ll go(int n) {
  if (n == 1 || n == 2)
    return 0;
  if (dp[n] != -1)
    return dp[n];
  return dp[n] = (go(n - 1) + go(n - 3)) % mod;
}
int main() {
  ios_base::sync_with_stdio(false), cin.tie(0);

  cin >> N;
  memset(dp, -1, sizeof dp);
  dp[0] = 1;
  cout << go(N) % mod << " ";
}


*** stack smashing detected ***: terminated


#include <bits/stdc++.h>
using namespace std;

typedef long long int ll;
typedef pair<ll, ll> pll;

const int Max = 2e6 + 10;
const int Mod = 1e9 + 7;
const ll Inf = 1LL << 62;

int dp[2020][2020];

int rec(int pos, int sum) {
  if (sum == 0) {
    return 1;
  }
  int &ret = dp[pos][sum];
  if (~ret) {
    return ret;
  }
  ret = 0;
  for (int i = 3; i <= sum; i++) {
    ret += rec(pos + 1, sum - i);
    if (ret > Mod) {
      ret %= Mod;
    }
  }
  return ret;
}

int main() {
  int s;
  cin >> s;
  memset(dp, -1, sizeof dp);
  cout << rec(0, s) << endl;
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define int long long
#define ALL(x) (x).begin(), (x).end()
#define MAX(x) *max_element(ALL(x))
#define MIN(x) *min_element(ALL(x))

typedef pair<int, int> PI;
typedef pair<int, pair<int, int>> PII;
static const int INF = 1010000000000000017LL;
static const double eps = 1e-12;
static const double pi = 3.14159265358979323846;
static const int dx[4] = {1, -1, 0, 0};
static const int dy[4] = {0, 0, 1, -1};
static const int ddx[8] = {1, -1, 0, 0, 1, 1, -1, -1};
static const int ddy[8] = {0, 0, 1, -1, 1, -1, 1, -1};

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

int mod = 1000000007;

int S;
int mem[2005][2005];

void init() {
  for (int i = 0; i < 2005; ++i)
    for (int j = 0; j < 2005; ++j)
      mem[i][j] = -1;
}

int calc(int n, int s) {
  if (mem[n][s] != -1)
    return mem[n][s];
  // cout<<s<<endl;
  if (s >= S) {
    if (s == S)
      return 1;
    else
      return 0;
  }
  int ret = 0;
  for (int i = 3; i <= S - s; ++i) {
    ret += calc(n + 1, s + i);
    ret %= mod;
  }
  return mem[n][s] = ret % mod;
}

signed main() {
  init();
  cin >> S;
  cout << calc(0, 0) << endl;
}

#include <bits/stdc++.h>

using namespace std;

#define int long long
#define ALL(x) (x).begin(), (x).end()
#define MAX(x) *max_element(ALL(x))
#define MIN(x) *min_element(ALL(x))

typedef pair<int, int> PI;
typedef pair<int, pair<int, int>> PII;
static const int INF = 1010000000000000017LL;
static const double eps = 1e-12;
static const double pi = 3.14159265358979323846;
static const int dx[4] = {1, -1, 0, 0};
static const int dy[4] = {0, 0, 1, -1};
static const int ddx[8] = {1, -1, 0, 0, 1, 1, -1, -1};
static const int ddy[8] = {0, 0, 1, -1, 1, -1, 1, -1};

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

int mod = 1000000007;

int S;
int dp[5005];

signed main() {
  cin >> S;
  for (int i = 3; i <= 2000; ++i)
    dp[i] = 1;
  for (int s = 3; s <= S; ++s) {
    for (int i = 3; i <= 2000; ++i) {
      dp[s + i] += dp[s];
      dp[s + i] %= mod;
    }
  }
  cout << dp[S] % mod << endl;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
#define rep(i, n) for (ll i = 0; i < n; ++i)
#define ocut cout
#define ouct cout
#define itn int

struct Union {
  vector<ll> par;
  Union(ll a) { par = vector<ll>(a, -1); }
  ll find(ll a) {
    if (par[a] < 0) {
      return a;
    } else {
      return par[a] = find(par[a]);
    }
  }
  bool same(ll a, ll b) { return (find(a) == find(b)); }
  ll size(ll a) { return -par[find(a)]; }
  void unite(ll a, ll b) {
    ll c = find(a), d = find(b);
    if (c == d)
      return;
    if (size(c) < size(d)) {
      swap(c, d);
    }
    par[c] += par[d];
    par[d] = c;
  }
};
ll euclidean_gcd(ll a, ll b) {
  if (a < b)
    return euclidean_gcd(b, a);
  ll r;
  while ((r = a % b)) {
    a = b;
    b = r;
  }
  return b;
}
ll euclidean_lcm(ll a, ll b) { return a / euclidean_gcd(a, b) * b; }

ll binary(ll bina) {
  ll ans = 0;
  for (ll i = 0; bina > 0; i++) {
    ans += bina % 2;
    bina = bina / 2;
  }
  return ans;
}
void revStr(char *str) {
  int size = strlen(str);
  int i, j;
  char tmp = {0};

  for (i = 0, j = size - 1; i < size / 2; i++, j--) {
    tmp = str[i];
    str[i] = str[j];
    str[j] = tmp;
  }
  return;
}
ll comb(ll n, ll r) {
  std::vector<std::vector<long long>> v(n + 1,
                                        std::vector<long long>(n + 1, 0));
  for (ll i = 0; i < v.size(); i++) {
    v[i][0] = 1;
    v[i][i] = 1;
  }
  for (ll j = 1; j < v.size(); j++) {
    for (ll k = 1; k < j; k++) {
      v[j][k] = (v[j - 1][k - 1] + v[j - 1][k]) % 1000000007;
    }
  }
  return v[n][r];
}
int main(void) {
  ll s;
  cin >> s;
  ll d, ans = 0;
  for (ll i = 1; i < s / 3 + 1; i++) {
    d = s - i * 3;
    ans = (ans + comb(i + d - 1, d) % 1000000007) % 1000000007;
  }
  cout << ans;
}

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
#define rep(i, n) for (ll i = 0; i < n; ++i)
#define ocut cout
#define ouct cout
#define itn int

struct Union {
  vector<ll> par;
  Union(ll a) { par = vector<ll>(a, -1); }
  ll find(ll a) {
    if (par[a] < 0) {
      return a;
    } else {
      return par[a] = find(par[a]);
    }
  }
  bool same(ll a, ll b) { return (find(a) == find(b)); }
  ll size(ll a) { return -par[find(a)]; }
  void unite(ll a, ll b) {
    ll c = find(a), d = find(b);
    if (c == d)
      return;
    if (size(c) < size(d)) {
      swap(c, d);
    }
    par[c] += par[d];
    par[d] = c;
  }
};
ll euclidean_gcd(ll a, ll b) {
  if (a < b)
    return euclidean_gcd(b, a);
  ll r;
  while ((r = a % b)) {
    a = b;
    b = r;
  }
  return b;
}
ll euclidean_lcm(ll a, ll b) { return a / euclidean_gcd(a, b) * b; }

ll binary(ll bina) {
  ll ans = 0;
  for (ll i = 0; bina > 0; i++) {
    ans += bina % 2;
    bina = bina / 2;
  }
  return ans;
}
void revStr(char *str) {
  int size = strlen(str);
  int i, j;
  char tmp = {0};

  for (i = 0, j = size - 1; i < size / 2; i++, j--) {
    tmp = str[i];
    str[i] = str[j];
    str[j] = tmp;
  }
  return;
}

const int MAX = 510000;
const int MOD = 1000000007;

long long fac[MAX], finv[MAX], inv[MAX];

// テーブルを作る前処理
void COMinit() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < MAX; i++) {
    fac[i] = fac[i - 1] * i % MOD;
    inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
    finv[i] = finv[i - 1] * inv[i] % MOD;
  }
}

// 二項係数計算
long long COM(int n, int k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}
int main(void) {
  COMinit();
  ll s;
  cin >> s;
  ll d, ans = 0;
  for (ll i = 1; i < s / 3 + 1; i++) {
    d = s - i * 3;
    ans = (ans + COM(i + d - 1, d) % 1000000007) % 1000000007;
  }
  cout << ans;
}


#pragma GCC optimize("O3")
#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iomanip>
#include <iostream>
#include <istream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#define IINF 1000000000
#define INF 3223372036854775807
#define MOD 1000000007
#define mod 1000000007
#define INT_MAX_ 2147483647
#define EPS (1e-10)
#define REP(i, a, n) fo - r(ll i = a; i < (ll)(n); i++)
#define REPE(i, a, n) for (ll i = a; i <= (ll)(n); i++)
// #define rep(i,n)for (ll i = 0; i < (ll)(n); i++)
#define rep(i, l, r) for (ll i = (l); i < (r); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
#define Endl endl
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define mt make_tuple
#define eb emplace_back
#define mmax(x, y) (x > y ? x : y)
#define mmin(x, y) (x < y ? x : y)
#define chmax(x, y) x = mmax(x, y)
#define chmin(x, y) x = mmin(x, y)
#define all(x) (x).begin(), (x).end()
#define siz(x) (ll)(x).size()
#define PI acos(-1.0)
#define me memset
#define bit(n, k) ((n >> k) & 1)
#define lg length()
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<int, int> Pin;
typedef pair<ll, ll> Pll;
template <class T> using V = vector<T>;
template <typename T>
using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
long long GCD(long long a, long long b) { return b ? GCD(b, a % b) : a; }
long long LCM(long long a, long long b) { return a / GCD(a, b) * b; }
ll pom(ll a, ll n, int m) {
  ll x = 1;
  for (a %= m; n; n /= 2)
    n & 1 ? x = x * a % m : 0, a = a * a % m;
  return x;
}
#define invp(a, p) pom(a, p - 2, p)
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};
int ddx[8] = {-1, 0, 1, 0, 1, 1, -1, -1};
int ddy[8] = {0, -1, 0, 1, 1, -1, 1, -1};
ll cmp1(pair<Pll, ll> a, pair<Pll, ll> b) { return a.fi.se > b.fi.se; }
ll cmp2(pair<ll, ll> a, pair<ll, ll> b) {
  if (a.fi != b.fi)
    return a.se < b.se;
  else
    return a.se > b.se;
}
//----------------------------------------------------------------------
ll color[2002][2002];
ll rres[2001];
ll dfs(ll i, ll n, ll s) {
  if (color[i][n] >= 0)
    return color[i][n];
  ll res = n + i;
  ll tmp = 0;
  if (res == s)
    return 1;
  else if (res > s - 3 && res < s)
    return 0;
  else if (res > s)
    return 0;
  if (res >= s - res) {
    return rres[s - res];
  }
  for (ll j = 3; j <= s; j++) {
    if (res + j > s)
      break;
    if (res + j == s - 1)
      continue;
    if (res + j == s - 2)
      continue;
    tmp += dfs(j, res, s);
    tmp %= mod;
  }
  color[i][n] = tmp;
  return tmp;
}
//----------------------------------------------------------------------
int main(int argc, char *argv[]) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  //-------------------------------
  // ll begin_t=clock();
  // freopen("big.txt", "r", stdin);
  // freopen("out3.txt", "w", stdout);
  //------------------------------
  ll s;
  cin >> s;
  ll is = s;
  if (s < 3) {
    cout << 0 << endl;
    return 0;
  }
  for (ll i = 3; i <= s; i++) {
    ll aans = 0;
    for (ll y = 0; y <= i; y++) {
      for (ll j = 0; j <= i; j++) {
        color[y][j] = -1;
      }
    }
    for (ll k = 3; k <= i; k++) {
      aans += dfs(k, 0, i);
      aans %= mod;
    }
    rres[i] = aans;
    if (i == s)
      cout << rres[i] << endl;
  }
  //------------------------------
  // fclose(stdin);
  // fclose(stdout);
  // ll end_t=clock();cout<<"time="<<end_t-begin_t<<"ms"<<endl;
  //-------------------------------
  return 0;
}
//----------------------------------------------------------------------

#pragma GCC optimize("O3")
#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iomanip>
#include <iostream>
#include <istream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#define IINF 1000000000
#define INF 3223372036854775807
#define MOD 1000000007
#define mod 1000000007
#define INT_MAX_ 2147483647
#define EPS (1e-10)
#define REP(i, a, n) fo - r(ll i = a; i < (ll)(n); i++)
#define REPE(i, a, n) for (ll i = a; i <= (ll)(n); i++)
// #define rep(i,n)for (ll i = 0; i < (ll)(n); i++)
#define rep(i, l, r) for (ll i = (l); i < (r); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
#define Endl endl
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define mt make_tuple
#define eb emplace_back
#define mmax(x, y) (x > y ? x : y)
#define mmin(x, y) (x < y ? x : y)
#define chmax(x, y) x = mmax(x, y)
#define chmin(x, y) x = mmin(x, y)
#define all(x) (x).begin(), (x).end()
#define siz(x) (ll)(x).size()
#define PI acos(-1.0)
#define me memset
#define bit(n, k) ((n >> k) & 1)
#define lg length()
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<int, int> Pin;
typedef pair<ll, ll> Pll;
template <class T> using V = vector<T>;
template <typename T>
using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
long long GCD(long long a, long long b) { return b ? GCD(b, a % b) : a; }
long long LCM(long long a, long long b) { return a / GCD(a, b) * b; }
ll pom(ll a, ll n, int m) {
  ll x = 1;
  for (a %= m; n; n /= 2)
    n & 1 ? x = x * a % m : 0, a = a * a % m;
  return x;
}
#define invp(a, p) pom(a, p - 2, p)
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, -1, 0, 1};
int ddx[8] = {-1, 0, 1, 0, 1, 1, -1, -1};
int ddy[8] = {0, -1, 0, 1, 1, -1, 1, -1};
ll cmp1(pair<Pll, ll> a, pair<Pll, ll> b) { return a.fi.se > b.fi.se; }
ll cmp2(pair<ll, ll> a, pair<ll, ll> b) {
  if (a.fi != b.fi)
    return a.se < b.se;
  else
    return a.se > b.se;
}
//----------------------------------------------------------------------
ll color[2002][2002];
ll rres[2001];
ll dfs(ll i, ll n, ll s) {
  if (color[i][n] >= 0)
    return color[i][n];
  ll res = n + i;
  ll tmp = 0;
  if (res == s)
    return 1;
  else if (res > s - 3 && res < s)
    return 0;
  else if (res > s)
    return 0;
  return rres[s - res];

  for (ll j = 3; j <= s; j++) {
    if (res + j > s)
      break;
    if (res + j == s - 1)
      continue;
    if (res + j == s - 2)
      continue;
    tmp += dfs(j, res, s);
    tmp %= mod;
  }
  color[i][n] = tmp;
  return tmp;
}
//----------------------------------------------------------------------
int main(int argc, char *argv[]) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  //-------------------------------
  // ll begin_t=clock();
  // freopen("big.txt", "r", stdin);
  // freopen("out3.txt", "w", stdout);
  //------------------------------
  ll s;
  cin >> s;
  ll is = s;
  if (s < 3) {
    cout << 0 << endl;
    return 0;
  }
  for (ll i = 3; i <= s; i++) {
    ll aans = 0;
    for (ll y = 0; y <= i; y++) {
      for (ll j = 0; j <= i; j++) {
        color[y][j] = -1;
      }
    }
    for (ll k = 3; k <= i; k++) {
      aans += dfs(k, 0, i);
      aans %= mod;
    }
    rres[i] = aans;
    if (i == s)
      cout << rres[i] << endl;
  }
  //------------------------------
  // fclose(stdin);
  // fclose(stdout);
  // ll end_t=clock();cout<<"time="<<end_t-begin_t<<"ms"<<endl;
  //-------------------------------
  return 0;
}
//----------------------------------------------------------------------


/*/ Author: KaySeeKay /*/

#include <bits/stdc++.h>
using namespace std;

/*/---------------------------Defines-----------------------------------------/*/

#pragma GCC optimize("Ofast")
#define int long long
#define IOS                                                                    \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);
#define pb push_back
#define eb emplace_back
#define fn for (int i = 0; i < n; i++)
#define fn1 for (int i = 1; i <= n; i++)
#define fm for (int j = 0; j < m; j++)
#define fm1 for (int j = 1; j <= m; j++)
#define fi first
#define se second
#define endl '\\n'
#define PI 3.14159265358979323846
#define MOD 1000000007
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
const int N = 2e6 + 5;
const int INF = 1e18L;
// mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
/*/-----------------------------Debug
 * begins----------------------------------/*/
vector<string> split(const string &s, char c) {
  vector<string> v;
  stringstream ss(s);
  string x;
  while (getline(ss, x, c))
    v.emplace_back(x);
  return move(v);
}
template <typename T, typename... Args> inline string arrStr(T arr, int n) {
  stringstream s;
  s << "[";
  for (int i = 0; i < n - 1; i++)
    s << arr[i] << ",";
  s << arr[n - 1] << "]";
  return s.str();
}
#define trace(args...)                                                         \\
  {                                                                            \\
    __trace_begin(__LINE__);                                                   \\
    __trace(split(#args, ',').begin(), args);                                  \\
  }
inline void __trace_begin(int line) { cerr << "#" << line << ": "; }
template <typename T> inline void __trace_out_var(vector<T> val) {
  cerr << arrStr(val, val.size());
}
template <typename T> inline void __trace_out_var(T *val) {
  cerr << arrStr(val, 10);
}
template <typename T> inline void __trace_out_var(T val) { cerr << val; }
inline void __trace(vector<string>::iterator it) { cerr << endl; }

template <typename T, typename... Args>
inline void __trace(vector<string>::iterator it, T a, Args... args) {
  cerr << it->substr((*it)[0] == ' ', it->length()) << "=";
  __trace_out_var(a);
  cerr << "; ";
  __trace(++it, args...);
}
/*/-----------------------------Code begins----------------------------------/*/
int ar[N];
int dp[N];
inline int add(int x, int y, int mod) {
  if (y >= mod)
    y %= mod;
  if (x >= mod)
    x %= mod;
  x += y;
  return (x >= mod ? x - mod : x);
}
signed main() {
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  IOS;
  int T = 1;
  // cin >> T;
  while (T--) {
    int n;
    cin >> n;
    vector<int> v;
    dp[0] = 1;
    for (int i = 3; i <= n; i++) {
      v.pb(i);
    }
    int m = v.size();
    for (int j = 1; j <= n; j++) {
      for (int i = 0; i < m; i++) {
        dp[j] = add(dp[j], dp[j - v[i]], MOD);
      }
    }
    cout << dp[n];
  }
  return 0;
}

/*/ Author: KaySeeKay /*/

#include <bits/stdc++.h>
using namespace std;

/*/---------------------------Defines-----------------------------------------/*/

#pragma GCC optimize("Ofast")
#define int long long
#define IOS                                                                    \\
  ios_base::sync_with_stdio(false);                                            \\
  cin.tie(NULL);
#define pb push_back
#define eb emplace_back
#define fn for (int i = 0; i < n; i++)
#define fn1 for (int i = 1; i <= n; i++)
#define fm for (int j = 0; j < m; j++)
#define fm1 for (int j = 1; j <= m; j++)
#define fi first
#define se second
#define endl '\\n'
#define PI 3.14159265358979323846
#define MOD 1000000007
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
const int N = 2e6 + 5;
const int INF = 1e18L;
// mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
/*/-----------------------------Debug
 * begins----------------------------------/*/
vector<string> split(const string &s, char c) {
  vector<string> v;
  stringstream ss(s);
  string x;
  while (getline(ss, x, c))
    v.emplace_back(x);
  return move(v);
}
template <typename T, typename... Args> inline string arrStr(T arr, int n) {
  stringstream s;
  s << "[";
  for (int i = 0; i < n - 1; i++)
    s << arr[i] << ",";
  s << arr[n - 1] << "]";
  return s.str();
}
#define trace(args...)                                                         \\
  {                                                                            \\
    __trace_begin(__LINE__);                                                   \\
    __trace(split(#args, ',').begin(), args);                                  \\
  }
inline void __trace_begin(int line) { cerr << "#" << line << ": "; }
template <typename T> inline void __trace_out_var(vector<T> val) {
  cerr << arrStr(val, val.size());
}
template <typename T> inline void __trace_out_var(T *val) {
  cerr << arrStr(val, 10);
}
template <typename T> inline void __trace_out_var(T val) { cerr << val; }
inline void __trace(vector<string>::iterator it) { cerr << endl; }

template <typename T, typename... Args>
inline void __trace(vector<string>::iterator it, T a, Args... args) {
  cerr << it->substr((*it)[0] == ' ', it->length()) << "=";
  __trace_out_var(a);
  cerr << "; ";
  __trace(++it, args...);
}
/*/-----------------------------Code begins----------------------------------/*/
int ar[N];
int dp[N];
inline int add(int x, int y, int mod) {
  if (y >= mod)
    y %= mod;
  if (x >= mod)
    x %= mod;
  x += y;
  return (x >= mod ? x - mod : x);
}
signed main() {
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  IOS;
  int T = 1;
  // cin >> T;
  while (T--) {
    int n;
    cin >> n;
    vector<int> v;
    dp[0] = 1;
    for (int i = 3; i <= n; i++) {
      v.pb(i);
    }
    int m = v.size();
    for (int j = 1; j <= n; j++) {
      for (int i = 0; i < m; i++) {
        if (j - v[i] >= 0)
          dp[j] = add(dp[j], dp[j - v[i]], MOD);
      }
    }
    cout << dp[n];
  }
  return 0;
}

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc


/**
 * @File   : atcoder.cpp
 * @Author : pasnger
 * @Date   : 13/9/2020, 5:10:33 pm
 */

#include <bits/stdc++.h>
using namespace std;

#define INF 2e18
#define int long long
#define f(i, a, b) for (int i = (a); i < (b); (i)++)
#define fe(i, a, b) for (int i = (a); i <= (b); (i)++)
#define rf(i, a, b) for (int i = (a); i > (b); (i)--)
#define rfe(i, a, b) for (int i = (a); i >= (b); (i)--)
#define ff(ele, cont) for (auto(ele) : (cont))
#define pb push_back;

typedef vector<int> vi;
typedef pair<int, int> pii;
typedef map<int, int> mii;
typedef set<int> si;
typedef multiset<int> msi;

const int mxn = 1e6 + 4;
const int mod = 1e9 + 7;
const double pi = acos(-1);

#define deb(...) cerr << "[" << #__VA_ARGS__ << "] : [", DBG(__VA_ARGS__)
void DBG() { cerr << "]\\n"; }
template <typename T, typename... Args> void DBG(T first, Args... args) {
  cerr << first;
  if (sizeof...(args))
    cerr << ", ";
  DBG(args...);
}
int mul(int x, int y) {
  int res = x * y;
  if (res >= mod)
    res %= mod;
  return res;
}

int power(int x, int y) {
  int res = 1;
  while (y) {
    if (y & 1)
      res = mul(res, x);
    y = y >> 1;
    x = mul(x, x);
  }
  return res;
}
int add(int x, int y) {
  int res = x + y;
  if (res >= mod)
    res -= mod;
  return res;
}

/////////////////////////// GLOBAL ///////////////////////////

/////////////////////////// GLOBAL ///////////////////////////

void solve() {
  int n;
  cin >> n;
  int dp[n + 1];
  memset(dp, 0, sizeof(dp));
  dp[0] = 0;
  dp[1] = 0;
  dp[2] = 0;
  dp[3] = 1;
  dp[4] = 1;
  dp[5] = 1;
  fe(i, 6, n) {
    fe(j, 3, n) {
      if (i - j >= 3)
        dp[i] = add(dp[i - j], dp[i]);
    }
    dp[i]++;
  }
  cout << dp[n] << "\\n";
}

int32_t main() {
#ifndef ONLINE_JUDGE
  clock_t tStart = clock();
  freopen("in.txt", "r", stdin);
// freopen("output.txt","w",stdout);
#endif
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int t = 1;
  // cin >> t;
  for (int tt = 1; tt <= t; tt++) {
    // cout << "Case #"<<tt<<": ";
    solve();
  }
#ifndef ONLINE_JUDGE
  cerr << "\\nRun Time -> " << (double)(clock() - tStart) / CLOCKS_PER_SEC
       << " sec\\n";
#endif
}

/**
 * @File   : atcoder.cpp
 * @Author : pasnger
 * @Date   : 13/9/2020, 5:10:33 pm
 */

#include <bits/stdc++.h>
using namespace std;

#define INF 2e18
#define int long long
#define f(i, a, b) for (int i = (a); i < (b); (i)++)
#define fe(i, a, b) for (int i = (a); i <= (b); (i)++)
#define rf(i, a, b) for (int i = (a); i > (b); (i)--)
#define rfe(i, a, b) for (int i = (a); i >= (b); (i)--)
#define ff(ele, cont) for (auto(ele) : (cont))
#define pb push_back;

typedef vector<int> vi;
typedef pair<int, int> pii;
typedef map<int, int> mii;
typedef set<int> si;
typedef multiset<int> msi;

const int mxn = 1e6 + 4;
const int mod = 1e9 + 7;
const double pi = acos(-1);

#define deb(...) cerr << "[" << #__VA_ARGS__ << "] : [", DBG(__VA_ARGS__)
void DBG() { cerr << "]\\n"; }
template <typename T, typename... Args> void DBG(T first, Args... args) {
  cerr << first;
  if (sizeof...(args))
    cerr << ", ";
  DBG(args...);
}
int mul(int x, int y) {
  int res = x * y;
  if (res >= mod)
    res %= mod;
  return res;
}

int power(int x, int y) {
  int res = 1;
  while (y) {
    if (y & 1)
      res = mul(res, x);
    y = y >> 1;
    x = mul(x, x);
  }
  return res;
}
int add(int x, int y) {
  int res = x + y;
  if (res >= mod)
    res -= mod;
  return res;
}

/////////////////////////// GLOBAL ///////////////////////////
int dp[20004];
/////////////////////////// GLOBAL ///////////////////////////

void solve() {
  int n;
  cin >> n;

  memset(dp, 0, sizeof(dp));
  dp[0] = 0;
  dp[1] = 0;
  dp[2] = 0;
  dp[3] = 1;
  dp[4] = 1;
  dp[5] = 1;
  fe(i, 6, n) {
    fe(j, 3, n) {
      if (i - j >= 3)
        dp[i] = add(dp[i - j], dp[i]);
    }
    dp[i]++;
  }
  cout << dp[n] << "\\n";
}

int32_t main() {
#ifndef ONLINE_JUDGE
  clock_t tStart = clock();
  freopen("in.txt", "r", stdin);
// freopen("output.txt","w",stdout);
#endif
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  int t = 1;
  // cin >> t;
  for (int tt = 1; tt <= t; tt++) {
    // cout << "Case #"<<tt<<": ";
    solve();
  }
#ifndef ONLINE_JUDGE
  cerr << "\\nRun Time -> " << (double)(clock() - tStart) / CLOCKS_PER_SEC
       << " sec\\n";
#endif
}


#include <bits/stdc++.h>
using namespace std;

#ifndef ONLINE_JUDGE
#define debarr(a, x, y)                                                        \\
  cerr << #a << ":";                                                           \\
  for (int i = x; i <= y; i++)                                                 \\
    cerr << a[i] << " ";                                                       \\
  cerr << endl;
#define debmat(mat, row, col)                                                  \\
  cerr << #mat << ":\\n";                                                       \\
  for (int i = 0; i < row; i++) {                                              \\
    for (int j = 0; j < col; j++)                                              \\
      cerr << mat[i][j] << " ";                                                \\
    cerr << endl;                                                              \\
  }
#define deb(...) dbs(#__VA_ARGS__, __VA_ARGS__)
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &p) {
  return os << "(" << p.first << "," << p.second << ")";
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &p) {
  os << "[";
  for (auto &it : p)
    os << it << " ";
  return os << "]";
}
template <class T> ostream &operator<<(ostream &os, const set<T> &p) {
  os << "[";
  for (auto &it : p)
    os << it << " ";
  return os << "]";
}
template <class T> ostream &operator<<(ostream &os, const multiset<T> &p) {
  os << "[";
  for (auto &it : p)
    os << it << " ";
  return os << "]";
}
template <class S, class T>
ostream &operator<<(ostream &os, const map<S, T> &p) {
  os << "[";
  for (auto &it : p)
    os << it << " ";
  return os << "]";
}
template <class T> void dbs(string str, T t) {
  cerr << str << ":" << t << "\\n";
}
template <class T, class... S> void dbs(string str, T t, S... s) {
  int idx = str.find(',');
  cerr << str.substr(0, idx) << ":" << t << ",";
  dbs(str.substr(idx + 1), s...);
}
#else
#define deb(...)                                                               \\
  {}
#define debarr(a, x, y)                                                        \\
  {}
#define debmat(mat, row, col)                                                  \\
  {}
#endif
#define pr(x)                                                                  \\
  {                                                                            \\
    cout << x << "\\n";                                                         \\
    return;                                                                    \\
  }
template <class T> bool umin(T &a, T b) {
  return a > b ? (a = b, true) : false;
}
template <class T> bool umax(T &a, T b) {
  return a < b ? (a = b, true) : false;
}

#define int long long
#define ld long double
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define rep(i, n) for (int i = 0; i < n; i++)
#define re(i, n) for (int i = 1; i <= n; i++)
#define fr(i, a, b) for (int i = a; i <= b; i++)
#define fb(i, a, b) for (int i = a; i >= b; i--)
#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()
#define ini(x, y) memset(x, y, sizeof(x))
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<pii> vii;
typedef map<int, int> mii;
typedef set<int> si;
const int N = 2e5 + 10;
const int mod = 1000 * 1000 * 1000 + 7;
// const int mod = 998244353;
int mpow(int a, int l) {
  int res = 1;
  while (l) {
    if (l & 1)
      res = res * 1LL * a % mod;
    l /= 2;
    a = a * 1LL * a % mod;
  }
  return res;
}
int minv(int a) { return mpow(a, mod - 2); }
void add(int &a, int b) { a = ((a % mod) + (b % mod)) % mod; }
void sub(int &a, int b) { a = (a - b + mod) % mod; }
int mul(int a, int b) { return ((a % mod) * 1LL * (b % mod)) % mod; }
int cache[700][2001];
int dp(int len, int sum) {
  if (sum == 0)
    return 1;
  if (sum < 3)
    return 0;
  int &ans = cache[len][sum];
  if (ans != -1)
    return ans;
  ans = 0;
  for (int i = 3; i <= sum; i++)
    add(ans, dp(len + 1, sum - i));
  return ans;
}
void solve(int tc) {
  ini(cache, -1);
  int n;
  cin >> n;
  cout << dp(1, n) << endl;
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  int t = 1;
  // cin >> t;
  for (int i = 1; i <= t; i++)
    solve(i);
  return 0;
}

#include <bits/stdc++.h>
using namespace std;

#ifndef ONLINE_JUDGE
#define debarr(a, x, y)                                                        \\
  cerr << #a << ":";                                                           \\
  for (int i = x; i <= y; i++)                                                 \\
    cerr << a[i] << " ";                                                       \\
  cerr << endl;
#define debmat(mat, row, col)                                                  \\
  cerr << #mat << ":\\n";                                                       \\
  for (int i = 0; i < row; i++) {                                              \\
    for (int j = 0; j < col; j++)                                              \\
      cerr << mat[i][j] << " ";                                                \\
    cerr << endl;                                                              \\
  }
#define deb(...) dbs(#__VA_ARGS__, __VA_ARGS__)
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &p) {
  return os << "(" << p.first << "," << p.second << ")";
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &p) {
  os << "[";
  for (auto &it : p)
    os << it << " ";
  return os << "]";
}
template <class T> ostream &operator<<(ostream &os, const set<T> &p) {
  os << "[";
  for (auto &it : p)
    os << it << " ";
  return os << "]";
}
template <class T> ostream &operator<<(ostream &os, const multiset<T> &p) {
  os << "[";
  for (auto &it : p)
    os << it << " ";
  return os << "]";
}
template <class S, class T>
ostream &operator<<(ostream &os, const map<S, T> &p) {
  os << "[";
  for (auto &it : p)
    os << it << " ";
  return os << "]";
}
template <class T> void dbs(string str, T t) {
  cerr << str << ":" << t << "\\n";
}
template <class T, class... S> void dbs(string str, T t, S... s) {
  int idx = str.find(',');
  cerr << str.substr(0, idx) << ":" << t << ",";
  dbs(str.substr(idx + 1), s...);
}
#else
#define deb(...)                                                               \\
  {}
#define debarr(a, x, y)                                                        \\
  {}
#define debmat(mat, row, col)                                                  \\
  {}
#endif
#define pr(x)                                                                  \\
  {                                                                            \\
    cout << x << "\\n";                                                         \\
    return;                                                                    \\
  }
template <class T> bool umin(T &a, T b) {
  return a > b ? (a = b, true) : false;
}
template <class T> bool umax(T &a, T b) {
  return a < b ? (a = b, true) : false;
}

#define int long long
#define ld long double
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define rep(i, n) for (int i = 0; i < n; i++)
#define re(i, n) for (int i = 1; i <= n; i++)
#define fr(i, a, b) for (int i = a; i <= b; i++)
#define fb(i, a, b) for (int i = a; i >= b; i--)
#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()
#define ini(x, y) memset(x, y, sizeof(x))
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<pii> vii;
typedef map<int, int> mii;
typedef set<int> si;
const int N = 2e5 + 10;
const int mod = 1000 * 1000 * 1000 + 7;
// const int mod = 998244353;
int mpow(int a, int l) {
  int res = 1;
  while (l) {
    if (l & 1)
      res = res * 1LL * a % mod;
    l /= 2;
    a = a * 1LL * a % mod;
  }
  return res;
}
int minv(int a) { return mpow(a, mod - 2); }
void add(int &a, int b) { a = ((a % mod) + (b % mod)) % mod; }
void sub(int &a, int b) { a = (a - b + mod) % mod; }
int mul(int a, int b) { return ((a % mod) * 1LL * (b % mod)) % mod; }
void division(int &a, int b) { a = mul(a, mpow(b, mod - 2)); }
void solve(int tc) {
  int s;
  cin >> s;
  if (s < 3)
    pr(0);
  vi dp(s + 1, 0);
  dp[0] = 1;
  for (int i = 3; i <= s; i++) {
    for (int j = 3; j <= i; j++) {
      add(dp[i], dp[i - j]);
    }
  }
  cout << dp[s] << endl;
}

signed main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  int t = 1;
  // cin >> t;
  for (int i = 1; i <= t; i++)
    solve(i);
  return 0;
}


#include <algorithm>
#include <cmath>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>
#define rep(i, n) for (int i = 0; i < n; i++)
// #include <bits/stdc++.h>
using namespace std;

const long int INF = 1000000007;

int main() {
  int S;
  cin >> S;
  long long a[S + 1], sum[S + 1];
  if (S <= 2) {
    cout << 0 << endl;
    return 0;
  }
  a[0] = 0;
  a[1] = 0;
  a[2] = 0;
  a[3] = 1;
  a[4] = 1;
  a[5] = 1;
  sum[2] = 0;
  for (int i = 3; i <= S - 3; i++) {
    sum[i] = sum[i - 1] + a[i];
    sum[i] = sum[i] % INF;
    a[i + 3] = 1 + sum[i];
    a[i + 3] = a[i + 3] % INF;
  }
  cout << a[S] << endl;
  return 0;
}

#include <algorithm>
#include <cmath>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>
#define rep(i, n) for (int i = 0; i < n; i++)
// #include <bits/stdc++.h>
using namespace std;

const long int INF = 1000000007;

int main() {
  int S;
  cin >> S;
  long long a[S + 1], sum[S + 1];
  if (S <= 2) {
    cout << 0 << endl;
    return 0;
  }
  if (S <= 5) {
    cout << 1 << endl;
    return 0;
  }
  a[0] = 0;
  a[1] = 0;
  a[2] = 0;
  a[3] = 1;
  a[4] = 1;
  a[5] = 1;
  sum[0] = 0;
  sum[1] = 0;
  sum[2] = 0;
  for (int i = 3; i <= S - 3; i++) {
    sum[i] = sum[i - 1] + a[i];
    sum[i] = sum[i] % INF;
    a[i + 3] = 1 + sum[i];
    a[i + 3] = a[i + 3] % INF;
  }
  cout << a[S] << endl;
  return 0;
}