#include using namespace std; #define int long long #define rep(i, a, b) for(int i = a; i < (b); ++i) #define all(x) begin(x),end(x) #define sz(x) (int)(x).size() typedef long long ll; typedef pair pii; typedef vector vi; typedef vector> vvi; typedef vector> vpii; template using vec = vector; template using uset = unordered_set; template using umap = unordered_map; ll euclid(ll a, ll b, ll&x, ll&y) { if (!b) return x = 1, y = 0, a; ll d = euclid(b, a%b, y, x); return y -= a/b*x, d; } const ll mod = 1e9+7; struct Mod { ll x; Mod(ll xx) : x(xx) { } Mod operator +(Mod b) { return Mod((x + b.x) % mod); } Mod operator -(Mod b) { return Mod((x - b.x + mod) % mod); } Mod operator *(Mod b) { return Mod((x * b.x) % mod); } Mod operator/(Mod b) { return *this * invert(b); } Mod invert(Mod a) { ll x, y, g = euclid(a.x, mod, x, y); assert(g == 1); return Mod((x + mod) % mod); } Mod operator^(ll e) { if (!e) return Mod(1); Mod r = *this ^ (e/2); r = r*r; return e&1 ? *this *r : r; } }; ll multinomial(vi&v) { ll c = 1, m = v.empty() ? 1 : v[0]; rep(i, 1, sz(v)) rep(j, 0, v[i]) c = c * ++m / (j+1); return c; } vec facts(110000, 1); int binom(int n, int k) { vi x { k, n-k }; return multinomial(x); } Mod binommod(Mod a, Mod b) { return facts[a.x] / (facts[b.x] * facts[(a - b).x]); } bool inc(vec &v) { rep(i, 0, sz(v)) { int j = sz(v) - i - 1; if (v[j] < 0xF) { v[j] += 1; return true; } else { v[j] = 0x0; } } return false; } void show(vec & v) { for (auto x : v) { rep(i, 0, 4) { cout << (x & (1 << (3 - i)) ? "D" : "."); } cout << " "; } cout << endl; } int val(uint8_t x) { int v = 0; rep(i, 0, 4) if (x & (1 << i)) v += 1; return v; } Mod s(int n0, int n, int d) { Mod res = 0; if (n == 0) return 0; if (d > 2*n) return 0; rep(k, 1, n/2 + 1) { Mod b1 = binommod(n, k); Mod top = 4*n - 4*k; Mod bot = 2*n0 - 4*k - d; if (top.x < bot.x) continue; Mod b2 = binommod(top, bot); Mod rem = s(n0, n - k, d + 4*k); res = res + b1*(b2 - rem); } return res; } void bruteforce() { for (int N = 1; true; ++N) { int res = 0; vec sticks(N, 0); do { if (none_of(all(sticks), [](auto a) { return a == 0; })) continue; if (accumulate(all(sticks), 0, [](auto a, auto b) { return a + val(b); }) != 2*N) continue; ++res; } while (inc(sticks)); // cout << "N = " << N << ": " << res << endl; // vi m = { 2*N - 4, 2*N }; // cout << "N*nCr(4N - 4, 2N - 2) = " << N * multinomial(m) << endl; // cout << "^ - res = " << N * multinomial(m) - res << endl; // // cout << "recurrence: " << s(N, N, 0) << endl; // cout << "recurrence - ^^ = " << s(N, N , 0) - N * multinomial(m) << endl; // cout << endl; } } void solve() { int N; cin >> N; cout << s(N, N, 0).x << endl; } signed main() { // bruteforce(); rep(i, 1, sz(facts)) { facts[i] = facts[i - 1]; facts[i] = facts[i] * i; } cin.tie(0)->sync_with_stdio(0); cin.exceptions(cin.failbit); ll T = 1; // cin >> T; rep(i, 0, T) solve(); }