#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math") #include using namespace std; typedef long long ll; #define pb(...) emplace_back(__VA_ARGS__) #define mp(a, b) make_pair(a, b) #define all(x) x.begin(), x.end() #define rall(x) x.rbegin(), x.rend() #define lscan(x) scanf("%I64d", &x) #define lprint(x) printf("%I64d", x) #define rep(i, n) for (ll i = 0; i < (n); i++) #define rep2(i, n) for (ll i = (ll)n - 1; i >= 0; i--) #define REP(i, l, r) for (ll i = l; i < (r); i++) #define REP2(i, l, r) for (ll i = (ll)r - 1; i >= (l); i--) #define siz(x) (ll) x.size() template using rque = priority_queue, greater>; template bool chmin(T &a, const T &b) { if (b < a) { a = b; return 1; } return 0; } template bool chmax(T &a, const T &b) { if (b > a) { a = b; return 1; } return 0; } template void print(vector a) { if (a.empty()) cout << '\n'; else { for (int i = 0; i < a.size(); i++) cout << a[i] << (i + 1 == a.size() ? '\n' : ' '); } } // __int128_t gcd(__int128_t a, __int128_t b) { // if (a == 0) // return b; // if (b == 0) // return a; // __int128_t cnt = a % b; // while (cnt != 0) { // a = b; // b = cnt; // cnt = a % b; // } // return b; // } long long extGCD(long long a, long long b, long long &x, long long &y) { if (b == 0) { x = 1; y = 0; return a; } long long d = extGCD(b, a % b, y, x); y -= a / b * x; return d; } struct UnionFind { vector data; int num; UnionFind(int sz) { data.assign(sz, -1); num = sz; } bool unite(int x, int y) { x = find(x), y = find(y); if (x == y) return (false); if (data[x] > data[y]) swap(x, y); data[x] += data[y]; data[y] = x; num--; return (true); } int find(int k) { if (data[k] < 0) return (k); return (data[k] = find(data[k])); } ll size(int k) { return (-data[find(k)]); } bool same(int x, int y) { return find(x) == find(y); } int operator[](int k) { return find(k); } }; template struct Mod_Int { int x; Mod_Int() : x(0) { } Mod_Int(long long y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) { } static int get_mod() { return mod; } Mod_Int &operator+=(const Mod_Int &p) { if ((x += p.x) >= mod) x -= mod; return *this; } Mod_Int &operator-=(const Mod_Int &p) { if ((x += mod - p.x) >= mod) x -= mod; return *this; } Mod_Int &operator*=(const Mod_Int &p) { x = (int)(1LL * x * p.x % mod); return *this; } Mod_Int &operator/=(const Mod_Int &p) { *this *= p.inverse(); return *this; } Mod_Int &operator++() { return *this += Mod_Int(1); } Mod_Int operator++(int) { Mod_Int tmp = *this; ++*this; return tmp; } Mod_Int &operator--() { return *this -= Mod_Int(1); } Mod_Int operator--(int) { Mod_Int tmp = *this; --*this; return tmp; } Mod_Int operator-() const { return Mod_Int(-x); } Mod_Int operator+(const Mod_Int &p) const { return Mod_Int(*this) += p; } Mod_Int operator-(const Mod_Int &p) const { return Mod_Int(*this) -= p; } Mod_Int operator*(const Mod_Int &p) const { return Mod_Int(*this) *= p; } Mod_Int operator/(const Mod_Int &p) const { return Mod_Int(*this) /= p; } bool operator==(const Mod_Int &p) const { return x == p.x; } bool operator!=(const Mod_Int &p) const { return x != p.x; } Mod_Int inverse() const { assert(*this != Mod_Int(0)); return pow(mod - 2); } Mod_Int pow(long long k) const { Mod_Int now = *this, ret = 1; for (; k > 0; k >>= 1, now *= now) { if (k & 1) ret *= now; } return ret; } friend ostream &operator<<(ostream &os, const Mod_Int &p) { return os << p.x; } friend istream &operator>>(istream &is, Mod_Int &p) { long long a; is >> a; p = Mod_Int(a); return is; } }; ll mpow2(ll x, ll n, ll mod) { ll ans = 1; x %= mod; while (n != 0) { if (n & 1) ans = ans * x % mod; x = x * x % mod; n = n >> 1; } return ans; } ll modinv2(ll a, ll mod) { ll b = mod, u = 1, v = 0; while (b) { ll t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v); } u %= mod; if (u < 0) u += mod; return u; } constexpr int mod = 1000000007; // constexpr int mod = 998244353; // constexpr int mod = 31607; using mint = Mod_Int; mint mpow(mint x, ll n) { mint ans = 1; while (n != 0) { if (n & 1) ans *= x; x *= x; n = n >> 1; } return ans; } // ----- library ------- template< class T > struct Matrix { vector< vector< T > > A; Matrix() {} Matrix(size_t n, size_t m) : A(n, vector< T >(m, 0)) {} Matrix(size_t n) : A(n, vector< T >(n, 0)) {}; size_t height() const { return (A.size()); } size_t width() const { return (A[0].size()); } inline const vector< T > &operator[](int k) const { return (A.at(k)); } inline vector< T > &operator[](int k) { return (A.at(k)); } static Matrix I(size_t n) { Matrix mat(n); for(int i = 0; i < n; i++) mat[i][i] = 1; return (mat); } Matrix &operator+=(const Matrix &B) { size_t n = height(), m = width(); assert(n == B.height() && m == B.width()); for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) (*this)[i][j] += B[i][j]; return (*this); } Matrix &operator-=(const Matrix &B) { size_t n = height(), m = width(); assert(n == B.height() && m == B.width()); for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) (*this)[i][j] -= B[i][j]; return (*this); } Matrix &operator*=(const Matrix &B) { size_t n = height(), m = B.width(), p = width(); assert(p == B.height()); vector< vector< T > > C(n, vector< T >(m, 0)); for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) for(int k = 0; k < p; k++) C[i][j] = (C[i][j] + (*this)[i][k] * B[k][j]); A.swap(C); return (*this); } Matrix &operator^=(long long k) { Matrix B = Matrix::I(height()); while(k > 0) { if(k & 1) B *= *this; *this *= *this; k >>= 1LL; } A.swap(B.A); return (*this); } Matrix operator+(const Matrix &B) const { return (Matrix(*this) += B); } Matrix operator-(const Matrix &B) const { return (Matrix(*this) -= B); } Matrix operator*(const Matrix &B) const { return (Matrix(*this) *= B); } Matrix operator^(const long long k) const { return (Matrix(*this) ^= k); } friend ostream &operator<<(ostream &os, Matrix &p) { size_t n = p.height(), m = p.width(); for(int i = 0; i < n; i++) { os << "["; for(int j = 0; j < m; j++) { os << p[i][j] << (j + 1 == m ? "]\n" : ","); } } return (os); } T determinant() { Matrix B(*this); assert(width() == height()); T ret = 1; for(int i = 0; i < width(); i++) { int idx = -1; for(int j = i; j < width(); j++) { if(B[j][i] != 0) idx = j; } if(idx == -1) return (0); if(i != idx) { ret *= -1; swap(B[i], B[idx]); } ret *= B[i][i]; T vv = B[i][i]; for(int j = 0; j < width(); j++) { B[i][j] /= vv; } for(int j = i + 1; j < width(); j++) { T a = B[j][i]; for(int k = 0; k < width(); k++) { B[j][k] -= B[i][k] * a; } } } return (ret); } }; mint fib(ll k) { Matrix a(2), b(2, 1); a[0][0] = 1, a[0][1] = 1, a[1][0] = 1, b[0][0] = 1, b[1][0] = 0; a ^= k; a *= b; return a[1][0]; } // ----- library ------- int main() { ios::sync_with_stdio(false); std::cin.tie(nullptr); cout << fixed << setprecision(15); ll n; cin >> n; if(n & 1) { mint ans = ((fib(n / 2 + 3) + fib(n / 2 + 1)) * (n / 2 + 2) - fib(n / 2 + 2)) / 5; ans += ((fib(n / 2 + 2) + fib(n / 2)) * (n / 2 + 1) - fib(n / 2 + 1)) / 5; cout << ans << endl; } else cout << fib(n / 2 + 1) << endl; }