#include <bits/stdc++.h>
using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
template<class T> using V = vector<T>;
template<class T> using VV = V<V<T>>;
constexpr ll TEN(int n){return (n==0) ? 1 : 10 * TEN(n-1);}
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define rep(i,N) for(int i=0;i<(int)(N);i++)
#define rep1(i,N) for(int i=1;i<=(int)(N);i++)
#define fs first
#define sc second
#define eb emplace_back
#define pb eb
#define all(x) x.begin(),x.end()
template<class T, class U> void chmin(T& t, const U& u){ if(t>u) t = u;}
template<class T, class U> void chmax(T& t, const U& u){ if(t<u) t = u;}

#ifdef LOCAL
#define show(x) cerr << __LINE__ << " : " << #x << " = " << (x) << endl
#else
#define show(x) true
#endif

template<class T,class U>
ostream& operator<<(ostream& os, const pair<T,U>& p){
    return os << "P(" << p.fs << ", " << p.sc << ")";
}
template<class T> ostream& operator<<(ostream& os, const V<T>& v){
    os << "[";
    for(auto d: v) os << d << ", ";
    return os << "]";
}
template<unsigned int mod_>
struct ModInt{
    using M = ModInt;
    constexpr static uint mod = mod_;
    uint v;
    ModInt():v(0){}
    ModInt(ll _v):v(normS(_v%mod+mod)){}
    explicit operator bool() const {return v!=0;}
    static uint normS(const uint&x){return (x<mod)?x:x-mod;}
    static M make(const uint&x){M m;m.v=x;return m;}
    M operator+(const M& b) const {return make(normS(v+b.v));}
    M operator-(const M& b) const {return make(normS(v+mod-b.v));}
    M operator-() const {return make(normS(mod-v));}
    M operator*(const M& b) const {return make((ull)v*b.v%mod);}
    M operator/(const M& b){return *this*b.inv();}
    M& operator+=(const M& b){return *this=*this+b;}
    M& operator-=(const M& b){return *this=*this-b;}
    M& operator*=(const M& b){return *this=*this*b;}
    M& operator/=(const M& b){return *this=*this/b;}
    ll extgcd(ll a,ll b,ll &x,ll& y) const {
        ll p[]={a,1,0},q[]={b,0,1};
        while(*q){
            ll t=*p/ *q;
            rep(i,3) swap(p[i]-=t*q[i],q[i]);
        }
        if(p[0]<0) rep(i,3) p[i] = -p[i];
        x = p[1], y = p[2];
        return p[0];
    }
    ModInt inv() const {
        ll x,y;
        extgcd(v,mod,x,y);
        return make(normS(x+mod));
    }
    M pow(ll p) const {
        if(p<0) return inv().pow(-p);
        M a = 1;
        M x = *this;
        while(p){
            if(p&1) a *= x;
            x *= x;
            p /= 2;
        }
        return a;
    }
    bool operator==(const M& b) const {return v == b.v;}
    bool operator!=(const M& b) const {return v != b.v;}
    friend ostream& operator<<(ostream &o, const M& x){return o<<x.v;}
};
using mint = ModInt<1000000007>;
V<mint> fact,ifact;
void InitFact(int N){
    fact.resize(N);
    ifact.resize(N);
    fact[0] = 1;
    rep1(i,N-1) fact[i] = fact[i-1] * i;
    ifact[N-1] = fact[N-1].inv();
    for(int i=N-2;i>=0;i--) ifact[i] = ifact[i+1] * (i+1);
}
int bsr(int x){return 31-__builtin_clz(x);}
using D = double;
const D pi = acos(-1);
using Pc = complex<D>;
void fft(bool type, V<Pc> &c){
    static V<Pc> buf[30];
    int N = c.size();
    int s = bsr(N);
    assert(1<<s == N);
    if(buf[s].empty()){
        buf[s] = V<Pc>(N);
        rep(i,N) buf[s][i] = polar<D>(1,i*2*pi/N);
    }
    V<Pc> a(N),b(N);
    copy(begin(c),end(c),begin(a));
    rep1(i,s){
        int W = 1<<(s-i);
        for(int y=0;y<N/2;y+=W){
            Pc now = buf[s][y];
            if(type) now = conj(now);
            rep(x,W){
                auto l = a[y<<1 | x];
                auto r = now * a[y<<1 | x | W];
                b[y|x] = l+r;
                b[y|x|N>>1] = l-r;
            }
        }
        swap(a,b);
    }
    copy(begin(a),end(a),begin(c));
}
template<class Mint>
V<Mint> multiply_fft(const V<Mint>& x, const V<Mint>& y){
    if(x.empty() || y.empty()) return {};
    const int B = 15;
    const int K = 2;
    int S = x.size() + y.size() - 1;
    int N = 1;while(N<S) N *= 2;
    V<Pc> a[K],b[K];
    rep(t,K){
        a[t] = V<Pc>(N);
        b[t] = V<Pc>(N);
        rep(i,x.size()) a[t][i] = Pc( (x[i].v >> (t*B)) & ((1<<B)-1) , 0);
        rep(i,y.size()) b[t][i] = Pc( (y[i].v >> (t*B)) & ((1<<B)-1) , 0);
        fft(false,a[t]);
        fft(false,b[t]);
    }
    V<Mint> z(S);
    V<Pc> c(N);
    Mint base = 1;
    rep(t,K+K-1){
        fill_n(begin(c),N,Pc(0,0));
        rep(xt,K){
            int yt = t-xt;
            if(0<=yt && yt<K){
                rep(i,N) c[i] += a[xt][i] * b[yt][i];
            }
        }
        fft(true,c);
        rep(i,S){
            c[i] *= 1.0/N;
            z[i] += Mint(ll(round(c[i].real()))) * base;
        }
        base *= 1<<B;
    }
    return z;
}

template<class D>
struct Poly{
    V<D> v;
    int size() const{return v.size();}
    Poly(){}
    Poly(V<D> _v) : v(_v){shrink();}

    Poly& shrink(){
        while(!v.empty() && v.back() == D(0)) v.pop_back();
        return *this;
    }
    D at(int i) const{
        return (i<size()) ? v[i] : D(0);
    }
    void set(int i,const D& x){
        if(i>=size() && !x) return;
        while(i>=size()) v.pb(D(0));
        v[i] = x;
        shrink();
        return;
    }
    Poly operator+(const Poly& r) const{
        int N = max(size(),r.size());
        V<D> ret(N);
        rep(i,N) ret[i] = at(i) + r.at(i);
        return Poly(ret);
    }
    Poly operator-(const Poly& r) const{
        int N = max(size(),r.size());
        V<D> ret(N);
        rep(i,N) ret[i] = at(i) - r.at(i);
        return Poly(ret);
    }
    Poly operator*(const Poly &r) const {
        if(size() == 0 || r.size() == 0) return Poly();
        return mul_fft(r);
    }
    Poly operator*(const D& r) const{
        int N = size();
        V<D> ret(N);
        rep(i,N) ret[i] = v[i] * r;
        return Poly(ret);
    }

    Poly mul_naive(const Poly &r) const{
        int N = size(), M = r.size();
        V<D> ret(N+M-1);
        rep(i,N) rep(j,M) ret[i+j] += at(i) * r.at(j);
        return Poly(ret);
    }
    Poly mul_fft(const Poly &r) const{
        return Poly(multiply_fft(v,r.v));
    }
    Poly strip(int n) const {
        V<D> res = v;
        res.resize(min(n,size()));
        return Poly(res);
    }
    
    Poly diff() const{
        int n = size();
        if(n == 0) return Poly();
        V<D> u(n-1);
        rep(i,n-1) u[i] = at(i+1) * (i+1);
        return Poly(u);
    }
    Poly intg() const {
        int n = size();
        V<D> u(n+1);
        rep(i,n) u[i+1] = at(i) / (i+1);
        return Poly(u);
    }
    Poly exp(int n) const {
        assert(at(0) == 0);
        Poly f({1}), g({1});
        for(int i=1;i<=n;i*=2){
            g = (g*2 - f*g*g).strip(i);
            auto q = (this->diff()).strip(i-1);
            auto w = (q+g*(f.diff()-f*q)).strip(2*i-1);
            f = (f + f * (*this - w.intg()).strip(2*i)).strip(2*i);
        }
        return f.strip(n+1);
    }

    friend ostream& operator<<(ostream&o,const Poly& x){
        if(x.size() == 0) return o<<0;
        rep(i,x.size()) if(x.v[i] != D(0)){
            o<<x.v[i]<<"x^"<<i;
            if(i!=x.size()-1) o<<" + ";
        }
        return o;
    }
};

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
    InitFact(1000000);

    int N;
    cin >> N;
    mint ans = 0;
    {
        Poly<mint> logf;
        rep1(i,N+10) logf.set(i,1);
        auto f = logf.exp(N);
        ans -= f.at(N) * f.at(N);
    }
    {
        Poly<mint> logg;
        rep1(i,N+10) logg.set(i,i);
        auto g = logg.exp(N);
        ans += g.at(N);
    }
    cout << ans << endl;
}


Measured memory_bytes: 56200