Problem:
Score : 300 points

Problem Statement

How many integer sequences A_1,A_2,\ldots,A_N of length N satisfy all of the following conditions?

0 \leq A_i \leq 9

There exists some i such that A_i=0 holds.

There exists some i such that A_i=9 holds.

The answer can be very large, so output it modulo 10^9 + 7.

Constraints

1 \leq N \leq 10^6

N is an integer.

Input

Input is given from Standard Input in the following format:

N

Output

Print the answer modulo 10^9 + 7.

Sample Input 1

2

Sample Output 1

2

Two sequences \{0,9\} and \{9,0\} satisfy all conditions.

Sample Input 2

1

Sample Output 2

0

Sample Input 3

869121

Sample Output 3

2511445

Solution in Rust (1.42.0) (judge verdict: Accepted)

use proconio::input;
use proconio::marker::Chars;
#[allow(unused_imports)]
use std::cmp::{max, min};
#[allow(unused)]
const ALPHA_SMALL: [char; 26] = [
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
    't', 'u', 'v', 'w', 'x', 'y', 'z',
];
#[allow(unused)]
const ALPHA: [char; 26] = [
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
    'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
];
macro_rules! maxs {
    ($x:expr, $($y:expr), *) => {{
        let mut ret = $x;
        $(
            ret = max(ret, $y);
        )*
        ret
    }};
}
fn main() {
    input!(N: usize);
    if N < 2 {
        println!("0");
        return;
    }
    let tot = Mod::new(10).pow(N);
    let sub1 = Mod::new(8).pow(N);
    let sub2 = Mod::new(9).pow(N);

    let ans = tot - sub2 - sub2 + sub1;

    println!("{}", ans.unwrap());
}

use std::cmp::Ord;
use std::cmp::*;

const MOD: usize = 1_000_000_000 + 7;

#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
struct Mod {
    val: usize,
}

// 和を定義
impl std::ops::Add for Mod {
    type Output = Mod;
    // O(1)
    fn add(self, other: Mod) -> Mod {
        Mod {
            val: (self.val + other.val) % MOD,
        }
    }
}

// 差を定義
impl std::ops::Sub for Mod {
    type Output = Mod;

    // O(1)
    fn sub(self, other: Mod) -> Mod {
        Mod {
            val: (self.val + MOD - other.val) % MOD,
        }
    }
}

// 積を定義
impl std::ops::Mul for Mod {
    type Output = Mod;

    // O(1)
    fn mul(self, other: Mod) -> Mod {
        Mod {
            val: (self.val * other.val) % MOD,
        }
    }
}

// 加法単位元
impl std::ops::Neg for Mod {
    type Output = Mod;

    // O(1)
    fn neg(self) -> Mod {
        Mod {
            val: MOD - self.val,
        }
    }
}

// 逆元を定義
// フェルマーの小定理により実装
impl std::ops::Div for Mod {
    type Output = Mod;

    //O(logN)
    fn div(self, other: Mod) -> Mod {
        self * other.inv()
    }
}

impl Mod {
    // コンストラクター
    fn new(n: usize) -> Mod {
        Mod { val: n % MOD }
    }

    // 加法単位元
    fn new_zero() -> Mod {
        Mod { val: 0 }
    }

    // 乗法単位元
    fn new_one() -> Mod {
        Mod { val: 1 }
    }

    // 加法逆元
    // 上記にて定義

    // 乗法逆元
    fn inv(self) -> Mod {
        if self.val == 0 {
            panic!("zero divide");
        }
        self.pow(MOD - 2)
    }

    // 累乗を定義
    // O(logN)
    fn pow(self, n: usize) -> Mod {
        let mut res = 1;
        let mut a = self.unwrap();
        let mut n = n;

        while n > 0 {
            if n % 2 == 0 {
                a = a * a;
                n /= 2;
            } else {
                res = res * a;
                a = a * a;
                n /= 2;
            }
            res %= MOD;
            a %= MOD;
        }
        Mod::new(res)
    }

    // 最大公約数
    // O(logN)
    fn gcd(self, other: Mod) -> usize {
        let mut x = self.val;
        let mut y = other.val;
        while y != 0 {
            let t = y;
            y = x % y;
            x = t;
        }
        x
    }

    // 階乗
    // O(N)
    fn fact(self) -> Mod {
        let mut res = 1;
        for i in 1..self.val + 1 {
            res *= i;
            res %= MOD;
        }

        Mod::new(res)
    }

    // 順列
    fn perm(self, other: Mod) -> Mod {
        let mut res = Mod::new_one();
        for x in (self.val - other.val + 1)..self.val + 1 {
            res = res * Mod::new(x);
        }

        res
    }

    // 組み合わせ O(N)
    fn conb(self, other: Mod) -> Mod {
        if self < other {
            return Mod::new_zero();
        }
        self.fact() / (other.fact() * (self - other).fact())
    }
    fn unwrap(self) -> usize {
        self.val % MOD
    }
}

#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
struct ModConb {
    fact: Vec<Mod>,
    inv_fact: Vec<Mod>,
    n: usize,
}

impl ModConb {
    // O(N)
    fn new(n: usize) -> ModConb {
        let mut fact = vec![Mod::new_one(); n + 1];
        let mut inv_fact = vec![Mod::new_one(); n + 1];
        for i in 1..(n + 1) {
            fact[i] = fact[i - 1] * Mod::new(i);
            inv_fact[i] = inv_fact[i - 1] / Mod::new(i);
        }

        ModConb {
            fact: fact,
            inv_fact: inv_fact,
            n: n + 1,
        }
    }
    // O(1)
    fn get(&self, n: usize, r: usize) -> Mod {
        if r <= n {
            self.fact[n] * self.inv_fact[r] * self.inv_fact[n - r]
        } else {
            Mod::new_zero()
        }
    }
}