#ifdef _MSC_VER # define _CRT_SECURE_NO_WARNINGS # define _USE_MATH_DEFINES # include # define __builtin_popcount __popcnt #endif #include using namespace std; using i32 = int; using i64 = long long int; using f64 = double; using str = string; using u32 = unsigned int; using u64 = unsigned long long int; template using vec = vector; void in(){}; template void in(T &&x, TS &&...xs) { cin >> x; in(move(xs)...); }; template void out(T &&x) { cout << x << "\n"; }; template void out(T &&x, TS &&...xs) { cout << x << " "; out(move(xs)...); } #define indef(t, ...) t __VA_ARGS__; in(__VA_ARGS__) #define get(t) []{ t _; cin >> _; return _; }() #define times(n, i) for (i32 i = 0 ; i < (n); ++i) #define range(a, b, i) for (i32 i = (a); i < (b); ++i) #define upto(a, b, i) for (i32 i = (a); i <= (b); ++i) #define downto(a, b, i) for (i32 i = (a); i >= (b); --i) #define all(xs) (xs).begin(), (xs).end() #define sortall(xs) sort(all(xs)) #define reverseall(xs) reverse(all(xs)) #define even(x) ((abs(x) & 1) == 0) #define odd(x) ((abs(x) & 1) == 1) #define bit(x, i) (((x) >> i) & 1) #define append emplace_back #define findge lower_bound #define findgt upper_bound const i64 MOD = 1000000007ll; const f64 EPS = 1e-10; template struct m32 { i64 raw; m32() : raw(0) {} m32(unsigned x) : raw(x % mod) {} m32(signed x) { i32 t = x % mod; if (t < 0) t += mod; raw = t; } m32(signed long long x) { i32 t = x % mod; if (t < 0) t += mod; raw = t; } i32 value() const { return (i32)raw; } m32 &operator+=(m32 that) { if ((raw += that.raw) >= mod) raw -= mod; return *this; } m32 &operator-=(m32 that) { if ((raw += mod - that.raw) >= mod) raw -= mod; return *this; } m32 &operator*=(m32 that) { raw = (u64)raw * that.raw % mod; return *this; } m32 operator+(m32 that) const { return m32(*this) += that; } m32 operator-(m32 that) const { return m32(*this) -= that; } m32 operator*(m32 that) const { return m32(*this) *= that; } }; template struct mat { i32 n, m; valarray> v; mat(i32 n, i32 m) : n(n), m(m) { v.resize(n); times(n, i) v[i].resize(m); } mat(const mat &src) : n(src.n), m(src.m), v(src.v) { } valarray &operator[](size_t i) { return v[i]; } mat &operator*=(const mat &that) { mat res(n, that.m); if (m != that.n) throw domain_error(0); times(n, i) { times(that.m, j) { res[i][j] = 0; times(m, k) res[i][j] += v[i][k] * that.v[k][j]; } } return *this = res; } mat &operator^=(i64 e) { if (e < 0) throw domain_error(0); if (e == 0 && n != m) throw domain_error(0); if (e == 0) { times(n, i) { times(m, j) v[i][j] = i == j; } return *this; } if (e == 1) return *this; mat res = ((*this) * (*this)) ^ (e / 2); if (odd(e)) res *= *this; return *this = res; } mat operator*(const mat &that) const { mat res(*this); return res *= that; } mat operator^(i64 e) const { mat res(*this); return res ^= e; } }; i64 solve() { indef(i64, n); if (n == 0) return 0; mat> a(2, 2); a.v = { {1, 1}, {1, 0}, }; a ^= n-1; mat> b(2, 2); b.v = { {1, 1}, {1, 0}, }; b ^= a[0][0].raw - 1; return b[0][0].raw; } i32 main() { ios::sync_with_stdio(false); #ifdef _MSC_VER /** ifstream fin("input.txt"); cin.rdbuf(fin.rdbuf()); assert(fin); ofstream fout("output.txt"); cout.rdbuf(fout.rdbuf()); assert(fout); /**/ #endif cout << fixed << setprecision(9); out(solve()); return 0; }