import std.algorithm, std.container, std.conv, std.math, std.range, std.typecons, std.stdio, std.string;

struct Spl{auto r="".splitter;auto rd(){r=readln.splitter;}auto bd(T)(ref T t){t=r.front.to!T;r.popFront;}}
auto _s = Spl();
auto lkst(T...)(ref T t){static if(t.length==1)return t[0];else return lockstep(t);}
auto getV(T...)(ref T t){foreach(ref u;t)_s.bd(u);}
auto getA(T)(size_t n,ref T t){t=new T(n);foreach(ref u;t)_s.bd(u);}
auto readV(T...)(ref T t){_s.rd;getV(t);}
auto readC(T...)(size_t n,ref T t){foreach(ref u;t)u=new typeof(u)(n);lkst(t).each!readV;}

const mod = 10^^9+7;
alias mint = ModInt!mod;

void main()
{
  int n, m; readV(n, m);
  int[] a; readC(m, a);

  auto ai = 0;
  auto dp = new mint[](n+1); dp[0] = 1;
  foreach (i; 1..n+1) {
    if (ai < m && a[ai] == i) {
      ++ai;
    } else {
      dp[i] = dp[i-1];
      if (i >= 2) dp[i] += dp[i-2];
    }
  }

  writeln(dp[n]);
}

struct ModInt(int m, bool pos = false)
{
  version(BigEndian) union { long l; struct { int i2; int i; } } else union { long l; int i; }
  alias M = ModInt!(m, pos);
  @property static init() { return M(0); }
  @property int value() { return i; }
  @property void value(int v) { i = mod(v); }
  alias value this;

  this(int v) { i = v; }
  this(int v, bool runMod) { i = runMod ? mod(v) : v; }
  this(long v) { i = mod(v); }

  ref auto opAssign(int v) { i = v; return this; }

  pure auto mod(int v) const { static if (pos) return v%m; else return (v%m+m)%m; }
  pure auto mod(long v) const { static if (pos) return cast(int)(v%m); else return cast(int)((v%m+m)%m); }

  static if (!pos) pure auto opUnary(string op: "-")() { return M(mod(-i)); }

  static if (m < int.max / 2) {
    pure auto opBinary(string op)(int r) if (op == "+" || op == "-") { return M(mod(mixin("i"~op~"r"))); }
    ref auto opOpAssign(string op)(int r) if (op == "+" || op == "-") { i = mod(mixin("i"~op~"r")); return this; }
  } else {
    pure auto opBinary(string op)(int r) if (op == "+" || op == "-") { return M(mod(mixin("l"~op~"r"))); }
    ref auto opOpAssign(string op)(int r) if (op == "+" || op == "-") { i = mod(mixin("l"~op~"r")); return this; }
  }
  pure auto opBinary(string op: "*")(int r) { return M(mod(l*r)); }
  ref auto opOpAssign(string op: "*")(int r) { i = mod(l*r); return this; }

  pure auto opBinary(string op)(M r) if (op == "+" || op == "-" || op == "*") { return opBinary!op(r.i); }
  ref auto opOpAssign(string op)(M r) if (op == "+" || op == "-" || op == "*") { return opOpAssign!op(r.i); }

  pure auto opBinary(string op: "/")(M r) { return M(mod(l*r.inv.i)); }
  ref auto opOpAssign(string op: "/")(M r) { i = mod(l*r.inv.i); return this; }

  pure auto opBinary(string op: "/")(int r) { return opBinary!op(M(r)); }
  ref auto opOpAssign(string op: "/")(int r) { return opOpAssign!op(M(r)); }

  pure auto opBinary(string op: "^^", U)(U n)
  {
    auto x = M(1);
    if (n == 0) return x;

    auto b = M(i);
    for (; n > 0; n >>= 1) {
      if (n&1) x *= b;
      b *= b;
    }

    return x;
  }

  pure auto inv()
  {
    int x = i, a, b;
    exEuclid(x, m, a, b);
    return M(mod(a));
  }

  pure int exEuclid(int a, int b, ref int x, ref int y)
  {
    auto g = a;
    x = 1; y = 0;
    if (b) {
      g = exEuclid(b, a%b, y, x);
      y -= a/b*x;
    }
    return g;
  }
}


Measured memory_bytes: 3580