#include using namespace std; using ll = long long; template using vt = vector; template using vvt = vector>; template using ttt = tuple; using tii = tuple; using vi = vector; #define rep(i,n) for(int i=0;i<(int)(n);i++) #define pb push_back #define mt make_tuple #define ALL(a) (a).begin(),(a).end() #define FST first #define SEC second #define DEB cerr<<"!"<0){if((n&1)==1)r=r*x%m;x=x*x%m;n>>=1;}return r%m;} inline ll lcm(ll d1, ll d2){return d1 / __gcd(d1, d2) * d2;} /*Coding Space*/ // 次の等式が非常に直観的で便利 // x = sum(c_i*d_i*u_i) mod P // [x : ans], [c_i : P/p_i], [d_i : p_iを法とするc_iの逆元], [u_i : p_iのときの余り], [P : 法p_iの積] (d_i*c_i == 1 (mod p_i)) // フェルマーの小定理を利用しているので互いに素である必要がある // で宣言しておいて、a, a_div, b, b_divは全部int型に収めておいた方がいい。あるいは多倍長整数型を使おう // https://yukicoder.me/wiki/%E4%B8%AD%E8%8F%AF%E9%A2%A8%E5%89%B0%E4%BD%99%E5%AE%9A%E7%90%86 // pair数が小さかったり、オンラインクエリだったらこれ⇔Lagrange CRA template // !! div == 0はやめろ T Newton_crt(T a, T a_div, T b, T b_div){ // 互いに素である必要? T t = pow(a_div, b_div - 2, b_div); t *= (b - a) + b_div; t %= b_div; return (a + a_div*t)%(a_div*b_div); } int main(){ int n,m; cin >> n >> m; vi in(m); rep(i,m) cin >> in[i]; ll div1 = 17 * 9920467; ll div2 = 592951213; ll ans_div1 = 0; int d = (n&1?1:0); { vi dp(n/2+d+1,0); rep(i,n/2+d+1){ rep(j,m){ if(i - in[j] >= 0) dp[i] += dp[i - in[j]] % div1; else dp[0] = 1; dp[i] %= div1; } } rep(i,n/2+d+1){ rep(j,m){ if(i + in[j] > n/2 + d&& i + in[j] < n) ans_div1 += ((ll)dp[i] * dp[n-i-in[j]-1])%div1; ans_div1 %= div1; } } } ll ans_div2 = 0; { vi dp(n/2+d+1); rep(i,n/2+d+1){ rep(j,m){ if(i - in[j] >= 0) dp[i] += dp[i - in[j]] % div2; else dp[0] = 1; dp[i] %= div2; } } rep(i,n/2+d+1){ rep(j,m){ if(i + in[j] > n/2 + d&& i + in[j] < n) ans_div2 += ((ll)dp[i] * dp[n-i-in[j]-1])%div2; ans_div2 %= div2; } } } //SHOW(ans_div1, ans_div2); cout << Newton_crt(ans_div1, div1, ans_div2, div2) << endl; }