#include <bits/stdc++.h>

using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using usize = std::size_t;
using namespace std;

#define rep(i, max) for(i32 i = 0; i < (i32)max; ++i)
#define loop while(true)
#define allOf(collection) collection.begin(), collection.end()

unique_ptr<string> readLine() { unique_ptr<string> line(new string()); getline(cin, *line); return line; }
template<typename T1, typename T2> pair<T1, T2> readPair() { T1 res1; cin >> res1; T2 res2; cin >> res2; readLine(); return make_pair(res1, res2);}
template<typename T> unique_ptr<vector<T>> readVector(usize num, bool isForIndex = false) { unique_ptr<vector<T>> list(new vector<T>(num)); rep(i, num) { cin >> (*list)[i]; if(isForIndex) --(*list)[i]; } readLine(); return list; }
void readValues() { readLine(); }
template<typename H, typename... T> void readValues(H& head, T&&... tails){ H a; cin >> a; head = a; readValues(forward<T>(tails)...); }
void writeLine() { cout << endl; }
template<typename T> void write(const T& arg) { cout << arg; }
template<typename T> void writeLine(const vector<T>& arg){ if(arg.empty()) { writeLine(); return; } write(arg[0]); for(int i = 1; i < arg.size(); ++i){ write(" "); write(arg[i]); } writeLine(); }
template<typename T> void writeLine(const T& arg) { cout << arg << endl; }
void recursiveCombination(vector<i32>& indexes, i32 s, i32 rest, function<void(vector<i32>&)> f) { if (rest == 0) { f(indexes); } else { if (s < 0) return; recursiveCombination(indexes, s - 1, rest, f); indexes[rest - 1] = s; recursiveCombination(indexes, s - 1, rest - 1, f); } }
void foreachWithCombination(i32 n, i32 k, function<void(vector<i32>&)> f) { auto indexes = vector<i32>(k); recursiveCombination(indexes, n - 1, k, f); }
void foreachWithPermutaton(i32 n, function<void(vector<i32>&)> f) { auto indexes = vector<i32>(); indexes.reserve(n); rep(i, (usize)n) indexes.push_back(i); do f(indexes); while (next_permutation(allOf(indexes))); }
void foreachWithPermutaton(i32 n, i32 k, function<void(vector<i32>&)> f){ foreachWithCombination(n, k, [=](vector<i32>& combIndexes){ foreachWithPermutaton(k, [=](vector<i32>& permIndexes){ auto indexes = vector<i32>(); indexes.reserve(k); rep(i, (usize)k){ indexes.push_back(combIndexes[permIndexes[i]]); } f(indexes); }); }); }
void program();
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    program();
    cin.get();
}

constexpr i64 mod = 1e9 + 7;
class ModNumber;
inline ModNumber operator+(const ModNumber left, const ModNumber right);
inline ModNumber operator-(const ModNumber left, const ModNumber right);
inline ModNumber operator*(const ModNumber left, const ModNumber right);
inline ModNumber operator/(const ModNumber left, const ModNumber right);
class ModNumber {
    i64 _num;
    static inline i32 _ncrMaximum;
    static inline vector<i64> _factorial, _factorialInverse, _inverse;
    static i64 gcdExtended(i64 a, i64 b, i64& x, i64& y) {
        if(b == 0) {
            x = 1;
            y = 0;
            return a;
        } else{
            i64 d = gcdExtended(b, a % b, y, x);
            y -= a / b * x;
            return d;
        }
    }
public: //static
    static void prepareNcr(i32 maximumValue) {
        if(maximumValue <= _ncrMaximum) return;
        maximumValue = max(2, maximumValue);
        _factorial.resize(maximumValue);
        _factorialInverse.resize(maximumValue);
        _inverse.resize(maximumValue);
        if(_ncrMaximum <= 2) {
            _factorial[0] = _factorial[1] = 1;
            _factorialInverse[0] = _factorialInverse[1] = 1;
            _inverse[1] = 1;
        }
        for(i32 i = max(2, _ncrMaximum); i < maximumValue; ++i) {
            _factorial[i] = _factorial[i - 1] * i % mod;
            _inverse[i] = mod - _inverse[mod % i] * (mod / i) % mod;
            _factorialInverse[i] = _factorialInverse[i - 1] * _inverse[i] % mod;
        }
        _ncrMaximum = maximumValue;
    }
    static ModNumber inverse(i64 a) {
        if(a < _ncrMaximum) return ModNumber(_inverse[a]);
        i64 x, y;
        gcdExtended(a, mod, x, y);
        return (mod + x % mod) % mod;
    }
    static ModNumber inverse(ModNumber a) {
        if(a._num < _ncrMaximum) return ModNumber(_inverse[a._num]);
        i64 x, y;
        gcdExtended(a._num, mod, x, y);
        return (mod + x % mod) % mod;
    }
    static ModNumber ncr(i32 n, i32 r) {
        if(n < r || n < 0 || r < 0) return 0;
        if(n >= _ncrMaximum || r >= _ncrMaximum) prepareNcr(max(n, r) + 1);
        return _factorial[n] * (_factorialInverse[r] * _factorialInverse[n - r] % mod) % mod;
    }
    static ModNumber pow(i64 a, i64 n) {
        i64 result = 1;
        for(a %= mod; n; a = a * a % mod, n >>= 1) 
            if(n & 1) result = result * a % mod;
        return ModNumber(result);
    }

public:
    ModNumber(i64 n) {
        _num = n % mod;
    }
    inline i64 get() const{
        return _num;
    }
    ModNumber& operator+=(const ModNumber left) {
        this->_num += left._num; this->_num %= mod;
        return *this;
    }
    ModNumber& operator-=(const ModNumber left) {
        if(this->_num < left._num) this->_num += mod;
        _num -= left._num; _num %= mod;
        return *this;
    }
    ModNumber& operator*=(const ModNumber left) {
        this->_num *= left._num; this->_num %= mod;
        return *this;
    }
    ModNumber& operator/=(const ModNumber left) {
        *this *= inverse(left); this->_num %= mod;
        return *this;
    }
};
inline ModNumber operator+(const ModNumber left, const ModNumber right) {
    return ModNumber(left.get() + right.get());
}
inline ModNumber operator-(const ModNumber left, const ModNumber right) {
    return ModNumber(left.get() < right.get() ? left.get() - right.get() + mod : left.get() - right.get());
}
inline ModNumber operator*(const ModNumber left, const ModNumber right) {
    return ModNumber((left.get() * right.get()));
}
inline ModNumber operator/(const ModNumber left, const ModNumber right) {
    return left * ModNumber::inverse(right);
}
ostream& operator<<(ostream& os, const ModNumber& data) {
    os << data.get();
    return os;
}


void program() {
    i32 n;
    readValues(n);
    if(n == 1) {
        writeLine(0);
        return;
    }

    auto res1 = ModNumber::pow(10, n);
    auto res2 = ModNumber::pow(9, n);
    auto res3 = ModNumber::pow(8, n);
    writeLine(res1 - 2 * res2 + res3);
}

Measured memory_bytes: 3604