#include <bits/stdc++.h>
#define ll long long
#define ls id << 1
#define rs id << 1 | 1
#define mem(array, value, size, type) memset(array, value, ((size) + 5) * sizeof(type))
#define memarray(array, value) memset(array, value, sizeof(array))
#define fillarray(array, value, begin, end) fill((array) + (begin), (array) + (end) + 1, value)
#define fillvector(v, value) fill((v).begin(), (v).end(), value)
#define pb(x) push_back(x)
#define st(x) (1LL << (x))
#define pii pair<int, int>
#define mp(a, b) make_pair((a), (b))
#define Flush fflush(stdout)
#define vecfirst (*vec.begin())
#define veclast (*vec.rbegin())
#define vecall(v) (v).begin(), (v).end()
#define vecupsort(v) (sort((v).begin(), (v).end()))
#define vecdownsort(v, type) (sort(vecall(v), greater<type>()))
#define veccmpsort(v, cmp) (sort(vecall(v), cmp))
using namespace std;
const int N = 500050;
const int inf = 0x3f3f3f3f;
const ll llinf = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
clock_t TIME__START, TIME__END;
void program_end()
{
#ifdef ONLINE
    printf("\nTime used: %.6lf(s)\n", ((double)TIME__END - TIME__START) / 1000);
    system("pause");
#endif
}
// 该模板不可实现负数
// vector 中从高位到低位
// 即输出时需要倒序输出
struct Wint : vector<ll>
{
    Wint(ll n = 0)
    {
        push_back(n);
        check();
    }
    Wint &check()
    {
        while (!empty() && !back())
            pop_back();
        if (empty())
            return *this;
        for (int i = 1; i < (int)size(); ++i)
        {
            (*this)[i] += (*this)[i - 1] / 10;
            (*this)[i - 1] %= 10;
        }
        while (back() >= 10)
        {
            push_back(back() / 10);
            (*this)[size() - 2] %= 10;
        }
        return *this;
    }
};

istream &operator>>(istream &is, Wint &n)
{
    string s;
    is >> s;
    n.clear();
    for (int i = (int)s.size() - 1; i >= 0; --i)
        n.push_back(s[i] - '0');
    return is;
}
ostream &operator<<(ostream &os, const Wint &n)
{
    if (n.empty())
        os << 0;
    for (int i = (int)n.size() - 1; i >= 0; --i)
        os << n[i];
    return os;
}

bool operator!=(const Wint &a, const Wint &b)
{
    if (a.size() != b.size())
        return 1;
    for (int i = (int)a.size() - 1; i >= 0; --i)
        if (a[i] != b[i])
            return 1;
    return 0;
}
bool operator==(const Wint &a, const Wint &b)
{
    return !(a != b);
}
bool operator<(const Wint &a, const Wint &b)
{
    if (a.size() != b.size())
        return a.size() < b.size();
    for (int i = (int)a.size() - 1; i >= 0; --i)
        if (a[i] != b[i])
            return a[i] < b[i];
    return 0;
}
bool operator>(const Wint &a, const Wint &b)
{
    return b < a;
}
bool operator<=(const Wint &a, const Wint &b)
{
    return !(a > b);
}
bool operator>=(const Wint &a, const Wint &b)
{
    return !(a < b);
}

Wint &operator+=(Wint &a, const Wint &b)
{
    if (a.size() < b.size())
        a.resize(b.size());
    for (int i = 0; i != (int)b.size(); ++i)
        a[i] += b[i];
    return a.check();
}
Wint operator+(Wint a, const Wint &b)
{
    return a += b;
}

Wint &operator-=(Wint &a, Wint b)
{
    if (a < b)
        swap(a, b);
    for (int i = 0; i != (int)b.size(); a[i] -= b[i], ++i)
        if (a[i] < b[i])
        {
            int j = i + 1;
            while (!a[j])
                ++j;
            while (j > i)
            {
                --a[j];
                a[--j] += 10;
            }
        }
    return a.check();
}
Wint operator-(Wint a, const Wint &b)
{
    return a -= b;
}

Wint operator*(const Wint &a, const Wint &b)
{
    Wint n;
    if (a.empty() || b.empty())
        return Wint(0);
    n.assign(a.size() + b.size() - 1, 0);
    for (int i = 0; i != (int)a.size(); ++i)
        for (int j = 0; j != (int)b.size(); ++j)
            n[i + j] += a[i] * b[j];
    return n.check();
}
Wint &operator*=(Wint &a, const Wint &b)
{
    return a = a * b;
}

Wint divmod(Wint &a, const Wint &b)
{
    Wint ans;
    for (int t = (int)a.size() - (int)b.size(); a >= b; --t)
    {
        Wint d;
        d.assign(t + 1, 0);
        d.back() = 1;
        Wint c = b * d;
        while (a >= c)
        {
            a -= c;
            ans += d;
        }
    }
    return ans;
}
Wint operator/(Wint a, const Wint &b)
{
    return divmod(a, b);
}
Wint &operator/=(Wint &a, const Wint &b)
{
    return a = a / b;
}
Wint &operator%=(Wint &a, const Wint &b)
{
    divmod(a, b);
    return a;
}
Wint operator%(Wint a, const Wint &b)
{
    return a %= b;
}
Wint Wpow(Wint a, Wint b)
{
    Wint ret = 1;
    while (b != 0)
    {
        if (b % 2 == 1)
            ret = ret * a;
        a = a * a;
        b /= 2;
    }
    return ret;
}
Wint Wpow(Wint a, Wint b, Wint p)
{
    Wint ret = 1;
    while (b != 0)
    {
        if (b % 2 == 1)
            ret = ret * a % p;
        a = a * a % p;
        b /= 2;
    }
    return ret;
}
Wint Wgcd(Wint a, Wint b)
{
    return (b == 0) ? a : Wgcd(b, a % b);
}
Wint n;

inline void solve()
{
    cin >> n;
    Wint ans1 = Wpow(10, n, MOD);
    Wint ans2 = Wpow(9, n, MOD) * 2 % MOD;
    Wint ans4 = Wpow(8, n, MOD);
    Wint ans5 = (ans1 + ans4 + MOD - ans2) % MOD;
    cout << ans5 << endl;
}

int main()
{
    TIME__START = clock();
    int Test = 1;
    // scanf("%d", &Test);
    while (Test--)
        solve();
    TIME__END = clock();
    program_end();
    return 0;
}

Measured memory_bytes: 3688