import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class Main {

	InputStream is;
	PrintWriter out;
	String INPUT = "";

	private static final long M = 1000000007L;

	void solve() {
		int n = ni();
		boolean a[] = new boolean[n + 1];
		long dp[] = new long[n + 1];
		int k = ni();
		for (int i = 0; i < k; i++) {
			int t = ni();
			a[t] = true;
		}
		dp[0] = 1;
		if (!a[1])
			dp[1] = 1;
		for (int i = 2; i <= n; i++) {
			if (!a[i])
				dp[i] = (dp[i - 1] + dp[i - 2]) % M;
		}
		out.println(dp[n]);
	}

	void run() throws Exception {
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		if (!INPUT.isEmpty())
			tr(System.currentTimeMillis() - s + "ms");
	}

	public static void main(String[] args) throws Exception {
		new Main().run();
	}

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte() {
		if (lenbuf == -1)
			throw new InputMismatchException();
		if (ptrbuf >= lenbuf) {
			ptrbuf = 0;
			try {
				lenbuf = is.read(inbuf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (lenbuf <= 0)
				return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) {
		return !(c >= 33 && c <= 126);
	}

	private int skip() {
		int b;
		while ((b = readByte()) != -1 && isSpaceChar(b))
			;
		return b;
	}

	private double nd() {
		return Double.parseDouble(ns());
	}

	private char nc() {
		return (char) skip();
	}

	private String ns() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != '
									// ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n) {
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while (p < n) {
			if (!(isSpaceChar(b)))
				buf[p++] = (char) b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m) {
		char[][] map = new char[n][];
		for (int i = 0; i < n; i++)
			map[i] = ns(m);
		return map;
	}

	private int[] na(int n) {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}

	private int[][] na(int n, int m) {
		int[][] a = new int[n][];
		for (int i = 0; i < n; i++)
			a[i] = na(m);
		return a;
	}

	private int ni() {
		int num = 0, b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl() {
		long num = 0;
		int b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') {
			minus = true;
			b = readByte();
		}

		while (true) {
			if (b >= '0' && b <= '9') {
				num = num * 10 + (b - '0');
			} else {
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private static void tr(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}
}


import java.util.Scanner;

public class Main {

	static long MOD = 1000000007;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);

		int N = sc.nextInt();
		int M = sc.nextInt();

		int[] broken =new int[M];

		for (int i = 0; i < M; i++) {
			broken[i] = sc.nextInt();
		}

		int[] dp=new int[N+1];
		dp[N] = 1;
		for (int i = N-1; i >= 0; i--) {
			boolean judge = false;
			for (int j = 0; j < M; j++) {
				if (broken[j] == i) judge = !judge;
			}
			if (judge) {
				continue;
			}else {
				int con = 0;
				//1段
				if (i+1 <= N) {
					con += dp[i+1] % MOD;
				}
				//2段
				if (i+2 <= N) {
					con += dp[i+2] % MOD;
				}
				dp[i] = Math.max(dp[i], con);
			}
		}

		System.out.println(dp[0]);

	}

}


import java.util.Scanner;

public class Main {
	static final long MOD = 1_000_000_007;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();

		boolean[] broken = new boolean[n];
		for (int i = 0; i < m; i++) {
			int a = sc.nextInt();
			a--;
			broken[a] = true;
		}

		long[] dp = new long[n];
		dp[0] = broken[0] ? 0 : 1;
		dp[1] = broken[1] ? 0 : 1 + dp[0];
		for (int i = 2 ; i < n; i++) {
			dp[i] = broken[i] ? 0 : (dp[i - 2] + dp[i - 1]) % MOD;
		}

//		System.out.println(Arrays.toString(dp));

		System.out.println(dp[n - 1]);

		sc.close();
	}
}


	import java.util.ArrayList;
	import java.util.Arrays;
	import java.util.Collections;
	import java.util.Comparator;
	import java.util.HashMap;
	import java.util.HashSet;
	import java.util.List;
	import java.util.Map;
	import java.util.Map.Entry;
	import java.util.PriorityQueue;
	import java.util.Queue;
	import java.util.Scanner;
	import java.util.Set;

	public class Main{

		public static void main(String[] args) {

			Scanner scanner = new Scanner(System.in);
			String[] t = scanner.nextLine().split(" ");
			int n = Integer.parseInt(t[0]);
			int m = Integer.parseInt(t[1]);
			HashSet<Integer> set = new HashSet<>();

			for(int i = 0; i < m;i++) {
				set.add(scanner.nextInt() - 1);
			}

			long mod = 1000000007;

			long[] dp = new long[n + 1];
			dp[0] = set.contains(0) ? 0 : 1;
			dp[1] = set.contains(1) ? dp[0] : dp[0] + 1;

			for(int i = 2; i < n; i++) {

				if(!set.contains(i)) {
					dp[i] = (dp[i - 1] + dp[i - 2]) % mod;
				}

			}

			System.out.println(dp[n - 1]);
		}
	}


#pragma GCC optimize ("O3")
#pragma GCC target ("avx")
//#include<bits/stdc++.h>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define Would
#define you
#define please

const int cm = 1 << 17;
char cn[cm], * ci = cn + cm, ct;
inline char getcha() {
	if (ci - cn == cm) { fread_unlocked(cn, 1, cm, stdin); ci = cn; }
	return *ci++;
}
inline int getint() {
	int A = 0;
	if (ci - cn + 16 > cm) while ((ct = getcha()) >= '0') A = A * 10 + ct - '0';
	else while ((ct = *ci++) >= '0') A = A * 10 + ct - '0';
	return A;
}

ll dp[100002];
int main() {
	//cin.tie(0);
	//ios::sync_with_stdio(false);

	int N = getint(), M = getint();
	if (M > N / 2) printf("0");
	else {
		rep(i, M) {
			dp[getint() + 1] = 1;
		}

		dp[0] = 0;
		dp[1] = 1;
		const ll mod = 1e9 + 7;
		int meyasu = 0;
		rep1(i, N) {
			if (!dp[i + 1]) {
				dp[i + 1] = dp[i] + dp[i - 1];
				meyasu++;
				if (meyasu >= 30) {
					dp[i] %= mod;
					dp[i + 1] %= mod;
					meyasu = 0;
				}
			}
			else dp[i + 1] = 0;
		}
		printf("%lld", dp[N + 1] % mod);
	}

	Would you please return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;

class FastIO {
    static const int BUF_SIZE = 1<<17;
    char inBuf[BUF_SIZE + 2];
    char *in, *inEnd = inBuf + BUF_SIZE;
    char outBuf[BUF_SIZE + 2];
    char *out, *outEnd = outBuf + BUF_SIZE;

    // stdinからBUFFER_SIZE分まで一気に読み込み、読み込んだサイズを返す
    size_t Load() {
        in = inBuf;
        size_t size = fread(inBuf, 1, BUF_SIZE, stdin);
        inBuf[size] = '\0';
        return size;
    }

    // lenの長さの文字列を出力した場合にバッファを超過するなら、バッファをリセットする
    void FlushIfNeed(int len) {
        if (out + len > outEnd) flush();
    }
    // lenの長さの文字列を入力した場合にバッファを超過するなら、バッファをリロードする
    void LoadIfNeed(int len) {
        if (in + len <= inEnd) return;

        unsigned long rest_size = inEnd - in;
        memcpy(inBuf, in, rest_size);
        size_t size = fread(inBuf + rest_size, 1, BUF_SIZE - rest_size, stdin);
        inBuf[rest_size + size] = '\0';
        in = inBuf;
    }

    char GetChar() {
        if (*in == '\0') {
            // これ以上読み込みできなかった場合はとりあえず0を返しておく
            if (Load() == 0) return 0;
        }
        return *in++;
    }
    void PutChar(char c) {
        FlushIfNeed(1);
        *out++ = c;
    }

    // 0以上の整数向けのscan
    template<typename T>
    void ScanNatural(T &x) {
        x = 0;

        // 数字が出てくるまでスキップ
        char c = GetChar();
        while(!isdigit(c)) c = GetChar();

        // 数値に変換
        LoadIfNeed(21);
        x = c&15;
        for (c = *in++; isdigit(c); c = *in++) {
            // c = '0'~'9' = 48~57 のとき、 c & 15 = c - '0'
            x = x * 10 + (c&15);
        }
    }
    // 負数を考慮する整数値scan
    template<typename T>
    void ScanInteger(T &x) {
        x = 0;

        // -記号か数字が出てくるまでスキップ
        char c = GetChar();
        while (c != '-' && !isdigit(c)) c = GetChar();

        // -記号の処理
        bool minus = c == '-';
        if (minus) c = GetChar();

        LoadIfNeed(21);
        x = c&15;
        for (c = *in++; isdigit(c); c = *in++) {
            x = x * 10 + (c&15);
        }
        if (minus) x = -x;
    }

    // 長さの分かっている文字列の出力(lenはBUFFER_SIZE以下)
    void PrintString(const char *s, size_t len) {
        char *new_out_pos = out + len;
        if (new_out_pos > outEnd) {
            flush();
            new_out_pos = out + len;
        }
        memcpy(out, s, len);
        out = new_out_pos;
    }
    // 非負整数値の出力
    template<typename T>
    void PrintNatural(T x) {
        char digit[21], *d_start, *d_end;
        d_start = d_end = digit + 21;
        // x = 0 の場合も0を出力する必要があるので、do whileで最低1桁は処理する
        do {
            // 上の桁に向かって処理していくので、表示順序と逆になる
            --d_start;
            *d_start = x % 10 + '0';
            x /= 10;
        } while (x != 0);

        // 出力
        PrintString(d_start, d_end - d_start);
    }
    // 整数値の出力
    template<typename T>
    void PrintInteger(T x) {
        if (x < 0) {
            PutChar('-');
            x = -x;
        }
        PrintNatural(x);
    }

public:
    // 出力バッファの中身をstdoutに流し出し、出力バッファをリセットする
    void flush() {
        fwrite(outBuf, out - outBuf, 1, stdout);
        out = outBuf;
    }

    FastIO() {
        in = inEnd;
        out = outBuf;
    }
    ~FastIO() {flush();}

    void scan(std::string &s) {
        char c = GetChar();
        while (!isprint(c)) c = GetChar();

        s.clear();
        for (; isprint(c); c = GetChar()) {
            s.push_back(c);
        }
    }
    void scan(ll &x) {ScanInteger(x);}
    void scan(int &x) {ScanInteger(x);}
    void scan(ull &x) {ScanNatural(x);}
    void scan(uint &x) {ScanNatural(x);}
    template<typename First, typename ... Ints>
    void scan(First &arg, Ints&... rest) {
        scan(arg);
        scan(rest...);
    }

    void print(const char *s) {
        size_t len = strlen(s);

        // バッファサイズより大きい文字列を出力しようとした場合は、stdoutにそのまま流す
        if (len > BUF_SIZE) {
            flush();
            printf("%s", s);
            return;
        }

        PrintString(s, len);
    }
    void print(std::string &s) {PrintString(s.c_str(), s.size());}
    void print(char c) {PutChar(c);}
    void print(int x) {PrintInteger(x);}
    void print(ll x) {PrintInteger(x);}
    void print(uint x) {PrintNatural(x);}
    void print(ull x) {PrintNatural(x);}
    template <class T>
    void print(std::vector<T> &v) {
        if (v.size() == 0) return;
        print(*v.begin());
        for (auto it = ++v.begin(); it != v.end(); ++it) {
            PutChar(' ');
            print(*it);
        }
    }
    template <class T>
    void print(std::vector< std::vector<T> > &grid) {
        if (grid.size() == 0) return;
        print(*grid.begin());
        for (auto it = ++grid.begin(); it != grid.end(); ++it) {
            PutChar('\n');
            print(*it);
        }
    }
    template<typename First, typename ... Ints>
    void print(First arg, Ints... rest) {
        print(arg);
        PutChar(' ');
        print(rest...);
    }
    template <typename T>
    void printl(T t) {
        print(t);
        PutChar('\n');
    }
    template <typename First, typename ... Ints>
    void printl(First arg, Ints... rest) {
        print(arg);
        PutChar(' ');
        printl(rest...);
    }

    void SayYes() {PrintString("Yes\n", 4);}
    void SayNo() {PrintString("No\n", 3);}
} io;

template<class T> inline bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template<class T> inline bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

int abs(int a) {
    return a < 0 ? -a : a;
}

int main() {
    ll N; io.scan(N);
    ll M; io.scan(M);

    vector<ll> dp(N+1, -1);

    ll bloken;
    REP(i, M) {
        io.scan(bloken);
        dp[bloken] = 0;
    }

    dp[0] = 1;
    if (dp[1] != 0) dp[1] = dp[0];

    FOR(i, 2, N+1) {
        if (dp[i] != 0) dp[i] = (dp[i-1] + dp[i-2]) % 1000000007;
    }
    io.print(dp[N]);

    return 0;
}


#include <bits/stdc++.h>

class kin{
public:
	inline void open(FILE *,int);
	inline void close(void);
	inline void scan(void);
	inline kin &operator>(char &);
	inline kin &operator>(int &);
	inline kin &operator>(long long &);
	inline kin &operator>(double &);
	inline kin &operator>(long double &);
	inline kin &operator>(char *);
	template<class T>
	inline void get(T *,int);
private:
	FILE *fp;
	char *buf;
	int siz;
	int idx;
}in;

class kout{
public:
	inline void open(FILE *,int);
	inline void close(void);
	inline void print(void);
	inline kout &operator<(char);
	inline kout &operator<(int);
	inline kout &operator<(long long);
	inline kout &operator<(double);
	inline kout &operator<(long double);
	inline kout &operator<(const char *);
	template<class T>
	inline void put(T *,int,char,char);
private:
	FILE *fp;
	char *buf;
	int siz;
	int idx;
}out;

int main(int argc,char **argv){
	in.open(stdin,512);
	out.open(stdout,512);
	in.scan();
	int n;
	in>n;
	int qwertyuiop[100002];
	int *x=&qwertyuiop[1];
	for(int i=1;i<=n;++i) x[i]=-1;
	x[-1]=0;
	x[0]=1;
	int m;
	in>m;
	for(int i=0;i<m;++i){
		int a;
		in>a;
		x[a]=0;
	}
	for(int i=1;i<=n;++i){
		if(x[i]==-1){
			x[i]=x[i-1]+x[i-2];
			if(x[i]>=1000000007) x[i]-=1000000007;
		}
	}
	out<x[n]<'\n';
	out.print();
	in.close();
	out.close();
	return 0;
}

inline void kin::open(FILE *fparg,int sizarg){
	fp=fparg;
	buf=new char[sizarg];
	siz=sizarg;
	idx=0;
	return;
}
inline void kin::close(void){
	fp=nullptr;
	delete[] buf;
	buf=nullptr;
	siz=0;
	idx=0;
	return;
}
inline void kin::scan(void){
	int readsiz=(int)std::fread((void *)buf,(std::size_t)1,(std::size_t)siz,fp);
	if(readsiz!=siz) buf[readsiz]='\x00';
	idx=0;
	return;
}
inline kin &kin::operator>(char &var){
	if(!buf[idx]){
		var='\x00';
		return *this;
	}
	var=buf[idx];
	if(++idx==siz) scan();
	if(++idx==siz) scan();
	return *this;
}
inline kin &kin::operator>(int &var){
	if(!buf[idx]){
		var=0;
		return *this;
	}
	int sign=-1;
	if(buf[idx]=='-'){
		sign=1;
		if(++idx==siz) scan();
	}
	var=0;
	while(buf[idx]>='0'){
		var=var*10-(int)(buf[idx]-'0');
		if(++idx==siz) scan();
	}
	var*=sign;
	if(++idx==siz) scan();
	return *this;
}
inline kin &kin::operator>(long long &var){
	if(!buf[idx]){
		var=0LL;
		return *this;
	}
	long long sign=-1LL;
	if(buf[idx]=='-'){
		sign=1LL;
		if(++idx==siz) scan();
	};
	var=0LL;
	while(buf[idx]>='0'){
		var=var*10LL-(long long)(buf[idx]-'0');
		if(++idx==siz) scan();
	}
	var*=sign;
	if(++idx==siz) scan();
	return *this;
}
inline kin &kin::operator>(double &var){
	if(!buf[idx]){
		var=0.0;
		return *this;
	}
	double sign=-1.0;
	if(buf[idx]=='-'){
		sign=1.0;
		if(++idx==siz) scan();
	}
	var=0.0;
	while(buf[idx]>='0'){
		var=var*10.0-(double)(buf[idx]-'0');
		if(++idx==siz) scan();
	}
	if(buf[idx]=='.'){
		if(++idx==siz) scan();
		double dig=1.0;
		while(buf[idx]>='0'){
			var-=(double)(buf[idx]-'0')*(dig/=10.0);
			if(++idx==siz) scan();
		}
	}
	var*=sign;
	if(++idx==siz) scan();
	return *this;
}
inline kin &kin::operator>(long double &var){
	if(!buf[idx]){
		var=0.0L;
		return *this;
	}
	long double sign=-1.0L;
	if(buf[idx]=='-'){
		sign=1.0L;
		if(++idx==siz) scan();
	}
	var=0.0L;
	while(buf[idx]>='0'){
		var=var*10.0L-(long double)(buf[idx]-'0');
		if(++idx==siz) scan();
	}
	if(buf[idx]=='.'){
		if(++idx==siz) scan();
		long double dig=1.0L;
		while(buf[idx]>='0'){
			var-=(long double)(buf[idx]-'0')*(dig/=10.0L);
			if(++idx==siz) scan();
		}
	}
	var*=sign;
	if(++idx==siz) scan();
	return *this;
}
inline kin &kin::operator>(char *str){
	if(!buf[idx]){
		str[0]='\x00';
		return *this;
	}
	int ptr=0;
	while(buf[idx]>='!'){
		str[ptr++]=buf[idx];
		if(++idx==siz) scan();
	}
	str[ptr]='\x00';
	if(++idx==siz) scan();
	return *this;
}
template<class T>
inline void kin::get(T *arr,int num){
	for(int i=0;i<num;++i) (*this)>arr[i];
	return;
}

inline void kout::open(FILE *fparg,int sizarg){
	fp=fparg;
	buf=new char[sizarg];
	siz=sizarg;
	idx=0;
	return;
}
inline void kout::close(void){
	fp=nullptr;
	delete[] buf;
	buf=nullptr;
	siz=0;
	idx=0;
	return;
}
inline void kout::print(void){
	std::fwrite((void *)buf,(std::size_t)1,(std::size_t)idx,fp);
	idx=0;
	return;
}
inline kout &kout::operator<(char val){
	buf[idx]=val;
	if(++idx==siz) print();
	return *this;
}
inline kout &kout::operator<(int val){
	if(val<0){
		buf[idx]='-';
		if(++idx==siz) print();
	}
	else val*=-1;
	char dig[10];
	int ptr=0;
	do{
		int tmp=val/10;
		dig[ptr++]=(char)-(val-tmp*10)+'0';
		val=tmp;
	}while(val);
	while(ptr--){
		buf[idx]=dig[ptr];
		if(++idx==siz) print();
	}
	return *this;
}
inline kout &kout::operator<(long long val){
	if(val<0LL){
		buf[idx]='-';
		if(++idx==siz) print();
	}
	else val*=-1LL;
	char dig[19];
	int ptr=0;
	do{
		long long tmp=val/10LL;
		dig[ptr++]=(char)-(val-tmp*10LL)+'0';
		val=tmp;
	}while(val);
	while(ptr--){
		buf[idx]=dig[ptr];
		if(++idx==siz) print();
	}
	return *this;
}
inline kout &kout::operator<(double val){
	if(val<0.0){
		buf[idx]='-';
		if(++idx==siz) print();
	}
	else val*=-1.0;
	double dig=1.0;
	while(val/dig<=-10.0) dig*=10.0;
	int tmp;
	while(dig>=1.0){
		buf[idx]=(char)-(tmp=(int)(val/dig))+'0';
		if(++idx==siz) print();
		val-=(double)tmp*dig;
		dig/=10.0;
	}
	buf[idx]='.';
	if(++idx==siz) print();
	for(int i=0;i<12;++i){
		buf[idx]=(char)-(tmp=(int)(val/dig))+'0';
		if(++idx==siz) print();
		val-=(double)tmp*dig;
		dig/=10.0;
	}
	return *this;
}
inline kout &kout::operator<(long double val){
	if(val<0.0L){
		buf[idx]='-';
		if(++idx==siz) print();
	}
	else val*=-1.0L;
	long double dig=1.0L;
	while(val/dig<=-10.0L) dig*=10.0L;
	int tmp;
	while(dig>=1.0L){
		buf[idx]=(char)-(tmp=(int)(val/dig))+'0';
		if(++idx==siz) print();
		val-=(long double)tmp*dig;
		dig/=10.0L;
	}
	buf[idx]='.';
	if(++idx==siz) print();
	for(int i=0;i<16;++i){
		buf[idx]=(char)-(tmp=(int)(val/dig))+'0';
		if(++idx==siz) print();
		val-=(long double)tmp*dig;
		dig/=10.0L;
	}
	return *this;
}
inline kout &kout::operator<(const char *str){
	for(int i=0;str[i];++i){
		buf[idx]=str[i];
		if(++idx==siz) print();
	}
	return *this;
}
template<class T>
inline void kout::put(T *arr,int num,char dlm,char end){
	--num;
	for(int i=0;i<num;++i) (*this)<arr[i]<dlm;
	(*this)<arr[num]<end;
	return;
}


#include <bits/stdc++.h>
using namespace std;
int main(void){
    long long int i=0,j=0,c,n,m,a[100000],dp[100000],MOD=1000000007;
    dp[1]=1;
    dp[2]=2;
    cin >> n >> m;
    for(i=0;i<n;i++)
    {
        cin >> a[i];
        if(a[i]==1)
        {
            dp[1]=0;
            dp[2]=1;
            j=1;
        }
        if(a[i]==2)
        {
            dp[2]=0;
            dp[1]=1;
            j=1;
        }
    }
    a[m]=0;
    for(i=3;i<=n;i++)
    {
        if(a[j]==i)
        {
            dp[i]=0;
            j++;
        }
        else
        {
          dp[i]=(dp[i-1]+dp[i-2])%MOD;
        }
    }
    cout << dp[n] << endl;
    return 0;

}


#include<bits/stdc++.h>
#include<vector>
#include<algorithm>
#include<set>
#include<map>
using namespace std;

int main(){
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    int n,m;
    cin>>n>>m;

    vector<bool> flag(n+1,true);
    for(int i=1;i<=m;i++){
        int a;
        cin>>a;
        flag[a]=false;
    }

    vector<long long> dp(n);
    dp[0]=1;
    dp[1]=1;
    if(!flag[1]){
        dp[1]=0;
    }

    for(int i=2;i<=n;i++){
        dp[i]=dp[i-1]+dp[i-2];
        dp[i]%=1000000007;

        if(!flag[i]){
            dp[i]=0;
        }
    }

    cout<<dp[n]<<"\n";

    return 0;
}


#include<bits/stdc++.h>
#include<vector>
#include<algorithm>
#include<set>
#include<map>
using namespace std;

vector<bool> flag(10001,true);
vector<long long> mem(10001,-1);

int dp(int n){
    if(n<0){
        return 0;
    }

    if(n==0){
        return 1;
    }

    if(!flag[n]){
        return 0;
    }

    long long sum=dp(n-1)+dp(n-2);
    sum%=1000000007;
    return sum;
}

int main(){
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    int n,m;
    cin>>n>>m;

    for(int i=1;i<=m;i++){
        int a;
        cin>>a;
        flag[a]=false;
    }

    cout<<dp(n)<<"\n";

    return 0;
}


// AtCoder ABC129: C - Typical Stairs
// 2019.9.4 bal4u

#include <stdio.h>
#include <string.h>

#if 1
#define gc() getchar_unlocked()
#else
#define gc() getchar()
#endif

int in() {   // 非負整数の入力
	int n = 0, c = gc();
	do n = 10 * n + (c & 0xf); while ((c = gc()) >= '0');
	return n;
}

#define MOD 1000000007
int N;
char f[100005];
int dp[100005];

int main()
{
	int i, M;

	N = in(), M = in();
	memset(f, 1, N+1);
	while (M--) f[in()] = 0;

	dp[0] = 1; if (f[1]) dp[1] = 1;
	for (i = 2; i <= N; i++) if (f[i]) dp[i] = (dp[i-1] + dp[i-2]) % MOD;
	printf("%d\n", dp[N]);
	return 0;
}


#include<stdio.h>
#include<stdlib.h>

int main(){
    long long n,m,d[100000],a,b=0,p=1;
    scanf("%lld %lld",&n,&m);
    d[0]=1;
    d[1]=1;
    for(int i=2;i<=n;i++){
        d[i]=d[i-1]+d[i-2];
        d[i]%=1000000007;
    }
    for(int i=0;i<m;i++){
        scanf("%lld",&a);
        if(a==b){
            printf("0\n");
            exit(0);
        }
        a=a-1;
        p*=d[a-b];
        p%=1000000007;
        b=a+2;
    }
    p*=d[n-b];
    p%=1000000007;
    printf("%lld\n",p);
    return 0;
}


#include<stdio.h>

typedef long long int ll;

int main(void){
    int M, N;
    int a[100000];
    int br[100000];
    int i = 0;
    int j = 0;
    ll ans = 1;
    ll div=1000000007;
    ll st[100001];

	for(i = 0; i < 100000; i++){
    	a[i] = 0;
    }

    scanf("%d %d", &N, &M);
    for(i = 0; i < M; i++){
        scanf("%d", &a[i]);
        if(i != 0 && a[i-1]+1 == a[i]){
            printf("0");
            return 0;
        }
    }

    br[0] = 0;

    for(i = 1; i <= N; i++){
        if(i == a[j]){
            br[i] = 1;
          	j++;
        }else{
            br[i] = 0;
        }
    }

    st[0] = 1;
    if(br[1] == 0){
        st[1] = 1;
    }else{
        st[2] = 2;
    }

    for(i = 2; i <= N; i++){
        if(br[i] == 0){
            if(br[i-1] == 0 && br[i-2] == 0){
                st[i] = st[i-1] + st[i-2];
            }else if(br[i-1] == 1){
                st[i] = st[i-2];
            }else if(br[i-2] == 1){
                st[i] = st[i-1];
            }
          	st[i] = st[i]%div;
            ans = st[i];
        }
    }

    printf("%lld", ans);
    return 0;
}


#include <stdio.h>

int main(void){
  long long n,m,a[200005],sum=0,mod=1000000007,h[200005],jud;                                                             scanf("%lld %lld",&n,&m);                                                                                for(int i=1;i<=n;i++){                                                                                scanf("%lld",&a[i]);                                                                                h[a[i]]=0;                                                                                }
                                                                                for(int i=1;i<=n;i++){
     if(a[i]==1) jud=-1;
     if(a[i]==2) jud=1;
     if((a[i]==1)&&(a[i]==2)){
       printf("0\n");
       return 0;                                                                                }
  }
   if(jud==-1) h[1]=0; h[2]=1;
   if(jud==1) h[1]=1; h[2]=0;
   for(int i=1;i<=n-2;i++){
     if(h[i+2]==0) continue;
     h[i+2]=h[i+1]+h[i];
     h[i+2]%=mod;
   }
   printf("%lld\n",h[n]);                                                                                return 0;
 }


#include<stdio.h>
int main()
{
long long int n,m,i;
scanf("%lld %lld",&n,&m);
  long long int ans[n+1],a[m],sw;
  sw=0;
  ans[0]=1;

  for(i=0;i<m;++i)
  {scanf("%lld",&a[i]);}

  if(a[sw]==1) {ans[1]=0;
               sw++;}
  else ans[1]=1;

  for(i=2;i<=n;++i)
  {
  if(i==a[sw]) {ans[i]=0;
                sw++;}
   else
   {
   ans[i]=(ans[i-1]+ans[i-2])%1000000007;
   }
  }
  printf("%lld",ans[n]);

return 0;}


#include <stdio.h>
#define max(x, y) ((x)<(y) ? (y) : (x))

int main(){
  long mod = 1e9+7;
  int n, m;  scanf("%d %d", &n, &m);
  int a[100005] = {0}; a[m+1] = n+1;  a[0] = -10000;
  for(int i=1; i<=m; i++){
    scanf("%d", a+i);
    if(a[i] - a[i-1] <= 1){
      printf("0\n");
      return 0;
    }
  }
  if(a[m+1] - a[m] <= 1){ printf("0\n"); return 0; }
  a[0] = 1;
  int now = 0, b[100005] = {0}, maxi = 0;
  for(int i=1; i<=m+1; i++){
    b[i] = a[i] - 1 - now;
    maxi = max(maxi, b[i]);
    now = a[i] + 1;
  }

  long fibo[100005] = {0};  fibo[1] = fibo[0] = 1;
  for(int i=2; i<=maxi; i++)
    fibo[i] = fibo[i-1] + fibo[i-2];

  long ans = 1;
  for(int i=1; i<=m+1; i++)
    if(b[i])
      ans = (ans * fibo[b[i]]) % mod;

  printf("%ld\n", ans);
  return 0;
}


"use strict";
const main = input => {
    let n = parseInt(input[0].split(' ')[0],10), m = parseInt(input[0].split(' ')[1],10);
    let arr = new Array(n+1),a=0;
    arr[0] = 1,arr[1] = 1;
    for(let i=0; i<m; i++) {
        a = parseInt(input[i+1],10);
        arr[a] = 0;
    }
    for(let i=2; i<n+1; i++) {
        if (arr[i]!=0) {
            arr[i] = (arr[i-1]+arr[i-2])%1000000007;
        }
    }
    // console.log(arr);

    console.log(arr[n]);

}
main(require("fs").readFileSync("/dev/stdin", "utf8").split('\n'));


const main = (inputs) => {
  var mod = 1000000007;

  var N = inputs[0].split(" ")[0]-0;
  var M = inputs[0].split(" ")[1]-0;
  var ana = {};
  for(var i=1;i<=M;i++){
    ana[inputs[i]] = true;
    if(i>1 && inputs[i] - inputs[i-1] == 1) {console.log(0);return;}
  }
  var map = {
    0: 1,
    1: (ana[1]?0:1)
  };
  for(var i=2;i<=N;i++){
    if(ana[i]) continue;
    map[i] = (map[i-1]||0) + (map[i-2]||0);
    map[i] = map[i]%mod;
  }
  console.log(map[N]);
}

main(require('fs').readFileSync('/dev/stdin', 'UTF-8').trim().split("\n"));


'use strict'

const INF = 900719925474099;
function mapint(temp){
    return temp.split(' ').map((v)=>parseInt(v));
}
const MOD = 1000000007;

function Main(input){
    let temp = input.trim().split('\n');
    let n = mapint(temp[0])[0];
    let m = mapint(temp[0])[1];
    let a = new Array(m);

    let step = new Array(n+10).fill(0);
    step[0] = 1;

    for(let i=1;i<=m;i++){
        step[parseInt(temp[i])] = -1;
    }

    for(let i=0;i<n;i++){
        if(step[i] == -1) continue;
        if(step[i+1] != -1){
            step[i+1]+=step[i];
            step[i+1]%=MOD;
        }
        if(step[i+2] != -1){
            step[i+2]+=step[i];
            step[i+2]%=MOD;
        }
        //console.log(step);
    }

    console.log(step[n]);

}
//*この行以降は編集しないでください（標準入出力から一度に読み込み、Mainを呼び出します）
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


function spilitInput(input, to_int) {
  if (typeof to_int === 'undefined') to_int = false;
  var splited = [];
  var rows = input.split('\n');
  for (var i = 0; i < rows.length; i += 1) {
    if (to_int) {
      splited.push(rows[i].split(' ').map(function(d){return parseInt(d,10);}));
    } else {
      splited.push(rows[i].split(' '));
    }
  }
  return splited;
}

function initDp(N, init_n) { return Array(N+2).fill(init_n); }
function chmin(a, b) { if (a > b) a = b; }
function chmax(a, b) { if (a < b) a = b; }

function Main(input) {
  var splited = spilitInput(input, true);
  var N = splited[0][0];
  var hasons = [];
  for (var i = 1; i < splited.length; i += 1) {
    hasons.push(splited[i][0]);
  }

  var dp = initDp(N, 0);
  dp[0] = 1;

  for (var i = 1; i <= N; i += 1) {
    if (hasons.indexOf(i) !== -1) continue;
    dp[i] += dp[i - 1];
    if (i >= 2) dp[i] += dp[i - 2];
    dp[i] %= 1000000007;
  }

  console.log(dp[N]);
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


function spilitInput(input, to_int) {
  if (typeof to_int === 'undefined') to_int = false;
  var splited = [];
  var rows = input.split('\n');
  for (var i = 0; i < rows.length; i += 1) {
    if (to_int) {
      splited.push(rows[i].split(' ').map(function(d){return parseInt(d,10);}));
    } else {
      splited.push(rows[i].split(' '));
    }
  }
  return splited;
}

function initDp(N, init_n) {
  var dp = [];
  for (var i = 0; i <= N; i += 1) { dp.push(0);}
  return dp;
}
function chmin(a, b) { if (a > b) a = b; }
function chmax(a, b) { if (a < b) a = b; }

function Main(input) {
  var splited = spilitInput(input, true);
  var N = splited[0][0];
  var hasons = [];
  for (var i = 1; i < splited.length; i += 1) {
    hasons.push(splited[i][0]);
  }

  var dp = initDp(N, 0);
  dp[0] = 1;

  for (var i = 1; i <= N; i += 1) {
    if (hasons.indexOf(i) !== -1) continue;
    dp[i] += dp[i - 1];
    if (i >= 2) dp[i] += dp[i - 2];
    dp[i] %= 1000000007;
  }

  console.log(dp[N]);
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


function spilitInput(input, to_int) {
  if (typeof to_int === 'undefined') to_int = false;
  var splited = [];
  var rows = input.split('\n');
  for (var i = 0; i < rows.length; i += 1) {
    if (to_int) {
      splited.push(rows[i].split(' ').map(function(d){return parseInt(d,10);}));
    } else {
      splited.push(rows[i].split(' '));
    }
  }
  return splited;
}

function initDp(N, init_n) {
  var dp = [];
  for (var i = 0; i <= N; i += 1) { dp.push(0);}
  return dp;
}
function chmin(a, b) { if (a > b) a = b; }
function chmax(a, b) { if (a < b) a = b; }

function Main(input) {
  var splited = spilitInput(input, true);
  var N = splited[0][0];
  var hasons = [];
  for (var i = 1; i < splited.length; i += 1) {
    hasons.push(splited[i][0]);
  }

  var dp = initDp(N, 0);
  dp[0] = 1;

  for (var i = 1; i <= N; i += 1) {
    if (hasons.indexOf(i) !== -1) continue;
    dp[i] += dp[i - 1];
    if (i >= 2) dp[i] += dp[i - 2];
    dp[i] = parseInt((dp[i] % 1000000007), 10);
  }

  console.log(dp[N]);
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


package main

import (
	"fmt"
	"bufio"
	"os"
	"strconv"
	// "sort"
)

var stdin = initStdin()

func initStdin() *bufio.Scanner {
	bufsize := 1 * 1024 * 1024
	var stdin = bufio.NewScanner(os.Stdin)
	stdin.Buffer(make([]byte, bufsize), bufsize)
	stdin.Split(bufio.ScanWords)
	return stdin
}

func scanInt() int {
	stdin.Scan()
	i, _ := strconv.Atoi(stdin.Text())
	return i
}

func scanStr() string {
	stdin.Scan()
	return stdin.Text()
}

type ia []int

func (ia ia)Len() int {
	return len(ia)
}
func (ia ia)Swap(i, j int) {
	ia[i], ia[j] = ia[j], ia[i]
}
func (ia ia)Less(i, j int) bool {
	return ia[i] < ia[j]
}

const inf = 1000000000 + 7

var fib = []int {1, 1, 2, 3, 5, 8}
var fibCount = 6

func mFib(req int) int {
	if req <= fibCount {
	} else {
		lo := req - fibCount
		for i := 0; i < lo; i++ {
			fib = append(fib, (fib[fibCount-2]+fib[fibCount-1])%inf )
			fibCount++
		}
	}
	return fib[req-1]
}

func main() {
	n := scanInt()
	m := scanInt()
	bef := -1
	ans := 1
	a := 1
	for i := 0; i < m; i++ {
		a = scanInt()
		diff := a - bef
		if diff < 2 {
			ans = 0
			break
		}
		ans *= mFib(diff-1)
		ans %= inf
		bef = a
	}
	ans *= mFib(n - bef)
	ans %= inf
	fmt.Println(ans)
}


package main

import (
	"bufio"
	"fmt"
	"os"
)

var sc = bufio.NewScanner(os.Stdin)

const inf = 1 << 60
const mod int = 1e9 + 7

func ri() (n int) {
	sc.Scan()
	for _, v := range sc.Bytes() {
		n = n*10 + int(v-48)
	}
	return
}

func main() {
	sc.Split(bufio.ScanWords)
	n, m := ri(), ri()

	dp := make([]int, n+1)

	a := make([]int, m)
	for i := 0; i < m; i++ {
		a[i] = ri()
		dp[a[i]] += -1
	}

	dp[0] = 1
	if dp[1] != -1 {
		dp[1] = 1
	}

	for i := 2; i < len(dp); i++ {
		if dp[i] == -1 {
			continue
		}
		var x, y int
		if dp[i-2] != -1 {
			x = dp[i-2]
		} else {
			x = 0
		}
		if dp[i-1] != -1 {
			y = dp[i-1]
		} else {
			y = 0
		}
		dp[i] = (x + y) % mod
	}

	fmt.Println(dp[n])
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

const mod = 1000000007

func main() {
	var n, m int
	fmt.Scan(&n, &m)
	xs := make([]int, n+1)
	for i := range xs {
		xs[i] = 1
	}
	var (
		sc = bufio.NewScanner(os.Stdin)
		a  int
	)
	for i := 0; i < m; i++ {
		sc.Scan()
		a, _ = strconv.Atoi(sc.Text())
		xs[a] = 0
	}
	var (
		f2     = 1
		f1, f0 = xs[1], xs[0]
	)
	for i := 2; i <= n; i++ {
		f2 = (f1*xs[i-1] + f0*xs[i-2]) % mod
		f1, f0 = f2, f1
	}
	fmt.Println(f2)
}


package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"strconv"
)

var DEBUG = true

// -----------------------------------------------------------------------------

// IO helper functions

// Returns next token from input.  It must be initialized by SetInput()
// before the first call.
var nextToken func() ([]byte, error)
var nextLine func() ([]byte, error)

// Holds a buffer for output.  It must be initialized by SetOutput().
// All IO functions (read*() and [e]print*()) should write to OutputWriter
// instead of this.
var OutputBuffer *bufio.Writer

// Holds an io.Writer.  It must be initialized by SetOutput()
var OutputWriter io.Writer

// Set IO functions for interactive input/output.
func SetInteractive(w io.Writer, r io.Reader) {
	SetUnbufferedInput(r)
	OutputBuffer = nil
	OutputWriter = w
}

// Setup OutputBuffer and OutputWriter.
func SetOutput(w io.Writer) {
	OutputBuffer = bufio.NewWriter(w)
	OutputWriter = OutputBuffer
}

// Flushes OutputBuffer
func Flush() {
	if OutputBuffer != nil {
		OutputBuffer.Flush()
	}
}

// Returns true if c is a white space
func IsSpace(c byte) bool {
	switch c {
	case '\t', '\n', '\v', '\f', '\r', ' ':
		return true
	}
	return false
}

func IsNewLine(c byte) bool {
	switch c {
	case '\n', '\r':
		return true
	}
	return false
}

// Setup nextToken with input buffer.
func SetInput(r io.Reader) {
	buf := new(bytes.Buffer)
	var b []byte

	var i int
	rest := func() ([]byte, error) {
		for i < len(b) && IsSpace(b[i]) {
			i++
		}
		if i == len(b) {
			return nil, io.ErrUnexpectedEOF
		}
		j := i
		for i < len(b) && !IsSpace(b[i]) {
			i++
		}
		return b[j:i], nil
	}
	initial := func() ([]byte, error) {
		io.Copy(buf, r)
		b = buf.Bytes()
		nextToken = rest
		return rest()
	}
	nextToken = initial

	restLn := func() ([]byte, error) {
		for i < len(b) && IsNewLine(b[i]) {
			i++
		}
		if i == len(b) {
			return nil, io.ErrUnexpectedEOF
		}
		j := i
		for i < len(b) && !IsNewLine(b[i]) {
			i++
		}
		return b[j:i], nil
	}

	initialLn := func() ([]byte, error) {
		io.Copy(buf, r)
		b = buf.Bytes()
		nextLine = restLn
		return restLn()
	}
	nextLine = initialLn
}

// Setup nextToken without input buffer.
func SetUnbufferedInput(r io.Reader) {
	buf := bufio.NewReader(r)
	var b []byte

	var i int
	nextToken = func() ([]byte, error) {
		var err error
		if i == len(b) {
			b, err = buf.ReadBytes('\n')
			if err != nil {
				return nil, err
			}
			i = 0
			j := len(b) - 1
			for 0 <= j && IsSpace(b[j]) {
				j--
			}
			b = b[0 : j+1]
		}
		for i < len(b) && IsSpace(b[i]) {
			i++
		}
		j := i
		for i < len(b) && !IsSpace(b[i]) {
			i++
		}
		if i == j {
			return nil, io.ErrUnexpectedEOF
		}
		return b[j:i], nil
	}
}

// -----------------------------------------------------------------------------

// IO functions

// Reads next token and return it as []byte
func readb() []byte {
	b, err := nextToken()
	if err != nil {
		panic(err)
	}
	return b[:len(b):len(b)]
}

// Reads next token and return it as string
func reads() string {
	return string(readb())
}

// Read next line as []byte.  Trailing '\n' will not be included.
// See also comments on readb()
func readbln() []byte {
	b, err := nextLine()
	if err != nil {
		panic(err)
	}
	return b[:len(b):len(b)]
}

// Read next line as string
func readsln() string {
	return string(readbln())
}

// Reads next token and return it as int64
func readll() int64 {
	i, err := strconv.ParseInt(reads(), 10, 64)
	if err != nil {
		panic(err.Error())
	}
	return i
}

// Reads next token and return it as int
func readi() int {
	return int(readll())
}

// Reads next token and return it as float64
func readf() float64 {
	f, err := strconv.ParseFloat(reads(), 64)
	if err != nil {
		panic(err.Error())
	}
	return f
}

// Write args to OutputWriter with the format f
func printf(f string, args ...interface{}) (int, error) {
	return fmt.Fprintf(OutputWriter, f, args...)
}

// Write args to OutputWriter without format
func println(args ...interface{}) (int, error) {
	return fmt.Fprintln(OutputWriter, args...)
}

// Write args to stderr with the format f
func eprintf(f string, args ...interface{}) (int, error) {
	return fmt.Fprintf(os.Stderr, f, args...)
}

// Write args to stderr without format
func eprintln(args ...interface{}) (int, error) {
	return fmt.Fprintln(os.Stderr, args...)
}

func debugf(f string, args ...interface{}) {
	if !DEBUG {
		return
	}
	fmt.Fprintf(os.Stderr, f, args...)
}

func debug(args ...interface{}) {
	if !DEBUG {
		return
	}
	fmt.Fprintln(os.Stderr, args...)
}

// -----------------------------------------------------------------------------

// Utilities

func sumSlice(a []int) int {
	var res int
	for _, v := range a {
		res += v
	}
	return res
}

func sumSlicell(a []int64) int64 {
	var res int64
	for _, v := range a {
		res += v
	}
	return res
}

func readInts(N int) (int, []int) {
	if N == 0 {
		N = readi()
	}
	a := make([]int, N)
	for i := range a {
		a[i] = readi()
	}
	return N, a
}

func readIntsll(N int) (int, []int64) {
	if N == 0 {
		N = readi()
	}
	a := make([]int64, N)
	for i := range a {
		a[i] = readll()
	}
	return N, a
}

// -----------------------------------------------------------------------------

// Simple math functions

const (
	// big prime
	INF  = 1000000007
	INF2 = 1000000009
	INF3 = 998244353
)

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func minll(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}

func minf(a, b float64) float64 {
	if a < b {
		return a
	}
	return b
}

func max(a, b int) int {
	if a < b {
		return b
	}
	return a
}

func maxll(a, b int64) int64 {
	if a < b {
		return b
	}
	return a
}

func maxf(a, b float64) float64 {
	if a < b {
		return b
	}
	return a
}

func abs(a int) int {
	if a < 0 {
		return -a
	}
	return a
}

func absll(a int64) int64 {
	if a < 0 {
		return -a
	}
	return a
}

func absf(a float64) float64 {
	if a < 0 {
		return -a
	}
	return a
}

// egcd(a, b) returns d, x, y:
//   d is gcd(a,b)
//   x, y are  integers that satisfy ax + by = d
func egcd(a, b int) (int, int, int) {
	if b == 0 {
		return a, 1, 0
	}
	d, x, y := egcd(b, a%b)
	return d, y, x - a/b*y
}

func egcdll(a, b int64) (int64, int64, int64) {
	if b == 0 {
		return a, 1, 0
	}
	d, x, y := egcdll(b, a%b)
	return d, y, x - a/b*y
}

func gcd(a, b int) int {
	d, _, _ := egcd(a, b)
	return d
}

func gcdll(a, b int64) int64 {
	d, _, _ := egcdll(a, b)
	return d
}

// set up IO functions
func init() {
	// for non-interactive
	SetInput(os.Stdin)
	SetOutput(os.Stdout)

	// Enable below when interactive.  Its ok to leave above intact.
	SetInteractive(os.Stdout, os.Stdin)
}

func main() {
	defer Flush()
	n := readi()
	m := readi()
	_, a := readInts(m)
	answer := solve(n, m, a)
	println(answer)
}

var mod = 1000000007

func solve(n, m int, a []int) int {
	dp := make([]int, n+1)
	dp[0] = 1
	ai := 0

	if m > 0 && a[0] == 1 {
		dp[1] = 0
		ai++
	} else {
		dp[1] = 1
	}

	for i := 2; i < n+1; i++ {
		if ai < m && a[ai] == i {
			dp[i] = 0
			ai++
		} else {
			dp[i] = (dp[i-1] + dp[i-2]) % mod
		}
	}

	return dp[n]
}


package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"strconv"
)

var DEBUG = true

// -----------------------------------------------------------------------------

// IO helper functions

// Returns next token from input.  It must be initialized by SetInput()
// before the first call.
var nextToken func() ([]byte, error)
var nextLine func() ([]byte, error)

// Holds a buffer for output.  It must be initialized by SetOutput().
// All IO functions (read*() and [e]print*()) should write to OutputWriter
// instead of this.
var OutputBuffer *bufio.Writer

// Holds an io.Writer.  It must be initialized by SetOutput()
var OutputWriter io.Writer

// Set IO functions for interactive input/output.
func SetInteractive(w io.Writer, r io.Reader) {
	SetUnbufferedInput(r)
	OutputBuffer = nil
	OutputWriter = w
}

// Setup OutputBuffer and OutputWriter.
func SetOutput(w io.Writer) {
	OutputBuffer = bufio.NewWriter(w)
	OutputWriter = OutputBuffer
}

// Flushes OutputBuffer
func Flush() {
	if OutputBuffer != nil {
		OutputBuffer.Flush()
	}
}

// Returns true if c is a white space
func IsSpace(c byte) bool {
	switch c {
	case '\t', '\n', '\v', '\f', '\r', ' ':
		return true
	}
	return false
}

func IsNewLine(c byte) bool {
	switch c {
	case '\n', '\r':
		return true
	}
	return false
}

// Setup nextToken with input buffer.
func SetInput(r io.Reader) {
	buf := new(bytes.Buffer)
	var b []byte

	var i int
	rest := func() ([]byte, error) {
		for i < len(b) && IsSpace(b[i]) {
			i++
		}
		if i == len(b) {
			return nil, io.ErrUnexpectedEOF
		}
		j := i
		for i < len(b) && !IsSpace(b[i]) {
			i++
		}
		return b[j:i], nil
	}
	initial := func() ([]byte, error) {
		io.Copy(buf, r)
		b = buf.Bytes()
		nextToken = rest
		return rest()
	}
	nextToken = initial

	restLn := func() ([]byte, error) {
		for i < len(b) && IsNewLine(b[i]) {
			i++
		}
		if i == len(b) {
			return nil, io.ErrUnexpectedEOF
		}
		j := i
		for i < len(b) && !IsNewLine(b[i]) {
			i++
		}
		return b[j:i], nil
	}

	initialLn := func() ([]byte, error) {
		io.Copy(buf, r)
		b = buf.Bytes()
		nextLine = restLn
		return restLn()
	}
	nextLine = initialLn
}

// Setup nextToken without input buffer.
func SetUnbufferedInput(r io.Reader) {
	buf := bufio.NewReader(r)
	var b []byte

	var i int
	nextToken = func() ([]byte, error) {
		var err error
		if i == len(b) {
			b, err = buf.ReadBytes('\n')
			if err != nil {
				return nil, err
			}
			i = 0
			j := len(b) - 1
			for 0 <= j && IsSpace(b[j]) {
				j--
			}
			b = b[0 : j+1]
		}
		for i < len(b) && IsSpace(b[i]) {
			i++
		}
		j := i
		for i < len(b) && !IsSpace(b[i]) {
			i++
		}
		if i == j {
			return nil, io.ErrUnexpectedEOF
		}
		return b[j:i], nil
	}
}

// -----------------------------------------------------------------------------

// IO functions

// Reads next token and return it as []byte
func readb() []byte {
	b, err := nextToken()
	if err != nil {
		panic(err)
	}
	return b[:len(b):len(b)]
}

// Reads next token and return it as string
func reads() string {
	return string(readb())
}

// Read next line as []byte.  Trailing '\n' will not be included.
// See also comments on readb()
func readbln() []byte {
	b, err := nextLine()
	if err != nil {
		panic(err)
	}
	return b[:len(b):len(b)]
}

// Read next line as string
func readsln() string {
	return string(readbln())
}

// Reads next token and return it as int64
func readll() int64 {
	i, err := strconv.ParseInt(reads(), 10, 64)
	if err != nil {
		panic(err.Error())
	}
	return i
}

// Reads next token and return it as int
func readi() int {
	return int(readll())
}

// Reads next token and return it as float64
func readf() float64 {
	f, err := strconv.ParseFloat(reads(), 64)
	if err != nil {
		panic(err.Error())
	}
	return f
}

// Write args to OutputWriter with the format f
func printf(f string, args ...interface{}) (int, error) {
	return fmt.Fprintf(OutputWriter, f, args...)
}

// Write args to OutputWriter without format
func println(args ...interface{}) (int, error) {
	return fmt.Fprintln(OutputWriter, args...)
}

// Write args to stderr with the format f
func eprintf(f string, args ...interface{}) (int, error) {
	return fmt.Fprintf(os.Stderr, f, args...)
}

// Write args to stderr without format
func eprintln(args ...interface{}) (int, error) {
	return fmt.Fprintln(os.Stderr, args...)
}

func debugf(f string, args ...interface{}) {
	if !DEBUG {
		return
	}
	fmt.Fprintf(os.Stderr, f, args...)
}

func debug(args ...interface{}) {
	if !DEBUG {
		return
	}
	fmt.Fprintln(os.Stderr, args...)
}

// -----------------------------------------------------------------------------

// Utilities

func sumSlice(a []int) int {
	var res int
	for _, v := range a {
		res += v
	}
	return res
}

func sumSlicell(a []int64) int64 {
	var res int64
	for _, v := range a {
		res += v
	}
	return res
}

func readInts(N int) (int, []int) {
	if N == 0 {
		N = readi()
	}
	a := make([]int, N)
	for i := range a {
		a[i] = readi()
	}
	return N, a
}

func readIntsll(N int) (int, []int64) {
	if N == 0 {
		N = readi()
	}
	a := make([]int64, N)
	for i := range a {
		a[i] = readll()
	}
	return N, a
}

// -----------------------------------------------------------------------------

// Simple math functions

const (
	// big prime
	INF  = 1000000007
	INF2 = 1000000009
	INF3 = 998244353
)

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func minll(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}

func minf(a, b float64) float64 {
	if a < b {
		return a
	}
	return b
}

func max(a, b int) int {
	if a < b {
		return b
	}
	return a
}

func maxll(a, b int64) int64 {
	if a < b {
		return b
	}
	return a
}

func maxf(a, b float64) float64 {
	if a < b {
		return b
	}
	return a
}

func abs(a int) int {
	if a < 0 {
		return -a
	}
	return a
}

func absll(a int64) int64 {
	if a < 0 {
		return -a
	}
	return a
}

func absf(a float64) float64 {
	if a < 0 {
		return -a
	}
	return a
}

// egcd(a, b) returns d, x, y:
//   d is gcd(a,b)
//   x, y are  integers that satisfy ax + by = d
func egcd(a, b int) (int, int, int) {
	if b == 0 {
		return a, 1, 0
	}
	d, x, y := egcd(b, a%b)
	return d, y, x - a/b*y
}

func egcdll(a, b int64) (int64, int64, int64) {
	if b == 0 {
		return a, 1, 0
	}
	d, x, y := egcdll(b, a%b)
	return d, y, x - a/b*y
}

func gcd(a, b int) int {
	d, _, _ := egcd(a, b)
	return d
}

func gcdll(a, b int64) int64 {
	d, _, _ := egcdll(a, b)
	return d
}

// set up IO functions
func init() {
	// for non-interactive
	SetInput(os.Stdin)
	SetOutput(os.Stdout)

	// Enable below when interactive.  Its ok to leave above intact.
	SetInteractive(os.Stdout, os.Stdin)
}

func main() {
	defer Flush()
	n := readi()
	m := readi()
	_, a := readInts(m)
	answer := solve(n, m, a)
	println(answer)
}

var mod = 1000000007

func solve(n, m int, a []int) int {
	dp := make([]int, n+1)
	dp[0] = 1
	ai := 0
	if a[0] == 1 {
		dp[1] = 0
		ai++
	} else {
		dp[1] = 1

	}

	for i := 2; i < n+1; i++ {
		if ai < m && a[ai] == i {
			dp[i] = 0
			ai++
		} else {
			dp[i] = (dp[i-1] + dp[i-2]) % mod
		}
	}

	return dp[n]
}


package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"strconv"
)

var DEBUG = true

// -----------------------------------------------------------------------------

// IO helper functions

// Returns next token from input.  It must be initialized by SetInput()
// before the first call.
var nextToken func() ([]byte, error)
var nextLine func() ([]byte, error)

// Holds a buffer for output.  It must be initialized by SetOutput().
// All IO functions (read*() and [e]print*()) should write to OutputWriter
// instead of this.
var OutputBuffer *bufio.Writer

// Holds an io.Writer.  It must be initialized by SetOutput()
var OutputWriter io.Writer

// Set IO functions for interactive input/output.
func SetInteractive(w io.Writer, r io.Reader) {
	SetUnbufferedInput(r)
	OutputBuffer = nil
	OutputWriter = w
}

// Setup OutputBuffer and OutputWriter.
func SetOutput(w io.Writer) {
	OutputBuffer = bufio.NewWriter(w)
	OutputWriter = OutputBuffer
}

// Flushes OutputBuffer
func Flush() {
	if OutputBuffer != nil {
		OutputBuffer.Flush()
	}
}

// Returns true if c is a white space
func IsSpace(c byte) bool {
	switch c {
	case '\t', '\n', '\v', '\f', '\r', ' ':
		return true
	}
	return false
}

func IsNewLine(c byte) bool {
	switch c {
	case '\n', '\r':
		return true
	}
	return false
}

// Setup nextToken with input buffer.
func SetInput(r io.Reader) {
	buf := new(bytes.Buffer)
	var b []byte

	var i int
	rest := func() ([]byte, error) {
		for i < len(b) && IsSpace(b[i]) {
			i++
		}
		if i == len(b) {
			return nil, io.ErrUnexpectedEOF
		}
		j := i
		for i < len(b) && !IsSpace(b[i]) {
			i++
		}
		return b[j:i], nil
	}
	initial := func() ([]byte, error) {
		io.Copy(buf, r)
		b = buf.Bytes()
		nextToken = rest
		return rest()
	}
	nextToken = initial

	restLn := func() ([]byte, error) {
		for i < len(b) && IsNewLine(b[i]) {
			i++
		}
		if i == len(b) {
			return nil, io.ErrUnexpectedEOF
		}
		j := i
		for i < len(b) && !IsNewLine(b[i]) {
			i++
		}
		return b[j:i], nil
	}

	initialLn := func() ([]byte, error) {
		io.Copy(buf, r)
		b = buf.Bytes()
		nextLine = restLn
		return restLn()
	}
	nextLine = initialLn
}

// Setup nextToken without input buffer.
func SetUnbufferedInput(r io.Reader) {
	buf := bufio.NewReader(r)
	var b []byte

	var i int
	nextToken = func() ([]byte, error) {
		var err error
		if i == len(b) {
			b, err = buf.ReadBytes('\n')
			if err != nil {
				return nil, err
			}
			i = 0
			j := len(b) - 1
			for 0 <= j && IsSpace(b[j]) {
				j--
			}
			b = b[0 : j+1]
		}
		for i < len(b) && IsSpace(b[i]) {
			i++
		}
		j := i
		for i < len(b) && !IsSpace(b[i]) {
			i++
		}
		if i == j {
			return nil, io.ErrUnexpectedEOF
		}
		return b[j:i], nil
	}
}

// -----------------------------------------------------------------------------

// IO functions

// Reads next token and return it as []byte
func readb() []byte {
	b, err := nextToken()
	if err != nil {
		panic(err)
	}
	return b[:len(b):len(b)]
}

// Reads next token and return it as string
func reads() string {
	return string(readb())
}

// Read next line as []byte.  Trailing '\n' will not be included.
// See also comments on readb()
func readbln() []byte {
	b, err := nextLine()
	if err != nil {
		panic(err)
	}
	return b[:len(b):len(b)]
}

// Read next line as string
func readsln() string {
	return string(readbln())
}

// Reads next token and return it as int64
func readll() int64 {
	i, err := strconv.ParseInt(reads(), 10, 64)
	if err != nil {
		panic(err.Error())
	}
	return i
}

// Reads next token and return it as int
func readi() int {
	return int(readll())
}

// Reads next token and return it as float64
func readf() float64 {
	f, err := strconv.ParseFloat(reads(), 64)
	if err != nil {
		panic(err.Error())
	}
	return f
}

// Write args to OutputWriter with the format f
func printf(f string, args ...interface{}) (int, error) {
	return fmt.Fprintf(OutputWriter, f, args...)
}

// Write args to OutputWriter without format
func println(args ...interface{}) (int, error) {
	return fmt.Fprintln(OutputWriter, args...)
}

// Write args to stderr with the format f
func eprintf(f string, args ...interface{}) (int, error) {
	return fmt.Fprintf(os.Stderr, f, args...)
}

// Write args to stderr without format
func eprintln(args ...interface{}) (int, error) {
	return fmt.Fprintln(os.Stderr, args...)
}

func debugf(f string, args ...interface{}) {
	if !DEBUG {
		return
	}
	fmt.Fprintf(os.Stderr, f, args...)
}

func debug(args ...interface{}) {
	if !DEBUG {
		return
	}
	fmt.Fprintln(os.Stderr, args...)
}

// -----------------------------------------------------------------------------

// Utilities

func sumSlice(a []int) int {
	var res int
	for _, v := range a {
		res += v
	}
	return res
}

func sumSlicell(a []int64) int64 {
	var res int64
	for _, v := range a {
		res += v
	}
	return res
}

func readInts(N int) (int, []int) {
	if N == 0 {
		N = readi()
	}
	a := make([]int, N)
	for i := range a {
		a[i] = readi()
	}
	return N, a
}

func readIntsll(N int) (int, []int64) {
	if N == 0 {
		N = readi()
	}
	a := make([]int64, N)
	for i := range a {
		a[i] = readll()
	}
	return N, a
}

// -----------------------------------------------------------------------------

// Simple math functions

const (
	// big prime
	INF  = 1000000007
	INF2 = 1000000009
	INF3 = 998244353
)

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func minll(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}

func minf(a, b float64) float64 {
	if a < b {
		return a
	}
	return b
}

func max(a, b int) int {
	if a < b {
		return b
	}
	return a
}

func maxll(a, b int64) int64 {
	if a < b {
		return b
	}
	return a
}

func maxf(a, b float64) float64 {
	if a < b {
		return b
	}
	return a
}

func abs(a int) int {
	if a < 0 {
		return -a
	}
	return a
}

func absll(a int64) int64 {
	if a < 0 {
		return -a
	}
	return a
}

func absf(a float64) float64 {
	if a < 0 {
		return -a
	}
	return a
}

// egcd(a, b) returns d, x, y:
//   d is gcd(a,b)
//   x, y are  integers that satisfy ax + by = d
func egcd(a, b int) (int, int, int) {
	if b == 0 {
		return a, 1, 0
	}
	d, x, y := egcd(b, a%b)
	return d, y, x - a/b*y
}

func egcdll(a, b int64) (int64, int64, int64) {
	if b == 0 {
		return a, 1, 0
	}
	d, x, y := egcdll(b, a%b)
	return d, y, x - a/b*y
}

func gcd(a, b int) int {
	d, _, _ := egcd(a, b)
	return d
}

func gcdll(a, b int64) int64 {
	d, _, _ := egcdll(a, b)
	return d
}

// set up IO functions
func init() {
	// for non-interactive
	SetInput(os.Stdin)
	SetOutput(os.Stdout)

	// Enable below when interactive.  Its ok to leave above intact.
	SetInteractive(os.Stdout, os.Stdin)
}

func main() {
	defer Flush()
	n := readi()
	m := readi()
	_, a := readInts(m)
	answer := solve(n, m, a)
	println(answer)
}

var mod = 1000000007

func solve(n, m int, a []int) int {
	dp := make([]int, n+1)
	dp[0] = 1
	ai := 0
	if a[0] == 1 {
		dp[1] = 0
		ai++
	} else {
		dp[1] = 1

	}

	for i := 2; i < n+1; i++ {
		if ai < m && a[ai] == i {
			dp[i] = 0
			ai++
		} else {
			dp[i] = dp[i-1] + dp[i-2]
		}
	}

	return dp[n] % mod
}


MOD = 1000000007
def fib(n)
	#return n+1>>1 if n<4
	return ((0.5+Math.sqrt(5)*0.5)**n/Math.sqrt(5)).round % MOD if n<70
	nb = n.bit_length-6;a=((0.5+Math.sqrt(5)*0.5)**(n>>nb)/Math.sqrt(5)).round;b=(a+a*Math.sqrt(5)).round>>1
	(nb-1).downto(0){|m|a,b=a*(2*b-a)%MOD,(b*b+a*a)%MOD;a,b=b,a+b if (n>>m).odd?}
	return a
end

def mypow(a,m)
	return a**m%MOD if m<4;c,res=a,1;while(m>0);res=res*c%MOD if m.odd?;c,m=c*c%MOD,m>>1;end;return res
end

N, M = gets.split.map(&:to_i)
exit p(0) if M*2 > N
res = 1
$<.map(&:to_i).unshift(-1).push(N+1).each_cons(2).map{|x,y|y-x}.group_by(&:pred).each{|x,y|res=res*mypow(fib(x),y.size)%MOD}
p res


mod = 10**9+7
mod2 = mod * 5

n, m = gets.to_s.split
n, m = n.to_i, m.to_i

A = $<.map &:to_i

if A.each_cons(2).any?{|a, b| b - a == 1 }
  p 0
  exit
end

stairs = [1] * (n+1)

A.each do |a|
  stairs[a] = 0
end

2.upto(n) do |i|
  next if stairs[i] == 0
  stairs[i] = stairs[i-1] + stairs[i-2]
  stairs[i] %= mod if stairs[i] > mod2
end

puts stairs[-1] % mod


N, M  = gets.split.map &:to_i
A = $<.map &:to_i
MOD = 10**9+7
if A.each_cons(2).any?{|a, b| b - a == 1 }
  p 0
  exit
end
NG = [false] * (N + 1)
A.each{|a| NG[a] = true }

dp = [0] * (N + 1)
dp[0] = 1

(1..N).each{|to|
  next if NG[to]
  from_1 = to - 1 >= 0 ? dp[to - 1] : 0
  from_2 = to - 2 >= 0 ? dp[to - 2] : 0
  dp[to] = (from_1 + from_2) % MOD
}
p dp[N]


n,m = gets.split.map(&:to_i)
a = []
m.times { a << gets.to_i }
dp = [1,1]
dp[1] = 0 if a.include? 1
(2..n).each do |i|
  dp[i] = dp[i-1] + dp[i-2]
  dp[i] = 0 if a.include? i
end
p dp[n] % 1000000007


N, M = gets.chomp.split().map(&:to_i)

danger = []
M.times do
  danger << gets.chomp.to_i
end

dp = [0] * (N+1)
dp[0] = 1
if danger[0] == 1
  dp[1] = 0
  danger.shift
else
  dp[1] = 0
end

for i in 2..N do
  if i == danger[0]
    dp[i] = 0
    danger.shift
  else
    dp[i] = dp[i-1] + dp[i-2]
  end
end

puts dp[-1] % 1000000007


N, M = gets.chomp.split().map(&:to_i)

danger = []
M.times do
  danger << gets.chomp.to_i
end

dp = [0] * (N+1)
dp[0] = 1
dp[1] = danger.include?(1) ? 0 : 1

for i in 2..N do
  if danger.include?(i)
    dp[i] = 0
  else
    dp[i] = dp[i-1] + dp[i-2]
  end
end

puts dp[-1] % 1000000007


use std::cmp::*;
use std::io::*;
use std::ops::*;
use utils::*;

pub fn main() {
    let i = stdin();
    let mut o = Vec::new();
    run(i.lock(), &mut o);
    stdout().write_all(&o).unwrap();
}

pub fn run<R: BufRead, W: Write>(i: R, o: &mut W) {
    let mut i = CpReader::new(i);
    let (n, m) = i.read::<(usize, usize)>();
    let a = i.read_vec::<usize>(m);

    writeln!(o, "{}", solve(n, a)).unwrap();
}
fn solve(n: usize, mut a: Vec<usize>) -> usize {
    let mut count = (Mod::new(1), Mod::new(0));
    a.push(usize::max_value());

    let mut j = 0;
    for i in 0..n {
        if i == a[j] {
            j += 1;
            count = (count.1, Mod::new(0));
        } else {
            count = (count.0 + count.1, count.0);
        }
    }
    (count.0).0
}

pub mod utils {
    use super::*;

    pub struct CpReader<R: BufRead> {
        r: R,
        b: Vec<u8>,
    }
    impl<R: BufRead> CpReader<R> {
        pub fn new(r: R) -> Self {
            CpReader {
                r: r,
                b: Vec::new(),
            }
        }
        pub fn read_word(&mut self) -> &[u8] {
            self.b.clear();
            let mut consume = 0;
            loop {
                self.r.consume(consume);
                let b = self.r.fill_buf().unwrap();
                assert!(b.len() != 0);
                if let Some(p) = b.iter().position(|&x| x == b' ' || x == b'\n') {
                    self.b.extend_from_slice(&b[..p]);
                    consume = p + 1;
                    break;
                }
                self.b.extend_from_slice(b);
                consume = b.len();
            }
            self.r.consume(consume);
            &self.b
        }
        pub fn read_word_str(&mut self) -> &str {
            unsafe { std::str::from_utf8_unchecked(self.read_word()) }
        }

        pub fn read_line(&mut self) -> &[u8] {
            self.b.clear();
            self.r.read_until(b'\n', &mut self.b).unwrap();
            if self.b.last() == Some(&b'\n') {
                &self.b[..self.b.len() - 1]
            } else {
                &self.b
            }
        }
        pub fn read_line_str(&mut self) -> &str {
            unsafe { std::str::from_utf8_unchecked(self.read_line()) }
        }

        pub fn read<T: CpIn>(&mut self) -> T {
            T::read_from(self)
        }

        pub fn read_vec<T: CpIn>(&mut self, n: usize) -> Vec<T> {
            (0..n).map(|_| self.read()).collect()
        }
        pub fn read_iter<'a, T: CpIn>(&'a mut self, n: usize) -> CpIter<'a, R, T> {
            CpIter {
                r: self,
                n: n,
                _pd: Default::default(),
            }
        }
    }
    pub struct CpIter<'a, R: BufRead + 'a, T> {
        r: &'a mut CpReader<R>,
        n: usize,
        _pd: std::marker::PhantomData<fn() -> T>,
    }
    impl<'a, R: BufRead, T: CpIn> Iterator for CpIter<'a, R, T> {
        type Item = T;
        fn next(&mut self) -> Option<T> {
            if self.n == 0 {
                None
            } else {
                self.n -= 1;
                Some(self.r.read())
            }
        }
    }

    pub trait CpIn {
        fn read_from<R: BufRead>(r: &mut CpReader<R>) -> Self;
    }

    impl CpIn for u64 {
        fn read_from<R: BufRead>(r: &mut CpReader<R>) -> Self {
            read_u64_fast(&mut r.r)
        }
    }
    impl CpIn for i64 {
        fn read_from<R: BufRead>(r: &mut CpReader<R>) -> Self {
            read_i64_fast(&mut r.r)
        }
    }
    impl CpIn for char {
        fn read_from<R: BufRead>(r: &mut CpReader<R>) -> Self {
            let b = r.r.fill_buf().unwrap()[0] as char;
            r.r.consume(1);
            let s = r.r.fill_buf().unwrap()[0];
            assert!(s == b' ' || s == b'\n');
            r.r.consume(1);
            b
        }
    }

    macro_rules! cpin_tuple {
        ($($t:ident),*) => {
            impl<$($t: CpIn),*> CpIn for ($($t),*) {
                fn read_from<R: BufRead>(r: &mut CpReader<R>) -> Self {
                    ($($t::read_from(r)),*)
                }
            }
        };
    }

    macro_rules! cpin_cast {
        ($t_self:ty, $t_read:ty) => {
            impl CpIn for $t_self {
                fn read_from<R: BufRead>(r: &mut CpReader<R>) -> Self {
                    <$t_read>::read_from(r) as $t_self
                }
            }
        };
    }
    macro_rules! cpin_parse {
        ($t:ty) => {
            impl CpIn for $t {
                fn read_from<R: BufRead>(r: &mut CpReader<R>) -> Self {
                    r.read_word_str().parse().unwrap()
                }
            }
        };
    }
    cpin_cast!(usize, u64);
    cpin_cast!(u32, u64);
    cpin_cast!(u16, u64);
    cpin_cast!(i32, i64);
    cpin_cast!(i16, i64);
    cpin_cast!(i8, i64);

    cpin_parse!(f64);

    cpin_tuple!(T1, T2);
    cpin_tuple!(T1, T2, T3);
    cpin_tuple!(T1, T2, T3, T4);
    cpin_tuple!(T1, T2, T3, T4, T5);

    fn read_u64_fast<R: BufRead>(r: &mut R) -> u64 {
        let mut value = 0;
        loop {
            let mut idx = 0;
            let buf_len;
            {
                let buf = r.fill_buf().unwrap();
                buf_len = buf.len();
                assert!(buf_len != 0);
                while idx < buf_len && b'0' <= buf[idx] && buf[idx] <= b'9' {
                    value = value * 10 + (buf[idx] - b'0') as u64;
                    idx += 1;
                }
            }
            if idx < buf_len {
                r.consume(idx + 1);
                return value;
            }
            r.consume(idx);
        }
    }
    fn read_i64_fast<R: BufRead>(r: &mut R) -> i64 {
        let (consume, sign) = match r.fill_buf().unwrap()[0] {
            b'+' => (true, 1),
            b'-' => (true, -1),
            _ => (false, 1),
        };
        if consume {
            r.consume(1);
        }
        read_u64_fast(r) as i64 * sign
    }

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

    use std::fmt;
    impl fmt::Debug for Mod {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "{:?}", self.0)
        }
    }

    const MOD_BASE: usize = 1000000007;
    const MOD_INV_POW: usize = MOD_BASE - 2;

    impl Mod {
        pub fn new(n: usize) -> Self {
            Mod(n % MOD_BASE)
        }
        pub fn pow(self, mut exp: usize) -> Self {
            let mut b = self;
            let mut r = Mod(1);
            while exp != 0 {
                if exp % 2 == 1 {
                    r *= b;
                }
                exp /= 2;
                b = b * b;
            }
            r
        }
        pub fn inverse_element(self) -> Self {
            self.pow(MOD_INV_POW)
        }

        pub fn comb(n: usize, m: usize) -> Mod {
            let mut v0 = Mod::new(1);
            let mut v1 = Mod::new(1);
            for i in 0..min(m, n - m) {
                v0 *= i + 1;
                v1 *= n - i;
            }
            v1 / v0
        }
    }

    macro_rules! mod_op {
        (($ot:ident, $f:ident), ($ot_a:ident, $f_a:ident), $($rhs:ty : $e:expr,)*) => {
            $(
            impl $ot<$rhs> for Mod {
                type Output = Self;
                fn $f(self, rhs: $rhs) -> Self {
                    ($e)(self, rhs)
                }
            }
            impl $ot_a<$rhs> for Mod {
                fn $f_a(&mut self, rhs: $rhs) {
                    *self = ($e)(*self, rhs)
                }
            }
            )*
        }
    }

    mod_op!(
        (Add, add),
        (AddAssign, add_assign),
        Mod : |l: Mod, r: Mod| Mod::new(l.0 + r.0),
        usize : |l: Mod, r: usize| l + Mod::new(r),
    );

    mod_op!(
        (Mul, mul),
        (MulAssign, mul_assign),
        Mod : |l: Mod, r: Mod| Mod::new(l.0 * r.0),
        usize : |l: Mod, r: usize| l * Mod::new(r),
    );

    mod_op!(
        (Sub, sub),
        (SubAssign, sub_assign),
        Mod : |l: Mod, r: Mod| Mod::new(MOD_BASE + l.0 - r.0),
        usize : |l: Mod, r: usize| l - Mod::new(r),
    );

    mod_op!(
        (Div, div),
        (DivAssign, div_assign),
        Mod : |l: Mod, r: Mod| l * r.inverse_element(),
        usize : |l: Mod, r: usize| l / Mod::new(r),
    );

}


// Try AtCoder
// author: Leonardone @ NEETSDKASU

fn main() {
    let mut stdin = String::new();
    std::io::Read::read_to_string(
        &mut std::io::stdin(),
        &mut stdin).unwrap();
    let mut stdin = stdin.split_whitespace();
    let mut get = || stdin.next().unwrap();
    macro_rules! get {
        ($t:ty) => (get().parse::<$t>().unwrap());
        () => (get!(i64));
    }

    let md = 1_000_000_007;
    let n = get!(usize);
    let m = get!();
    let mut cur = 0;
    let mut dp = vec![0; n+3];
    dp[cur] = 1;
    for _ in 0..m {
        let a = get!(usize);
        if cur == a {
            println!("0");
            return;
        }
        for i in cur..a {
            dp[i+1] = (dp[i+1] + dp[i]) % md;
            dp[i+2] = (dp[i+2] + dp[i]) % md;
        }
        cur = a + 1;
    }
    for i in cur..n {
        dp[i+1] = (dp[i+1] + dp[i]) % md;
        dp[i+2] = (dp[i+2] + dp[i]) % md;
    }
    println!("{}", dp[n]);
}


/*------------------------------------------------------------------*/
/*------------------------- begin template -------------------------*/
/*------------------------------------------------------------------*/

// ref: tanakh <https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8>
// diff: using Parser
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut parser = Parser::from_str($s);
        input_inner!{parser, $($r)*}
    };
    (parser = $parser:ident, $($r:tt)*) => {
        input_inner!{$parser, $($r)*}
    };
    (new_stdin_parser = $parser:ident, $($r:tt)*) => {
        let stdin = std::io::stdin();
        let reader = std::io::BufReader::new(stdin.lock());
        let mut $parser = Parser::new(reader);
        input_inner!{$parser, $($r)*}
    };
    ($($r:tt)*) => {
        input!{new_stdin_parser = parser, $($r)*}
    };
}

macro_rules! input_inner {
    ($parser:ident) => {};
    ($parser:ident, ) => {};
    ($parser:ident, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($parser, $t);
        input_inner!{$parser $($r)*}
    };
}

macro_rules! read_value {
    ($parser:ident, ( $($t:tt),* )) => {
        ( $(read_value!($parser, $t)),* )
    };
    ($parser:ident, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($parser, $t)).collect::<Vec<_>>()
    };
    ($parser:ident, chars) => {
        read_value!($parser, String).chars().collect::<Vec<char>>()
    };
    ($parser:ident, char_) => {
        read_value!($parser, String).chars().collect::<Vec<char>>()[0]
    };
    ($parser:ident, usize1) => {
        read_value!($parser, usize) - 1
    };
    ($parser:ident, i64_) => {
        $parser.fast_i64()
    };
    ($parser:ident, usize_) => {
        $parser.fast_i64() as usize
    };
    ($parser:ident, usize1_) => {
        ($parser.fast_i64() - 1) as usize
    };
    ($parser:ident, $t:ty) => {
        $parser.next::<$t>().expect("Parse error")
    };
}

use std::io;
use std::io::BufRead;
use std::str;

// ref: tatsuya6502 <https://qiita.com/tatsuya6502/items/cd448486f7ef7b5b8c7e>
// ref: wariuni <https://qiita.com/tatsuya6502/items/cd448486f7ef7b5b8c7e#comment-7040a5ae96305e884eb9>
// diff: using std::io::BufRead::fill_buf()
pub struct Parser<R> {
    pub reader: R,
    buf: Vec<u8>,
    pos: usize,
}

impl Parser<io::Empty> {
    pub fn from_str(s: &str) -> Parser<io::Empty> {
        Parser {
            reader: io::empty(),
            buf: s.as_bytes().to_vec(),
            pos: 0,
        }
    }
}

impl<R: BufRead> Parser<R> {
    pub fn new(reader: R) -> Parser<R> {
        Parser {
            reader: reader,
            buf: vec![],
            pos: 0,
        }
    }
    pub fn update_buf(&mut self) {
        self.buf.clear();
        self.pos = 0;
        loop {
            let (len, complete) = {
                let buf2 = self.reader.fill_buf().unwrap();
                self.buf.extend_from_slice(buf2);
                let len = buf2.len();
                (len, buf2[len - 1] <= 0x20)
            };
            self.reader.consume(len);
            if complete {
                break;
            }
        }
    }
    pub fn next<T: str::FromStr>(&mut self) -> Result<T, T::Err> {
        loop {
            let mut begin = self.pos;
            while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                begin += 1;
            }
            let mut end = begin;
            while end < self.buf.len() && (self.buf[end] > 0x20) {
                end += 1;
            }
            if begin != self.buf.len() {
                self.pos = end;
                return unsafe { str::from_utf8_unchecked(&self.buf[begin..end]) }.parse::<T>();
            } else {
                self.update_buf();
            }
        }
    }
    pub fn fast_i64(&mut self) -> i64 {
        loop {
            let mut begin = self.pos;
            while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                begin += 1;
            }
            if begin == self.buf.len() {
                self.update_buf();
                continue;
            }
            let mut res = 0;
            let (is_positive, mut end) = match self.buf[begin] {
                b'+' => (true, begin + 1),
                b'-' => (false, begin + 1),
                _ => (true, begin),
            };
            while end < self.buf.len() && (self.buf[end] > 0x20) {
                res = res * 10 + (self.buf[end] as i64 - '0' as i64);
                end += 1;
            }
            if begin != self.buf.len() {
                self.pos = end;
                return if is_positive { res } else { -res };
            } else {
                self.update_buf();
            }
        }
    }
}

#[allow(unused_imports)]
use std::cmp::*;
use std::marker::PhantomData;
use std::ops::*;

pub trait ModP {
    fn as_u64() -> u64;
}

#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug)]
pub struct Mod_1_000_000_007();
impl ModP for Mod_1_000_000_007 {
    fn as_u64() -> u64 {
        1_000_000_007
    }
}

#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug)]
pub struct Mod_998_244_353();
impl ModP for Mod_998_244_353 {
    fn as_u64() -> u64 {
        998_244_353
    }
}

#[derive(Clone, Copy, PartialEq, Debug)]
pub struct Modular<P: ModP + Copy>(u32, PhantomData<P>);

impl<P: ModP + Copy> Modular<P> {
    pub fn new(x: u32) -> Modular<P> {
        Modular((x as u64 % P::as_u64()) as u32, PhantomData)
    }
    pub fn pow(self, n: u64) -> Modular<P> {
        if n == 0 {
            return Modular(1, PhantomData);
        }
        let t = self.pow(n / 2);
        if n % 2 == 0 {
            t * t
        } else {
            t * t * self
        }
    }
    pub fn as_u32(self) -> u32 {
        self.0
    }
}

impl<P: ModP + Copy> Add for Modular<P> {
    type Output = Self;
    fn add(self, rhs: Self) -> Self::Output {
        let t = (self.0 + rhs.0) as u64;
        let u = if t < P::as_u64() { t } else { t - P::as_u64() };
        Modular(u as u32, PhantomData)
    }
}

impl<P: ModP + Copy> AddAssign for Modular<P> {
    fn add_assign(&mut self, rhs: Self) {
        *self = *self + rhs;
    }
}

impl<P: ModP + Copy> Sub for Modular<P> {
    type Output = Self;
    fn sub(self, rhs: Self) -> Self::Output {
        let t = if self.0 >= rhs.0 {
            self.0 as u64 - rhs.0 as u64
        } else {
            self.0 as u64 + P::as_u64() - rhs.0 as u64
        };
        assert!(t < P::as_u64());
        Modular(t as u32, PhantomData)
    }
}

impl<P: ModP + Copy> SubAssign for Modular<P> {
    fn sub_assign(&mut self, rhs: Self) {
        *self = *self - rhs;
    }
}

impl<P: ModP + Copy> Neg for Modular<P> {
    type Output = Modular<P>;
    fn neg(self) -> Modular<P> {
        Modular((P::as_u64() - self.0 as u64) as u32, PhantomData)
    }
}

impl<P: ModP + Copy> Mul for Modular<P> {
    type Output = Self;
    fn mul(self, rhs: Self) -> Self::Output {
        Modular(
            ((self.0 as u64 % P::as_u64()) * (rhs.0 as u64 % P::as_u64()) % P::as_u64()) as u32,
            PhantomData,
        )
    }
}

impl<P: ModP + Copy> MulAssign for Modular<P> {
    fn mul_assign(&mut self, rhs: Self) {
        *self = *self * rhs;
    }
}

impl<P: ModP + Copy> Div for Modular<P> {
    type Output = Self;
    fn div(self, rhs: Self) -> Self::Output {
        if rhs.0 == 0 {
            loop {}
        }
        assert!(rhs.0 != 0);
        self * rhs.pow(P::as_u64() - 2)
    }
}

pub fn gen_fact_table<P: ModP + Copy>(n: usize) -> Vec<Modular<P>> {
    let mut res = vec![Modular::<P>::new(1); n + 1];
    for i in 0..n {
        res[i + 1] = res[i] * Modular::<P>::new((i + 1) as u32);
    }
    res
}

pub fn gen_inv_table<P: ModP + Copy>(n: usize) -> Vec<Modular<P>> {
    let mut res = vec![Modular::<P>::new(0); n + 1];
    res[1] = Modular::<P>::new(1);
    for i in 2..n + 1 {
        res[i] =
            -res[P::as_u64() as usize % i] * Modular::<P>::new((P::as_u64() / i as u64) as u32);
    }
    res
}

fn main() {
    input! {
        new_stdin_parser = parser,
    }
    let res = solve(&mut parser);
    print!("{}", res);
}

/*------------------------------------------------------------------*/
/*-------------------------- end template --------------------------*/
/*------------------------------------------------------------------*/

type Mod = Modular<Mod_1_000_000_007>;

use std::fmt::Write;
fn solve<R: BufRead>(parser: &mut Parser<R>) -> String {
    let mut buf = String::new();
    input! {
        parser = parser,
        n: usize,
        m: usize,
        xs: [usize; m],
    }
    let mut ys = vec![true; n + 1];
    for &x in &xs {
        ys[x] = false;
    }
    let ys = ys;
    let mut zs = vec![Mod::new(0); n + 1];
    zs[0] = Mod::new(1);
    for i in 1..n + 1 {
        if ys[i] {
            if i >= 1 && ys[i - 1] {
                zs[i] += zs[i - 1];
            }
            if i >= 2 && ys[i - 2] {
                zs[i] += zs[i - 2];
            }
        }
    }
    // eprintln!("zs = {:?}", zs);
    writeln!(buf, "{}", zs[n].as_u32());
    buf
}


use proconio::{input, fastout};
use std::usize::MAX;

const MOD: usize = 1_000_000_007;

fn dp(step_cnt: &mut Vec<usize>, steps: usize) -> usize {
    if step_cnt[steps] != MAX { return step_cnt[steps]; }
    step_cnt[steps] = ( dp(step_cnt, steps-1) + dp(step_cnt, steps-2) ) % MOD;
    step_cnt[steps]
}

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

    let mut step_cnt: Vec<usize> = vec![MAX; n];
    step_cnt[0] = 1;
    step_cnt[1] = 1;
    step_cnt[2] = 2;

    let mut ans = 1;
    let mut last_idx = 0;
    let mut it = broken.iter();
    let f = it.next();
    match f {
        None => (),
        Some(1) => { last_idx = 1 },
        Some(i) => {
            ans = dp(&mut step_cnt, i-last_idx-1);
            last_idx = *i
        },
    }
    for i in it {
        if i-last_idx==1 { ans=0; break }
        ans = ans * dp(&mut step_cnt, i-last_idx-2) % MOD;
        last_idx = *i;
    }
    ans = ans * dp(&mut step_cnt, n-last_idx-1) % MOD;

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


use proconio::{fastout, input};

#[fastout]
fn main() {
    input! {
        n: usize,
        m: usize,
        a: [u128; m]
    };
    let a: Vec<u128> = a;

    let base = (10i32.pow(9) + 7) as u128;
    let mut result = 1;

    let f = |x: u128| -> u128 {
        if x <= 2 {
            return 1;
        } else {
            let n = x - 2;
            let i = 2;
            let tmp = (n * (n - 1)) / 2;

            return i + tmp;
        }
    };

    let mut prev = n as u128;

    for i in 0..=m {
        if i < m {
            if prev + 1 == a[i] {
                result = 0;
                break;
            }
        }

        if i == 0 {
            let x = a[i];
            let r = f(x);
            result *= r;
            result %= base;
            prev = a[i];
        } else if i == m {
            let x = n as u128 - a[m as usize - 1];
            let r = f(x);
            result *= r;
            result %= base;
        } else {
            let x = a[i] - a[i - 1] - 1;
            let r = f(x);
            result *= r;
            result %= base;
            prev = a[i];
        }
    }

    println!("{}", result % base);
}


use std::cmp::*;
use std::collections::*;
use std::io::*;
use std::str::FromStr;

fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

fn main() {
    let MOD: i64 = 1000000007;
    let n:usize = read();
    let m:usize = read();
    let mut dp:Vec<i64> = vec![0;n + 1];
    for i in 0..m{
        let a:usize = read();
        dp[a] = -1;
    }
    dp[0] = 1;
    for i in 1..n + 1{
       if dp[i] != -1 && dp[i - 1] != -1 {
           dp[i] += dp[i - 1];
           dp[i] %= MOD;
       }
           if i > 1  && dp[i] != -1 && dp[i - 2] != -1{
               dp[i] += dp[i - 2];
               dp[i] %= MOD;
           }
    }
    println!("{:?}",dp);
    println!("{}",dp[n]);
}


import Foundation

func readWords<T>(_ f: (Substring) -> T) -> [T] {
    return readLine()!.split(separator: " ").map(f)
}

func main() {
    let nm = readWords { Int($0)! }
    let n = nm[0]
    let m = nm[1]
    let mod = 1_000_000_007

    var dp = Array(repeating: 0, count: n+1)
    dp[0] = 1

    var safe = Array(repeating: true, count: n+1)

    for _ in 0..<m {
        let a = Int(readLine()!)!
        safe[a] = false
    }

    for i in 0..<n {
        if i+1 <= n && safe[i+1] {
            dp[i+1] += dp[i]
            dp[i+1] %= mod
        }

        if i+2 <= n && safe[i+2] {
            dp[i+2] += dp[i]
            dp[i+2] %= mod
        }
    }
    print(dp.last!)
}

main()


let inp = readLine()!.split(separator: " ").map { Int($0)! }

let n = inp[0]
let m = inp[1]

let mod = 1000000007

var banned = Set<Int>()

for _ in 0..<m {
  let a = Int(readLine()!)!
  banned.insert(a)
}

var dp: [Int] = .init(repeating: 0, count: n + 1)

dp[0] = 1
for i in 1...n {
  if banned.contains(i) {
    continue
  }
  dp[i] = dp[i-1] + (i - 2 < 0 ? 0 : dp[i-2])
  dp[i] %= mod
}
print(dp[n] % mod)


import Foundation

let args = readLine()!.split(separator: " ")
let N = Int(args[0])!
let M = Int(args[1])!
let a = [Int](unsafeUninitializedCapacity: M) { buffer, _ in
    for m in 0 ..< M {
        buffer[m] = Int(readLine()!)!
    }
}

var step = 0
var s1 = 1
var s2 = 0

var n = N - 1
var m = M - 1
while 0 <= n {
    let isStepBroken = 0 <= m && a[m] == n
    if isStepBroken {
        step = 0
        m -= 1
    } else {
        step = (s1 + s2) % 1_000_000_007
    }
    s2 = s1
    s1 = step
    n -= 1
}
let answer = step

print(answer)


// 🐋💭
import Foundation

func readInts() -> [Int] {
    return readLine()!.split(separator: " ").map { Int($0)! }
}

func readInt() -> Int {
    return Int(readLine()!)!
}

func readDoubles () -> [Double] {
    return readLine()!.split(separator: " ").map { Double($0)! }
}

func readDouble() -> Double{
    return Double(readLine()!)!
}

func readLines() -> [String] {
    return readLine()!.map { String($0) }
}
///最大公約数を返す
func gcd(_ m:Int, _ n:Int) -> Int {
    if n == 0 {return m}
    return gcd(n, m % n)
}

///最大公約数を返す
func gcd(_ array: [Int]) -> Int {
    var value = array[0]
    if array.count > 1 {
        for i in 1..<array.count {
            value = gcd(value, array[i])
        }
    }
    return value
}

///最小公倍数を返す
func lcm(_ m:Int, _ n:Int) -> Int {
    return m * n / gcd(m, n)
}

///素数判定(試し割り)
func isPrime(_ x:Int) -> Bool {
    if x <= 1 || x % 2 == 0 { return false }
    if x == 2 { return true }
    for i in stride(from: 3, to: Int(ceil(sqrt(Double(x)))), by: 2){
        if x % i == 0 {
            return false
        }
    }
    return true
}

//https://program-life.com/669
///実行速度の計測
func exectionTime(action: () -> Void) {
    let startDate = Date()
    action()
    let endDate = Date()
    print(endDate.timeIntervalSince(startDate))
}

//https://riptutorial.com/ja/swift/example/14738/インデックスを知らずに配列から要素を削除する
extension Array where Element: Equatable {

    mutating func remove(_ element: Element) {
        _ = firstIndex(of: element).flatMap {
            self.remove(at: $0)
        }
    }
}

func binarySearch(rifgt:Int, key:Int, ary:[String]) -> Int{
    var left = 0
    var right = rifgt

    while abs(right - left) > 1 {
        let mid = left + (right - left) / 2

        if Int(ary[mid])! < key {
            left = mid

        } else {
            right = mid
        }
    }
    return left
}

func arrangement (prev:String, ary:[String], returnVal:[String]) -> [String] {
    var returnVal = returnVal
    if ary.count == 0 {
        returnVal.append(prev)
        return returnVal
    }

    for s in ary {
        let wprev = prev + s
        var wary = ary
        wary.remove(s)
        returnVal = arrangement(prev: wprev, ary: wary, returnVal: returnVal)
    }
    return returnVal
}
// https://algo-logic.info/divisor/
/// 約数の配列を返す
func divisor(_ n:Int) -> [Int] {
    var ret = [Int]()
    var i = 1
    while i * i <= n {
        if n % i == 0 {
            ret.append(i)
            if i * i != n {
                ret.append(n / i)
            }
        }
        i += 1
    }
    return ret.sorted()
}

/// 1〜nまでの数字からなる辞書順列のm番目の順列を返す
func permutation(_ n: Int, _ m: Int) -> [Int] {
    var m = m

    var temp = [Int](repeating: 0, count: n)
    var surplus = [Int](repeating: 0, count: n)

    for i in 1...n {
        temp[i - 1] = i

        surplus[n - i] = m % i
        m = m / i
    }

    var order = [Int](repeating: 0, count: n)

    for i in 0..<n {
        order[i] = temp[surplus[i]]
        var j = surplus[i]
        while j + 1 < n {
            temp[j] = temp[j + 1]
            j += 1
        }
    }
    return order
}
func check(_ ary: [Int], _ n: Int) -> Bool {
    for i in 0..<ary.count {
        if ary[i] == n { return true }
    }
    return false
}

func main() {
    let input = readInts()
    let (N, M) = (input[0], input[1])
    var a = [Bool](repeating: true, count: N + 1)
    for _ in 0..<M {
        a[readInt()] = false
    }
    //＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿＿ここまで入力
    // DP法
    let mod = 1000000007
    var dp = [Int](repeating: 0, count: N + 1)
    dp[0] = 1
    if a[1] { dp[1] = 1 }

    for i in 2...N {
        if a[i - 1] { dp[i] += dp[i - 1] }
        if a[i - 2] { dp[i] += dp[i - 2] }
        dp[i] %= mod
    }

    print(dp.last!)

}
main()


import Foundation

// Example1
//let N = 6
//let M = 1
//let a = [3]

// Example2
//let N = 10
//let M = 2
//let a = [4, 5]

// Example3
//let N = 100
//let M = 5
//let a = [1, 23, 45, 67, 89]

let array = readLine()!.split(separator: " ")
let N = Int(array[0])!
let M = Int(array[1])!
var a = [Int](repeating: 0, count: M)
for m in 0 ..< M {
    a[m] = Int(readLine()!)!
}

/*
 Example1:
 ---------------------
 n | N1, N2 | S
 ---------------------
 0 |  1,  2 | 2 + 2 -> 4
 1 |  2,  3 | 2 + 0 -> 2
 2 |  3,  4 | 0 + 2 -> 2
 3 |  7,  7 | 0 + 0 -> 0
 4 |  5,  6 | 1 + 1 -> 2
 5 |  6,  7 | 1 + 0 -> 1
 6 |                   1 ; goal
 7 |                   0 ; over or broken
*/

var N1 = [Int](repeating: 0, count: N)
var N2 = [Int](repeating: 0, count: N)
var S = [Int](repeating: 0, count: N + 2)
S[N] = 1
S[N + 1] = 0

var m = 0

for n in 0 ..< N {
    let isStepBroken = m < M && a[m] == n
    if isStepBroken {
        N1[n] = N + 1
        N2[n] = N + 1
        m += 1
    } else {
        N1[n] = n + 1
        N2[n] = n + 2
    }
}
for n in (0 ..< N).reversed() {
    S[n] = S[N1[n]] + S[N2[n]]
}
let answer = S[0] % 1_000_000_007

print(answer)


import Foundation

func readWords<T>(_ f: (Substring) -> T) -> [T] {
    return readLine()!.split(separator: " ").map(f)
}

func main() {
    let nm = readWords { Int($0)! }
    let n = nm[0]
    let m = nm[1]
    let mod = 1_000_000_007

    var dp = Array(repeating: 0, count: n+1)
    dp[0] = 1

    var safe = Array(repeating: true, count: n+1)

    for _ in 1...m {
        let a = Int(readLine()!)!
        safe[a] = false
    }

    for i in 0..<n {
        if i+1 <= n && safe[i+1] {
            dp[i+1] += dp[i]
            dp[i+1] %= mod
        }

        if i+2 <= n && safe[i+2] {
            dp[i+2] += dp[i]
            dp[i+2] %= mod
        }
    }
    print(dp.last!)
}

main()


const input=require('fs').readFileSync('/dev/stdin','utf8').split(/[\s]/);let input_i=-1;const tn=():number=>{input_i++;return Number(input[input_i])};const tnn=(n:number):number[]=>{const a=[];for(let i=0;i<n;i++){a.push(tn())}return a};const ts=():string=>{input_i++;return String(input[input_i])};const tss=(n:number):string[]=>{const a=[];for(let i=0;i<n;i++){a.push(ts())}return a};const to=(...arg)=>{console.log(...arg)};const abs=(a)=>{return Math.abs(a)};const min=(...a)=>{return Math.min(...a)};const max=(...a)=>{return Math.max(...a)};const floor=(a)=>{return Math.floor(a)};const asc=(ar:number[])=>{const t=[...ar];return ar.sort((a,b)=>{return a-b})};const desc=(ar:number[])=>{const t=[...ar];return t.sort((a,b)=>{return b-a})};const sw=(a,arr:any[],op:'=='|'>='|'>'|'<='|'<'='==')=>{for(let i=0;i<arr.length-1;i+=2){if(eval(a+op+arr[i])){return arr[i+1]}}return arr[arr.length-1]};const near=(n:number,arr:number[]):number=>{let ne=arr[0],ni=0;for(let i=1;i<arr.length;i++){if(Math.abs(n-ne)>Math.abs(n-arr[i])){ne=arr[i];ni=i}}return ni};const deduplicate=(a:any[]):any[]=>{return Array.from(new Set(a))};
//
const main=()=>{
  let [n,m]=tnn(2),mr=tnn(m),dp=new Array(n+1),x=1000000007
  dp[n]=1;
  dp[n-1]=1;
  for(let j=0;j<mr.length;j++){
    dp[mr[j]]=0
    if(mr[j]==mr[j+1]-1){
      to(0)
      return
    }
  }
  for(let i=n-2;i>=0;i--){
    if(dp[i]!=0)dp[i]=(dp[i+1]+dp[i+2])%x
  }
  to(dp[0])
}
main()


{
  const _mod = 10 ** 9 + 7

  const main = (input: string) => {
    const r = reader(input)
    const [n, _m] = r.ns()
    const a = r.nls()

    const dp: number[] = Array(n + 1)

    dp.fill(0)
    a.forEach(ai => (dp[ai] = -1))
    dp[0] = 1

    for (let i = 0; i < n; i++) {
      // console.log(dp.join(' '))
      if (dp[i] === -1) continue

      if (dp[i + 1] !== -1) {
        dp[i + 1] = (dp[i + 1] + dp[i]) % _mod
      }
      if (dp[i + 2] !== -1) {
        dp[i + 2] = (dp[i + 2] + dp[i]) % _mod
      }
    }
    console.log(dp[n])
  }

  const reader = (str: string) => {
    const lines = str.trim().split('\n')
    const s = () => lines.shift() || ''
    const n = () => Number(s())

    const ss = () => s().split(' ')
    const ns = () => ss().map(Number)
    const nls = () => lines.map(Number)

    return { lines, s, n, ss, ns, nls }
  }

  const getInput = () => require('fs').readFileSync('/dev/stdin', 'utf8')

  main(getInput())
}


'use strict'
const main = (input: string) => {
    // DP法苦手すぎて解説読んだ
    const std: string[] = input.split('\n')
    const [n, m] = std.shift().split(' ').map(Number)
    const holes: number[] = std.map(Number)
    let dp: number[] = []
    dp[0] = 1
    dp[1] = 1
    holes.forEach(v => dp[v] = 0)
    for (let i = 2; i <= n; i++) {
        if (dp[i] === 0) continue
        dp[i] = (dp[i-1] + dp[i-2]) % 1000000007
    }
    console.log(dp[n])
}
main(require('fs').readFileSync('/dev/stdin', 'utf8').trim())


const input=require('fs').readFileSync('/dev/stdin','utf8').split(/[\s]/);let input_i=-1;const tn=():number=>{input_i++;return Number(input[input_i])};const tnn=(n:number):number[]=>{const a=[];for(let i=0;i<n;i++){a.push(tn())}return a};const ts=():string=>{input_i++;return String(input[input_i])};const tss=(n:number):string[]=>{const a=[];for(let i=0;i<n;i++){a.push(ts())}return a};const to=(...arg)=>{console.log(...arg)};const abs=(a)=>{return Math.abs(a)};const min=(...a)=>{return Math.min(...a)};const max=(...a)=>{return Math.max(...a)};const floor=(a)=>{return Math.floor(a)};const asc=(ar:number[])=>{const t=[...ar];return ar.sort((a,b)=>{return a-b})};const desc=(ar:number[])=>{const t=[...ar];return t.sort((a,b)=>{return b-a})};const sw=(a,arr:any[],op:'=='|'>='|'>'|'<='|'<'='==')=>{for(let i=0;i<arr.length-1;i+=2){if(eval(a+op+arr[i])){return arr[i+1]}}return arr[arr.length-1]};const near=(n:number,arr:number[]):number=>{let ne=arr[0],ni=0;for(let i=1;i<arr.length;i++){if(Math.abs(n-ne)>Math.abs(n-arr[i])){ne=arr[i];ni=i}}return ni};const deduplicate=(a:any[]):any[]=>{return Array.from(new Set(a))};
//
const main=()=>{
  let [n,m]=tnn(2),mr=tnn(m),dp=new Array(n+1),x=1000000007
  for(let j=0;j<mr.length-1;j++){
    if(mr[j]==mr[j+1]-1){
      to(0)
      return
    }
  }
  dp[n]=1;
  dp[n-1]=1;
  for(let i=n-2;i>=0;i--){
    let f=0
    for(let j=0;j<mr.length;j++){
      if(i==mr[j]){
        f=1
        dp[i]=0
        break
      }
    }
    if(!f)dp[i]=(dp[i+1]+dp[i+2])%x
  }
  to(dp[0])
}
main()


const input=require('fs').readFileSync('/dev/stdin','utf8').split(/[\s]/);let input_i=-1;const tn=():number=>{input_i++;return Number(input[input_i])};const tnn=(n:number):number[]=>{const a=[];for(let i=0;i<n;i++){a.push(tn())}return a};const ts=():string=>{input_i++;return String(input[input_i])};const tss=(n:number):string[]=>{const a=[];for(let i=0;i<n;i++){a.push(ts())}return a};const to=(...arg)=>{console.log(...arg)};const abs=(a)=>{return Math.abs(a)};const min=(...a)=>{return Math.min(...a)};const max=(...a)=>{return Math.max(...a)};const floor=(a)=>{return Math.floor(a)};const asc=(ar:number[])=>{const t=[...ar];return ar.sort((a,b)=>{return a-b})};const desc=(ar:number[])=>{const t=[...ar];return t.sort((a,b)=>{return b-a})};const sw=(a,arr:any[],op:'=='|'>='|'>'|'<='|'<'='==')=>{for(let i=0;i<arr.length-1;i+=2){if(eval(a+op+arr[i])){return arr[i+1]}}return arr[arr.length-1]};const near=(n:number,arr:number[]):number=>{let ne=arr[0],ni=0;for(let i=1;i<arr.length;i++){if(Math.abs(n-ne)>Math.abs(n-arr[i])){ne=arr[i];ni=i}}return ni};const deduplicate=(a:any[]):any[]=>{return Array.from(new Set(a))};
const main=()=>{
  let [n,m]=tnn(2),mr=tnn(m),dp=new Array(n+1),x=1000000007
  dp[0]=1,dp[1]=1
  for(let j=0;j<mr.length-1;j++){
    if(mr[j]==mr[j+1]-1){
      to(0)
      return
    }
  }
  for(let i=2;i<=n;i++){
    let f=0
    for(let j=0;j<mr.length;j++){
      if(i==mr[j]){
        f=1
        dp[i]=dp[i-1]
        if(n>=i+1)dp[i+1]=dp[i-1]
        if(n>=i+2)dp[i+2]=dp[i-1]
        i+=2
        mr.pop()
        break
      }
    }
    if(!f)dp[i]=(dp[i-2]+dp[i-1])%x
  }
  to(dp[n])
}
main()


const input=require('fs').readFileSync('/dev/stdin','utf8').split(/[\s]/);let input_i=-1;const tn=():number=>{input_i++;return Number(input[input_i])};const tnn=(n:number):number[]=>{const a=[];for(let i=0;i<n;i++){a.push(tn())}return a};const ts=():string=>{input_i++;return String(input[input_i])};const tss=(n:number):string[]=>{const a=[];for(let i=0;i<n;i++){a.push(ts())}return a};const to=(...arg)=>{console.log(...arg)};const abs=(a)=>{return Math.abs(a)};const min=(...a)=>{return Math.min(...a)};const max=(...a)=>{return Math.max(...a)};const floor=(a)=>{return Math.floor(a)};const asc=(ar:number[])=>{const t=[...ar];return ar.sort((a,b)=>{return a-b})};const desc=(ar:number[])=>{const t=[...ar];return t.sort((a,b)=>{return b-a})};const sw=(a,arr:any[],op:'=='|'>='|'>'|'<='|'<'='==')=>{for(let i=0;i<arr.length-1;i+=2){if(eval(a+op+arr[i])){return arr[i+1]}}return arr[arr.length-1]};const near=(n:number,arr:number[]):number=>{let ne=arr[0],ni=0;for(let i=1;i<arr.length;i++){if(Math.abs(n-ne)>Math.abs(n-arr[i])){ne=arr[i];ni=i}}return ni};const deduplicate=(a:any[]):any[]=>{return Array.from(new Set(a))};
const main=()=>{
  let [n,m]=tnn(2),mr=tnn(m),dp=new Array(n+1),x=1000000007
  dp[0]=1,dp[1]=1
  for(let j=0;j<mr.length-1;j++){
    if(mr[j]==mr[j+1]-1){
      to(0)
      return
    }
  }
  for(let i=2;i<=n;i++){
    let f=0
    for(let j=0;j<mr.length;j++){
      if(i==mr[j]){
        f=1
        dp[i]=dp[i-1]
        if(n>=i+1)dp[i+1]=dp[i-1]
        if(n>=i+2)dp[i+2]=dp[i-1]
        i+=2
        break
      }
    }
    if(!f)dp[i]=(dp[i-2]+dp[i-1])%x
  }
  to(dp[n])
}
main()


def gcd(a,b):
    if b == 0:
        return a
    else:
        return gcd(b,a%b)
a,b = map(int,input().split())
print(int(a * b / gcd(a, b)))


a,b = map(int,input().split())

def gcd(a, b):
    while b:
        a, b = b, a % b
    return a

def lcm(x, y):
    return (x * y) // gcd(x, y)

print(lcm(a,b))


def inpl():
    return list(map(int, input().split()))

def gcd(a, b):
    # greatest common divisor
    while b > 0:
        a, b = b, a % b

    return a

def lcm(a, b):
    # least common multiple
    return a * b // gcd(a, b)

A, B = inpl()

print(lcm(max(A, B), min(A, B)))


import math
a, b = map(int, raw_input().split());
print(a * b / math.gcd(a,b))


a,b = map(int,input().split())
if a%b==0 or b%a==0:
    print(max(a,b))
else:
    print(a*b)


import numpy as np

A, B = map(int, input().split())

print(lcm(A, B))


import java.io.IOException;
import java.io.InputStream;
import java.util.NoSuchElementException;

public class Main {

	public static void main(String[] args) {

		FastScanner sc = new FastScanner();
		long A = sc.nextInt();
		long B = sc.nextInt();

		System.out.println(A * B / gcd(A, B));

	}

	public static long gcd(long a, long b) {

		if (a < b)
			return gcd(b, a);

		long c = 0;
		c = a % b;

		if (c == 0)
			return b;

		return gcd(b, c);
	}
}

class FastScanner {
	private final InputStream in = System.in;
	private final byte[] buffer = new byte[1024];
	private int ptr = 0;
	private int buflen = 0;

	private boolean hasNextByte() {
		if (ptr < buflen) {
			return true;
		} else {
			ptr = 0;
			try {
				buflen = in.read(buffer);
			} catch (IOException e) {
				e.printStackTrace();
			}
			if (buflen <= 0) {
				return false;
			}
		}
		return true;
	}

	private int readByte() {
		if (hasNextByte())
			return buffer[ptr++];
		else
			return -1;
	}

	private static boolean isPrintableChar(int c) {
		return 33 <= c && c <= 126;
	}

	public boolean hasNext() {
		while (hasNextByte() && !isPrintableChar(buffer[ptr]))
			ptr++;
		return hasNextByte();
	}

	public String next() {
		if (!hasNext())
			throw new NoSuchElementException();
		StringBuilder sb = new StringBuilder();
		int b = readByte();
		while (isPrintableChar(b)) {
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	public long nextLong() {
		if (!hasNext())
			throw new NoSuchElementException();
		long n = 0;
		boolean minus = false;
		int b = readByte();
		if (b == '-') {
			minus = true;
			b = readByte();
		}
		if (b < '0' || '9' < b) {
			throw new NumberFormatException();
		}
		while (true) {
			if ('0' <= b && b <= '9') {
				n *= 10;
				n += b - '0';
			} else if (b == -1 || !isPrintableChar(b)) {
				return minus ? -n : n;
			} else {
				throw new NumberFormatException();
			}
			b = readByte();
		}
	}

	public int nextInt() {
		long nl = nextLong();
		if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE)
			throw new NumberFormatException();
		return (int) nl;
	}

	public double nextDouble() {
		return Double.parseDouble(next());
	}
}


import java.io.*;
import java.util.*;

class Main{
    final static long MOD = 1000000007;
    FastScanner sc = new FastScanner();

    public static void main(String[] args) {
        new Main().solve();
    }

    void solve(){

        long a = sc.nextLong();
        long b = sc.nextLong();

        System.out.println(a * b / gcd(a, b));

    }

    long gcd(long a, long b){ // return aとbの最大公約数
        if(b == 0){
          return a;
        }
        return gcd(b, a % b);
    }

    long pow_mod(long a, long r){ // return a^r (mod MOD)
        long sum = 1;
        while(r > 0){
            if((r & 1) == 1){
                sum *= a;
                sum %= MOD;
            }
            a *= a;
            a %= MOD;
            r >>= 1;
        }
        return sum;
    }

}

class FastScanner {
    private final InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;
    private boolean hasNextByte(){
        if(ptr < buflen){
            return true;
        }else{
            ptr = 0;
            try{
                buflen = in.read(buffer);
            }catch(IOException e){
                e.printStackTrace();
            }
            if(buflen <= 0){
                return false;
            }
        }
        return true;
    }
    private int readByte(){ if(hasNextByte()) return buffer[ptr++]; else return -1;}
    private static boolean isPrintableChar(int c){ return 33 <= c && c <= 126;}
    public boolean hasNext(){ while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++; return hasNextByte();}
    public String next(){
        if(!hasNext()) throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)){
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }
    public long nextLong(){
        if(!hasNext()) throw new NoSuchElementException();
        long n = 0;
        boolean minus = false;
        int b = readByte();
        if(b == '-'){
            minus = true;
            b = readByte();
        }
        if(b < '0' || '9' < b){
            throw new NumberFormatException();
        }
        while(true){
            if('0' <= b && b <= '9'){
                n *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return minus ? -n : n;
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
    public int nextInt(){
        long nl = nextLong();
        if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE) throw new NumberFormatException();
        return (int) nl;
    }
    public double nextDouble(){ return Double.parseDouble(next());}
}