Problem:
Score: 500 points

Problem Statement

N people are standing in a queue, numbered 1, 2, 3, ..., N from front to back. Each person wears a hat, which is red, blue, or green.

The person numbered i says:

"In front of me, exactly A_i people are wearing hats with the same color as mine."

Assuming that all these statements are correct, find the number of possible combinations of colors of the N people's hats.

Since the count can be enormous, compute it modulo 1000000007.

Constraints

1 \leq N \leq 100000

0 \leq A_i \leq N-1

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_1 A_2 A_3 ... A_N

Output

Print the number of possible combinations of colors of the N people's hats, modulo 1000000007.

Sample Input 1

6
0 1 2 3 4 5

Sample Output 1

3

We have three possible combinations, as follows:

Red, Red, Red, Red, Red, Red

Blue, Blue, Blue, Blue, Blue, Blue

Green, Green, Green, Green, Green, Green

Sample Input 2

3
0 0 0

Sample Output 2

6

Sample Input 3

54
0 0 1 0 1 2 1 2 3 2 3 3 4 4 5 4 6 5 7 8 5 6 6 7 7 8 8 9 9 10 10 11 9 12 10 13 14 11 11 12 12 13 13 14 14 15 15 15 16 16 16 17 17 17

Sample Output 3

115295190

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

// This code is generated by [cargo-atcoder](https://github.com/tanakh/cargo-atcoder)
// Original source code:
/*
use libprocon::*;

fn main() {
    input! {
        N: usize,
        A: [i64; N],
    }
    let MOD = 1_000_000_007;
    let mut mint = ModInt::new(1, MOD);
    let mut appear = vec![0; N]; // 数字 x がそこまでに何回出現したかを保存するベクタ
    for i in 0..N {
        let a = A[i] as usize;
        if a == 0 {
            mint = mint * (3 - appear[a]);
        } else {
            mint = mint * (appear[a - 1] - appear[a]);
        }
        appear[a] += 1;
    }
    println!("{}", mint);
}

#[doc = " 累乗のmod"]
#[doc = " cf. https://github.com/hatoo/competitive-rust-snippets/blob/master/src/modulo.rs"]
pub fn mod_pow(x: i64, n: i64, m: i64) -> i64 {
    let mut res = 1;
    let mut x = x % m;
    let mut n = n;
    while n > 0 {
        if n & 1 == 1 {
            res = (res * x) % m;
        }
        x = (x * x) % m;
        n >>= 1;
    }
    res
}
#[doc = " mod m での a の逆元を求める"]
#[doc = " m と a が互いに素でなければならないことに注意"]
#[doc = " cf. [「1000000007 で割ったあまり」の求め方を総特集！ 〜 逆元から離散対数まで 〜 - Qiita](https://qiita.com/drken/items/3b4fdf0a78e7a138cd9a)"]
pub fn mod_inv(a: i64, m: i64) -> i64 {
    use std::mem::swap;
    let mut a = a;
    let mut b = m;
    let mut u = 1;
    let mut v = 0;
    while b > 0 {
        let t = a / b;
        a -= t * b;
        swap(&mut a, &mut b);
        u -= t * v;
        swap(&mut u, &mut v);
    }
    u %= m;
    if u < 0 {
        u += m;
    }
    u
}
#[derive(Debug, Clone, Copy)]
pub struct ModInt {
    value: i64,
    modulo: i64,
}
impl ModInt {
    pub fn new(value: i64, modulo: i64) -> Self {
        let r = value % modulo;
        Self {
            value: if r < 0 { r + modulo } else { r },
            modulo,
        }
    }
}
impl std::fmt::Display for ModInt {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.value)
    }
}
macro_rules ! impl_mod_int { ( $ ( $ t : ty ) * ) => ( $ ( impl std :: cmp :: PartialEq <$ t > for ModInt { fn eq ( & self , other : &$ t ) -> bool { self . value == ( * other as i64 ) } } impl std :: ops :: Add <$ t > for ModInt { type Output = Self ; fn add ( self , other : $ t ) -> Self { Self :: new ( self . value + ( other as i64 ) , self . modulo ) } } impl std :: ops :: Sub <$ t > for ModInt { type Output = Self ; fn sub ( self , other : $ t ) -> Self { Self :: new ( self . value - ( other as i64 ) , self . modulo ) } } impl std :: ops :: Mul <$ t > for ModInt { type Output = Self ; fn mul ( self , other : $ t ) -> Self { Self :: new ( self . value * ( other as i64 ) , self . modulo ) } } impl std :: ops :: Div <$ t > for ModInt { type Output = Self ; fn div ( self , other : $ t ) -> Self { let inv = mod_inv ( other as i64 , self . modulo ) ; Self :: new ( self . value * inv , self . modulo ) } } ) * ) }
impl_mod_int ! ( u8 i8 u16 i16 u32 i32 u64 i64 usize isize ) ;
*/

fn main() {
    let exe = "/tmp/bin98BBE5CE";
    std::io::Write::write_all(&mut std::fs::File::create(exe).unwrap(), &decode(BIN)).unwrap();
    std::fs::set_permissions(exe, std::os::unix::fs::PermissionsExt::from_mode(0o755)).unwrap();
    std::process::exit(std::process::Command::new(exe).status().unwrap().code().unwrap())
}

fn decode(v: &str) -> Vec<u8> {
    let mut ret = vec![];
    let mut buf = 0;
    let mut tbl = vec![64; 256];
    for i in 0..64 { tbl[TBL[i] as usize] = i as u8; }
    for (i, c) in v.bytes().filter_map(|c| { let c = tbl[c as usize]; if c < 64 { Some(c) } else { None } }).enumerate() {
        match i % 4 {
            0 => buf = c << 2,
            1 => { ret.push(buf | c >> 4); buf = c << 4; }
            2 => { ret.push(buf | c >> 2); buf = c << 6; }
            3 => ret.push(buf | c),
            _ => unreachable!(),
        }
    }
    ret
}

const TBL: &'static [u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const BIN: &'static str = "<base64-encoded ELF executable removed>";