/**
  *  Author: dhruv_gheewala
  *  Problem: C - Ubiquity
  *  Date:   19.09.2020
  *  Time:   11:31:25
**/

#if __has_include("debug.h")
    #include "debug.h"
#else
    #include<bits/stdc++.h>
    using namespace std;
    
    #define fundri 108
    #define debug(...) 1729
#endif

#define int int64_t
typedef pair<int, int> pii;
typedef vector<int> vi;

const bool testcases = false;
#define ff first
#define ss second
#define endl '\n'
#define all(s) s.begin(), s.end()

// if vector isn't soted then it will remove consecutive same elements
#define make_unique(vec) vec.erase(unique(all(vec)), vec.end())
#define test int TC = 1;if(testcases)cin >> TC;for(int tc = 1 ; tc <= TC ; tc++)solve(), fundri
#define sort_by(cont,expr) sort(all(cont),[&](const auto &lhs,const auto &rhs){return expr;})
// clears stdin
#define flush(ch) cin.ignore(std::numeric_limits<std::streamsize>::max(), ch) // default, EOF

int seed; mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
inline int rnd(int l = 0, int r = INT_MAX) {return uniform_int_distribution<int>(l, r)(rng);}

inline bool in_range(int a, int l, int r) {return (a >= l && a <= r);}
template<typename H, typename ...T>void inp(H &head) {cin >> head;}
template<typename H, typename ...T>void inp(H &head, T &...tail) {cin >> head;inp(tail...);}
template<typename T>bool isPrime(T n) {for(T i = 2; i * i <= n; i++)if(n % i == 0)return false; return n >= 2;}
template<typename T>inline istream &operator >>(istream &in, vector<T> &a) {for(T &x : a)in >> x; return in;}
template<typename T, typename U>inline istream &operator >>(istream &in, pair<T, U> &a) {in >> a.ff >> a.ss; return in;}

void solve();
void fast_io();

int32_t main(int32_t argc, char **argv)
{
    fast_io();
    test;
    return 0;
}

template<typename T>
T inverse(T a, T m)
{
    T u, v, t;
    u = 0;
    v = 1;

    while(a != 0)
    {
        t = m / a;
        m -= t * a;
        swap(a, m);
        u -= t * v;
        swap(u, v);
    }

    assert(m == 1);
    return u;
}

template<typename T>
class Modular
{
    public:
        using Type = typename decay<decltype(T::value)>::type;

        constexpr Modular() : value() {}
        
        template<typename U>
        Modular(const U& x)
        {
            value = normalize(x);
        }

        template<typename U>
        static Type normalize(const U& x)
        {
            Type v;
            if(-mod() <= x && x < mod()) v = static_cast<Type>(x);
            else v = static_cast<Type>(x % mod());
            if(v < 0) v += mod();
            return v;
        }

        const Type& operator()() const {return value;}
        
        template<typename U>
        explicit operator U() const {return static_cast<U>(value);}
        constexpr static Type mod() {return T::value;}

        Modular& operator+=(const Modular& other)
        {
            if((value += other.value) >= mod()) 
                value -= mod(); 
            return *this;
        }
        
        Modular& operator-=(const Modular& other)
        {
            if((value -= other.value) < 0)
                value += mod();
            return *this;
        }

        template <typename U> Modular& operator+=(const U& other){return *this += Modular(other);}
        template <typename U> Modular& operator-=(const U& other){return *this -= Modular(other);}
        Modular& operator++(){return *this += 1;}
        Modular& operator--(){return *this -= 1;}
        Modular operator++(int32_t){Modular result(*this); *this += 1; return result;}
        Modular operator--(int32_t){ Modular result(*this); *this -= 1; return result;}
        Modular operator-() const{return Modular(-value);}

        template<typename U = T>
        typename enable_if<is_same<typename Modular<U>::Type, int32_t>::value, Modular>::type& operator*=(const Modular& rhs)
        {
            #ifdef _WIN32
                uint64_t x = static_cast<int64_t>(value) * static_cast<int64_t>(rhs.value);
                uint32_t xh = static_cast<uint32_t>(x >> 32), xl = static_cast<uint32_t>(x), d, m;
                asm(
                  "divl %4; \n\t"
                  : "=a" (d), "=d" (m)
                  : "d" (xh), "a" (xl), "r" (mod())
                  );
                value = m;
            #else
                value = normalize(static_cast<int64_t>(value) * static_cast<int64_t>(rhs.value));
            #endif
                return *this;
        }
        
        template<typename U = T>
        typename enable_if<is_same<typename Modular<U>::Type, int64_t>::value, Modular>::type& operator*=(const Modular& rhs)
        {
            int64_t q = static_cast<int64_t>(static_cast<long double>(value) * rhs.value / mod());
            value = normalize(value * rhs.value - q * mod());
            return *this;
        }
        
        template<typename U = T>
        typename enable_if<!is_integral<typename Modular<U>::Type>::value, Modular>::type& operator*=(const Modular& rhs)
        {
            value = normalize(value * rhs.value);
            return *this;
        }

        Modular& operator/=(const Modular& other){return *this *= Modular(inverse(other.value, mod()));}

        template<typename U>
        friend const Modular<U>& abs(const Modular<U>& v){return v;}

        template<typename U>
        friend bool operator==(const Modular<U>& lhs, const Modular<U>& rhs);

        template<typename U>
        friend bool operator<(const Modular<U>& lhs, const Modular<U>& rhs);

        template<typename U>
        friend std::istream& operator>>(std::istream& stream, Modular<U>& number);

    private:
        Type value;
};

template<typename T> bool operator==(const Modular<T>& lhs, const Modular<T>& rhs){return lhs.value == rhs.value;}
template<typename T, typename U> bool operator==(const Modular<T>& lhs, U rhs){return lhs == Modular<T>(rhs);}
template<typename T, typename U> bool operator==(U lhs, const Modular<T>& rhs){return Modular<T>(lhs) == rhs;}

template<typename T> bool operator!=(const Modular<T>& lhs, const Modular<T>& rhs){return !(lhs == rhs);}
template<typename T, typename U> bool operator!=(const Modular<T>& lhs, U rhs){return !(lhs == rhs);}
template<typename T, typename U> bool operator!=(U lhs, const Modular<T>& rhs){return !(lhs == rhs);}

template<typename T> bool operator<(const Modular<T>& lhs, const Modular<T>& rhs){return lhs.value < rhs.value;}

template<typename T> Modular<T> operator+(const Modular<T>& lhs, const Modular<T>& rhs){return Modular<T>(lhs) += rhs;}
template<typename T, typename U> Modular<T> operator+(const Modular<T>& lhs, U rhs){return Modular<T>(lhs) += rhs;}
template<typename T, typename U> Modular<T> operator+(U lhs, const Modular<T>& rhs){return Modular<T>(lhs) += rhs;}

template<typename T> Modular<T> operator-(const Modular<T>& lhs, const Modular<T>& rhs){return Modular<T>(lhs) -= rhs;}
template<typename T, typename U> Modular<T> operator-(const Modular<T>& lhs, U rhs){return Modular<T>(lhs) -= rhs;}
template<typename T, typename U> Modular<T> operator-(U lhs, const Modular<T>& rhs){return Modular<T>(lhs) -= rhs;}

template<typename T> Modular<T> operator*(const Modular<T>& lhs, const Modular<T>& rhs){return Modular<T>(lhs) *= rhs;}
template<typename T, typename U> Modular<T> operator*(const Modular<T>& lhs, U rhs){return Modular<T>(lhs) *= rhs;}
template<typename T, typename U> Modular<T> operator*(U lhs, const Modular<T>& rhs){return Modular<T>(lhs) *= rhs;}

template<typename T> Modular<T> operator/(const Modular<T>& lhs, const Modular<T>& rhs){return Modular<T>(lhs) /= rhs;}
template<typename T, typename U> Modular<T> operator/(const Modular<T>& lhs, U rhs){return Modular<T>(lhs) /= rhs;}
template<typename T, typename U> Modular<T> operator/(U lhs, const Modular<T>& rhs){return Modular<T>(lhs) /= rhs;}

template<typename T, typename U>
Modular<T> power(const Modular<T>& a, const U& b)
{
    assert(b >= 0);
    Modular<T> x = a, res = 1;
    U p = b;
    while(p > 0)
    {
        if(p & 1)
            res *= x;
        x *= x;
        p >>= 1;
    }
    return res;
}

template<typename T>
bool IsZero(const Modular<T>& number){return number() == 0;}

template<typename T>
string to_string(const Modular<T>& number){return to_string(number());}

template<typename T>
std::ostream& operator<<(std::ostream& stream, const Modular<T>& number){return stream << number();}

template<typename T>
std::istream& operator>>(std::istream& stream, Modular<T>& number)
{
    typename common_type<typename Modular<T>::Type, int64_t>::type x;
    stream >> x;
    number.value = Modular<T>::normalize(x);
    return stream;
}

/*
using ModType = int;

struct VarMod { static ModType value; };
ModType VarMod::value;
ModType& MOD = VarMod::value;
using Mint = Modular<VarMod>;
*/

constexpr int32_t MOD = 1e9 + 7;
using Mint = Modular<std::integral_constant<decay<decltype(MOD)>::type, MOD>>;
typedef vector<Mint> vMi;

vMi inv,inv_fact,fact;
void build_factorial(int maximum = 1000000)
{
    for(int i = 2 ; i * i <= MOD ; i++)
        assert(MOD % i);

    inv = {0, 1};
    fact = inv_fact = {1, 1};

    maximum = max(maximum, (decltype(maximum))1);
    inv.resize(maximum + 1);
    fact.resize(maximum + 1);
    inv_fact.resize(maximum + 1);

    for(int i = 2 ; i <= maximum ; i++)
    {
        inv[i] = inv[MOD % i] * (MOD - MOD / i);
        fact[i] = i * fact[i - 1];
        inv_fact[i] = inv[i] * inv_fact[i - 1];
    }
}

// Mint choose(int n, int r)
// {
//     if(in_range(r, 0LL, n))
//         return fact[n] * inv_fact[r] * inv_fact[n-r];
//     return 0;
// }

// Mint inv_choose(int n, int r)
// {
//     assert(in_range(r, 0LL, n));
//     return inv_fact[n] * fact[r] * fact[n - r];
// }

// Mint permute(int n, int r)
// {
//     if(in_range(r, 0LL, n))
//         return fact[n] * inv_fact[n - r];
//     return 0;
// }

// Mint inv_permute(int n, int r)
// {
//     assert(in_range(r, 0LL, n));
//     return inv_fact[n] * fact[n - r];
// }

// const int mod = 1e9 + 7;
// int mul(int a, int b) {return ((a % mod) * (b % mod)) % mod;}
// int modpow(int a, int n)
// {
// 	if(n == 0)
// 		return 1;
// 	if(n == 1)
// 		return a;

// 	int val = modpow(a, n / 2);	
// 	int res = (n % 2 == 1 ? a : 1);
// 	res = mul(res, mul(val, val));
// 	return res;
// }

// Mint fact(const Mint a)
// {
// 	if(a < Mint(3))
// 		return a;
// 	return a * fact(a - 1);
// }

void solve()
{
	int m;
	cin >> m;
    
    if(m == 1) {
    	cout << 0 << endl;
    	return;
    }

    // build_factorial();
    cout << power(Mint(10), m) - Mint(2) * power(Mint(9), m) + power(Mint(8), m) << endl;
}

void fast_io()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

#ifdef DHRUV_GHEEWALA
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    freopen("debug.txt", "w", stderr);
#endif
}

Measured memory_bytes: 3656