#include <iostream>
#include <cassert>

template<int Modulus>
struct modint {
	using value_type = int;

	static constexpr int mod = Modulus;
	static_assert(mod > 1, "Modulus must be greater than 1");

private :
	value_type x;

	template<class T>
	static constexpr value_type normalize (T value) noexcept {
		if (value < 0) {
			value = (-value) % mod;
			return (value ? value : mod - value);
		}
		return (value % mod);
	}

public :
	explicit constexpr modint () noexcept : x(0) { }

	template<class T>
	constexpr modint (T value) noexcept : x(normalize(value)) { }

	constexpr modint operator+ () const noexcept {
		return modint(*this);
	}

	constexpr modint operator- () noexcept {
		if (x != 0) x = mod - x;
		return modint(*this);
	}

	constexpr modint &operator+= (const modint &p) noexcept {
		if ((x += p.x) >= mod) x -= mod;
		return (*this);
	}

	constexpr modint &operator-= (const modint &p) noexcept {
		if ((x += mod - p.x) >= mod) x -= mod;
		return (*this);
	}

	constexpr modint &operator*= (const modint &p) noexcept {
		x = (int)(1LL * x * p.x % mod);
		return (*this);
	}

	constexpr modint &operator/= (const modint &p) noexcept {
		return ((*this) *= p.inverse());
	}

	constexpr modint operator+ (const modint &p) const noexcept {
		return (modint(*this) += p);
	}

	constexpr modint operator- (const modint &p) const noexcept {
		return (modint(*this) -= p);
	}

	constexpr modint operator* (const modint &p) const noexcept {
		return (modint(*this) *= p);
	}

	constexpr modint operator/ (const modint &p) const noexcept {
		return (modint(*this) /= p);
	}

	constexpr bool operator== (const modint &p) const noexcept {
		return (x == p.x);
	}

	constexpr bool operator!= (const modint &p) const noexcept {
		return (x != p.x);
	}

	constexpr modint pow (long long exp) const noexcept {
		modint value(1), buff(x);
		while (exp) {
			if (exp & 1) value *= buff;
			buff *= buff;
			exp >>= 1;
		}
		return value;
	}

	constexpr modint inverse () const noexcept {
		return pow(mod - 2);
	}

	friend std::ostream &operator<< (std::ostream &os, const modint &p) {
		return (os << p.x);
	}

	friend std::istream &operator>> (std::istream &is, modint &p) {
		long long v;
		is >> v;
		p = modint(v);
		return (is);
	}

};

#include <vector>

template<int mod>
struct combination {
private :
    std::vector<modint<mod>> fact, ifact;
public : 
    combination(int n) : fact(n + 1), ifact(n + 1) {
        fact[0] = 1;
        for (int i = 1; i < n + 1; i++) fact[i] = (fact[i - 1] * i);
        ifact[n] = fact[n].inverse();
        for (int i = n; i > 0; i--) ifact[i - 1] = ifact[i] * i;
    }
    
	modint<mod> operator() (int n, int r) {
        if (r < 0 or r > n) return 0;
        return fact[n] * ifact[n - r] * ifact[r];
    }

    constexpr const modint<mod> &operator[] (int i) const {
        return fact[i];
    }

};

constexpr int MOD = 1'000'000'007;
constexpr int MAX = 1'000'100;
using mint = modint<MOD>;

int main() {
	combination<MOD> binom(MAX);
	int n;
	std::cin >> n;
	
	mint value1 = mint(8).pow(n);
	for (int i = 1; i <= n; i++) {
		value1 += binom(n, i) * mint(8).pow(n - i);
		value1 += binom(n, i) * mint(8).pow(n - i);
	}
	
	mint ans = mint(10).pow(n) - value1;
	std::cout << ans << '\n';
	
	return 0;
}

Measured memory_bytes: 10996