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 C# (Mono 4.6.2.0) (judge verdict: Runtime Error)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Collections;
static class Extensions
{
    public static int ToInt(this string s) => int.Parse(s);
    public static long ToLong(this string s) => long.Parse(s);
    public static char ToChar(this string s) => char.Parse(s);
    public static double ToDouble(this string s) => double.Parse(s);
    public static int[] ToIntArray(this string s) => s.Replace(',', ' ').Split(' ').Select(x => x.ToInt()).ToArray();
    public static long[] ToLongArray(this string s) => s.Replace(',', ' ').Split(' ').Select(x => x.ToLong()).ToArray();
    public static double[] ToDoubleArray(this string s) => s.Replace(',', ' ').Split(' ').Select(x => x.ToDouble()).ToArray();
}

class Program
{
    static string[] ReadLines(int n) => Enumerable.Range(0, n).Select(s => Console.ReadLine()).ToArray();

    static void Main()
    {
        long xxxx = 1000000007;

        var nm = Console.ReadLine().Split().Select(s => long.Parse(s)).ToArray();

        long N = nm[0];
        long M = nm[1];

        long[] memo = new long[N + 1];
        //長さiの区間を移動するための組み合わせを先に求める
        memo[0] = 0;
        memo[1] = 1;
        memo[2] = 1;

        for (int i = 3; i < memo.Length; i++)
        {
            memo[i] = memo[i - 1] % xxxx + memo[i - 2] % xxxx;
            memo[i] %= xxxx;
        }

        var aList = Enumerable.Range(0, (int)M).Select(n => Console.ReadLine().ToLong()).Distinct().ToArray();


        for(int i = 0; i < aList.Length - 1; i++)
        {
            if (aList[i + 1] - aList[i] == 1)
            {
                Console.WriteLine(0);
                return;
            }
        }


        long current = 0;
        List<long> safeAreaList = new List<long>();

        for(int i = 0; i < aList.Length; i++)
        {
            //現在居る区画の最小
            var first = current;

            //現在居る区画の最大
            var last = aList[i] - 1;

            //現在居る区画の長さ
            var len = last - first + 1;

            safeAreaList.Add(len);
            current = aList[i] + 1;
        }
                

        //最後、N段目までがある        
        safeAreaList.Add(N - current + 1);

        long ans = 1;

        foreach(var x in safeAreaList)
        {
            ans *= memo[x];
            ans %= xxxx;
        }

        Console.WriteLine(ans);

    }
}