/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author Pine1999
 */

#include <bits/stdc++.h>
//#include "../library/dsu.hpp"
//#include "../library/fenwicktree.hpp"
//#include "../library/modint.hpp"
//#include "../library/segtree.hpp"
//#include "../library/string.hpp"
//#include "../library/math.hpp"

using namespace std;
//using namespace atcoder;

#define ll long long
#define rep(i, n) for (int i = 0; i < (int) n; ++i)

template<class T> bool uin(T &a, T b) { return a > b ? (a = b, true) : false; }
template<class T> bool uax(T &a, T b) { return a < b ? (a = b, true) : false; }

const int mod = (int) (1e9 + 7);

template<int mod>
class ModInt {
    int x;
public:
    ModInt() : x(0) {}
    ModInt(long long int y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
    ModInt &operator+=(const ModInt& p)
    {
        if ((x += p.x) >= mod)
        {
            x -= mod;
        }
        return *this;
    }
    ModInt &operator-=(const ModInt& p)
    {
        if ((x += mod - p.x) >= mod)
        {
            x -= mod;
        }
        return *this;
    }
    ModInt &operator*=(const ModInt& p)
    {
        x = (int) (1LL * x * p.x % mod);
        return *this;
    }
    ModInt &operator/=(const ModInt& p)
    {
        *this *= p.Inverse();
        return *this;
    }
    ModInt operator-() const
    {
        return ModInt(-x);
    }
    ModInt operator+(const ModInt& p)
    {
        return ModInt(*this) += p;
    }
    ModInt operator-(const ModInt& p)
    {
        return ModInt(*this) -= p;
    }
    ModInt operator*(const ModInt& p)
    {
        return ModInt(*this) *= p;
    }
    ModInt operator/(const ModInt& p)
    {
        return ModInt(*this) /= p;
    }
    bool operator==(const ModInt& p)
    {
        return x == p.x;
    }
    bool operator!=(const ModInt& p)
    {
        return x!= p.x;
    }
    ModInt Inverse() const
    {
        int a = x, m = mod, u = 1, v = 0, t;
        while (m > 0)
        {
            t = a / m;
            std::swap(a -= t * m, m);
            std::swap(u -= t * v, v);
        }
        return ModInt(u);
    }
    friend std::ostream& operator<<(std::ostream& os, const ModInt& p)
    {
        return os << p.x;
    }
    friend std::istream& operator>>(std::istream& is, ModInt& a)
    {
        long long t;
        is >> t;
        a = ModInt<mod>(t);
        return is;
    }
};

using Mint = ModInt<mod>;

class Combination
{
public:
    std::vector<Mint> fact, inv;
    Combination(int n)
    {
        fact.resize(n + 1);
        inv.resize(n + 1);
        fact[0] = 1;
        for (int i = 1; i <= n; ++i)
        {
            fact[i] = fact[i - 1] * i;
        }
        inv[n] = fact[n].Inverse();
        for (int i = n - 1; i >= 0; --i)
        {
            inv[i] = inv[i + 1] * (i + 1);
        }
    }
    Mint C(int n, int r)
    {
        if (n < r)
        {
            return 0;
        }
        if (n == r)
        {
            return 1;
        }
        return fact[n] * inv[r] * inv[n - r];
    }
};

void CUbiquity(std::istream& in, std::ostream& out) {
    int n;
    in >> n;
    Mint ans = 0;
    vector<Mint> pw9(n + 1), pw8(n + 1);
    pw9[0] = 1;
    pw8[0] = 1;
    for (int i = 1; i <= n; ++i) {
        pw9[i] = pw9[i - 1] * 9;
        pw8[i] = pw8[i - 1] * 8;
    }
    Combination comb(n + 100);
    for (int i = 1; i < n; ++i) {
        ans += comb.C(n, i) * (pw9[n - i] - pw8[n - i]);
    }
    out << ans << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    std::istream& in(std::cin);
    std::ostream& out(std::cout);
    CUbiquity(in, out);
    return 0;
}

Measured memory_bytes: 18672