z = input().split()
z = [ int(x) for x in z]
broken = []
for i in range(z[1]):
    broken.append(input())
#print(broken)

max_step = z[0] 
import numpy as np

all_possible = []
candidate = np.ones(max_step)

def steps(cand):
  tmp = np.zeros_like(cand)
  for j in range(len(cand)):
    for i in range(len(cand[0])):
        tmp[j][i] = sum(cand[j][:i+1])
  return tmp

original_step = []
template_steps = []
for i in range(int(max_step/2), max_step+1):
    template_steps = []
    #iは段の数
    original_step.append(np.ones(i))
    #i = 5  1 = 0 ,2 = 5
    #i = 10 1 = 10, 2 = 0
    # 1 ... (i - 5) * 2  2 ... -1 * i + 10
    #1... (i - max_step/2)  2...-1 * i  + max_step
    num_1 =int( (i - max_step/2)*2)
    num_2 = (-1 * i + max_step)
    for i in range(num_1):
        template_steps.append(1)
    for i in range(num_2):
        template_steps.append(2)
        
    import itertools
    arrays = []
    for v in itertools.permutations(template_steps):
        arrays.append(v)

    array_unique = list(set(arrays))
    #print(array_unique)
    all_possible.append(array_unique)

    
count = 0
all_count = 0
for i in range(len(all_possible)):
  #print(i)
  all_possible[i] = steps(all_possible[i])
  for j in range(len(all_possible[i])):
    all_count += 1
    for b in broken:
      if  list(all_possible[i][j]).count(int(b)) > 0:
        all_possible[i][j]= 0
        count += 1
        
print((all_count - count)%1000000007)