#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
typedef pair<int,int> pii;

#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second

template<class T, class... Args>
auto create(size_t n, Args&&... args) {
	if constexpr(sizeof...(args) == 1)
		return vector<T>(n, args...);
	else
		return vector(n, create<T>(args...));
}

void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}

#ifdef OJ
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif
#define all(x) (x).begin(), (x).end()
#define rsort(x) sort((x).rbegin(), (x).rend())
#define sz(x) ((int)x.size())
#define fori(i, n) for (int i = 0; i < (int)(n); ++i)
#define ford(i, n, e) for (int i = (int)(n); i >= (int)(e); --i)
#define fore(i, a, b) for (int i = (int)(a); i <= (int)(b); ++i)
template<typename T> bool mmax(T &m, const T q) { if (m < q) {m = q; return true;} else return false; }
template<typename T> bool mmin(T &m, const T q) { if (m > q) {m = q; return true;} else return false; }
#define RETURN(x) do{cout << (x) << '\n'; return 0;}while(0)

const char en = '\n';
const int MOD = 1e9+7;
const int MAXN = 1e6+4;
const int INF = 1e9+1;

int fact[MAXN], inv[MAXN], ifact[MAXN];

template<typename T, typename T1>
T mod(T x, T1 p) {
    x %= p;
    if (x < 0)
        x += p;
    return x;
}

template<typename T>
T inverse(T x, T p) {
    x = mod(x, p);
    if (x == 1)
        return x;
    return mod((1LL * (-p / x) * (inv[p % x] % p)) , p); 
    // Since inverse of p % x is already calculated.
}

int NcR(int n, int r) {
    int ret = (1LL * ifact[n - r] * ifact[r]) % MOD ;
    ret = (1LL * ret * fact[n]) % MOD;
    return ret;
}


int solve() {
    fact[0] = 1;
    for(int i = 1; i < MAXN; i++) {
        fact[i] = 1LL * fact[i - 1] * i % MOD;
    }

    ifact[0] = 1;
    for(int i = 1; i < MAXN; i++) {
        inv[i] = inverse(i, MOD);
        ifact[i] = 1LL * ifact[i - 1] * inv[i] % MOD;
    }

    int n; cin >> n;
    vector<int> pw2(n+1),pw8(n+1);
    pw2[0] = 1;
    pw8[0] = 1;
    fore(i,1,n) pw8[i] = (1LL*pw8[i-1]*8)%MOD;
    fore(i,1,n) pw2[i] = (1LL*pw2[i-1]*2)%MOD;

    auto add = [](int a, int b) {
        int c = a+b;
        if(c >= MOD) c -= MOD;
        return c;
    };

    auto mul = [](int a, int b) {
        return (1LL*a*b) % MOD;
    };

    int ans = 0;
    fore(i,2,n) {
        int x1 = NcR(n,i);
        int x2 = pw2[i]-2;
        if(x2 < 0) x2 += MOD;
        int x3 = pw8[n-i];
        ans = add(ans,mul(x1,mul(x2,x3)));
    }

    cout << ans << en;
    return 0;
} 

int main(int argc, char **argv) {
#ifdef OJ
    freopen("input.txt", "rt", stdin);
    //freopen("output.txt", "wt", stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0);

    int ntest = 1;
    //cin >> ntest;
    fori(test, ntest) {
        //cout << "Case #" << test+1 << ": ";
        solve();
    }

    return 0;
}


Measured memory_bytes: 22728