Problem:
Score : 300 points

Problem Statement

There is a staircase with N steps. Takahashi is now standing at the foot of the stairs, that is, on the 0-th step.
He can climb up one or two steps at a time.

However, the treads of the a_1-th, a_2-th, a_3-th, \ldots, a_M-th steps are broken, so it is dangerous to set foot on those steps.

How many are there to climb up to the top step, that is, the N-th step, without setting foot on the broken steps?
Find the count modulo 1\ 000\ 000\ 007.

Constraints

1 \leq N \leq 10^5

0 \leq M \leq N-1

1 \leq a_1 < a_2 < ... < a_M \leq N-1

Input

Input is given from Standard Input in the following format:

N M
a_1
a_2
.
.
.
a_M

Output

Print the number of ways to climb up the stairs under the condition, modulo 1\ 000\ 000\ 007.

Sample Input 1

6 1
3

Sample Output 1

4

There are four ways to climb up the stairs, as follows:

0 \to 1 \to 2 \to 4 \to 5 \to 6

0 \to 1 \to 2 \to 4 \to 6

0 \to 2 \to 4 \to 5 \to 6

0 \to 2 \to 4 \to 6

Sample Input 2

10 2
4
5

Sample Output 2

0

There may be no way to climb up the stairs without setting foot on the broken steps.

Sample Input 3

100 5
1
23
45
67
89

Sample Output 3

608200469

Be sure to print the count modulo 1\ 000\ 000\ 007.

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 proconio::input;
use modint::ModInt;

fn main() {
    input! {
        n: usize,
        m: usize,
        a: [usize; m],
    }

    let mut corrupted = vec![false; n + 1];
    for a_i in a {
        corrupted[a_i] = true;
    }
    let corrupted = corrupted;

    let mut dp = vec![ModInt::from(0); n + 1];
    dp[0] = ModInt::from(1);
    for i in 0..=n {
        if corrupted[i] {
            continue;
        }

        if i >= 1 {
            let tmp = dp[i - 1];
            dp[i] += tmp;
        }
        if i >= 2 {
            let tmp = dp[i - 2];
            dp[i] += tmp;
        }
    }

    println!("{}", dp[n].0);
}

mod modint {
    use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};

    pub const MODULO: usize = 1_000_000_007;
    // pub const MODULO: usize = 11;

    fn positive_rem(a: isize, b: usize) -> usize {
        let b = b as isize;
        let mut value = a % b;
        if value < 0 {
            value += b;
        }
        // TODO: TryFrom
        value as usize
    }

    /// Return (x, y) s.t. ax + by = d where d = gcd(a, b)
    #[allow(unused)]
    pub fn ext_gcd(a: usize, b: usize) -> (isize, isize) {
        if b == 0 {
            return (1, 0);
        }

        let q = (a / b) as isize;
        let r = a % b;
        let (x1, y1) = ext_gcd(b, r);
        (y1, x1 - q * y1)
    }

    #[derive(Debug, Copy, Clone)]
    pub struct ModInt(pub usize);

    impl From<usize> for ModInt {
        fn from(n: usize) -> ModInt {
            ModInt(n % MODULO)
        }
    }

    impl From<isize> for ModInt {
        fn from(n: isize) -> ModInt {
            // TODO: use TryFrom
            ModInt(positive_rem(n, MODULO as usize))
        }
    }

    impl From<i32> for ModInt {
        fn from(n: i32) -> ModInt {
            // TODO: use TryFrom
            ModInt(positive_rem(n as isize, MODULO as usize))
        }
    }

    impl ModInt {
        #[allow(unused)]
        pub fn pow(self, p: usize) -> ModInt {
            if self == ModInt::from(0) {
                return ModInt::from(0);
            }
            if p == 0 {
                return ModInt::from(1);
            }

            if p % 2 == 0 {
                let half = self.pow(p / 2);
                half * half
            } else {
                self.pow(p - 1) * self
            }
        }

        // when MODULO is prime
        #[allow(unused)]
        pub fn inv(self) -> ModInt {
            let (x, _) = ext_gcd(self.0 as usize, MODULO as usize);
            ModInt::from(x)
        }
    }

    impl Add for ModInt {
        type Output = ModInt;

        fn add(self, other: ModInt) -> ModInt {
            ModInt::from(self.0 + other.0)
        }
    }

    impl Sub for ModInt {
        type Output = ModInt;

        fn sub(self, other: ModInt) -> ModInt {
            ModInt::from(self.0 as isize - other.0 as isize)
        }
    }

    impl Mul for ModInt {
        type Output = ModInt;

        fn mul(self, other: ModInt) -> ModInt {
            ModInt::from(self.0 * other.0)
        }
    }

    impl Neg for ModInt {
        type Output = ModInt;

        fn neg(self) -> Self::Output {
            ModInt::from(0) - self
        }
    }

    impl AddAssign for ModInt {
        fn add_assign(&mut self, other: Self) {
            *self = *self + other;
        }
    }

    impl MulAssign for ModInt {
        fn mul_assign(&mut self, other: Self) {
            *self = *self * other;
        }
    }

    impl SubAssign for ModInt {
        fn sub_assign(&mut self, other: Self) {
            *self = *self - other;
        }
    }

    impl PartialEq for ModInt {
        fn eq(&self, &other: &Self) -> bool {
            self.0 == other.0
        }
    }

    impl Eq for ModInt {}

    #[derive(Debug)]
    pub struct ModIntUtil {
        factorial: Vec<ModInt>,
        factorial_inv: Vec<ModInt>,
        inv: Vec<ModInt>,
    }

    impl ModIntUtil {
        #[allow(unused)]
        pub fn new() -> ModIntUtil {
            ModIntUtil {
                factorial: vec![ModInt::from(1), ModInt::from(1)],
                factorial_inv: vec![ModInt::from(1), ModInt::from(1)],
                inv: vec![ModInt::from(0), ModInt::from(1)],
            }
        }

        fn calc_cache(&mut self, n: usize) {
            let len = self.factorial.len();
            if len < n + 1 {
                for i in len..(n + 1) {
                    let prev = *self.factorial.last().unwrap();
                    self.factorial.push(prev * ModInt::from(i));

                    let inv_i = -self.inv[MODULO % i] * ModInt::from(MODULO / i);
                    self.inv.push(inv_i);

                    let prev = *self.factorial_inv.last().unwrap();
                    self.factorial_inv.push(prev * self.inv[i]);
                }
            }
        }

        #[allow(unused)]
        pub fn factorial(&mut self, n: usize) -> ModInt {
            self.calc_cache(n);
            self.factorial[n]
        }

        #[allow(unused)]
        pub fn factorial_inv(&mut self, n: usize) -> ModInt {
            self.calc_cache(n);
            self.factorial_inv[n]
        }

        // when MODULO is prime
        #[allow(unused)]
        pub fn binom_coef(&mut self, n: usize, k: usize) -> ModInt {
            if n < k {
                return ModInt::from(0);
            }

            self.calc_cache(n);
            self.factorial[n] * self.factorial_inv[k] * self.factorial_inv[n - k]
        }

        #[allow(unused)]
        fn perm(&mut self, n: usize, k: usize) -> ModInt {
            if n < k {
                return ModInt::from(0);
            }
            self.factorial(n) * self.factorial_inv(n - k)
        }

        // Not tested!!
        #[allow(unused)]
        pub fn multi_coef(&mut self, v: &[usize]) -> ModInt {
            let n = v.iter().sum();
            self.calc_cache(n);

            let mut ret = ModInt::from(1);
            ret *= self.factorial[n];
            for v_i in v {
                ret *= self.factorial_inv[*v_i];
            }

            ret
        }
    }
}
*/

fn main() {
    let exe = "/tmp/binBDEF6D12";
    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>";