import Control.Monad
 
import Data.Ord
import Data.List
import Data.Function
import Data.Maybe

import qualified Data.ByteString.Char8 as BS

import Debug.Trace

tuplify2 :: [a] -> (a, a)
tuplify2 (x:y:_) = (x, y)
tuplify2 _ = undefined

readInt = read :: String -> Integer
readIntTuple = tuplify2 . map readInt . words
readIntList = map readInt . words

getInt = readInt <$> getLine
getIntList = readIntList <$> getLine
getIntMatrix = map readIntList . lines <$> getContents
getIntTuple = readIntTuple <$> getLine
getIntTuples = map readIntTuple . lines <$> getContents

indicesToBools xs = orderedIndicesToBooleans [0..] (sort xs)
  where
    orderedIndicesToBooleans _ []            = repeat False
    orderedIndicesToBooleans (x:xs) yall@(y:ys)
      | x == y    = True  : orderedIndicesToBooleans xs ys
      | otherwise = False : orderedIndicesToBooleans xs yall

main = do
  [n,m] <- getIntList
  as <- concat <$> getIntMatrix
  let combos = 0 : 1 : zipWith3 f (tail (indicesToBools as)) combos (tail combos)
  print $ combos !! (fromIntegral n+1)

-- ある段への移動方法の組み合わせ数を求める
-- a: その段が壊れている
-- prevCombo: 前の段への組み合わせ数
-- prevPrevCombo: 前の前の段への組み合わせ数
f isBroken prevCombo prevPrevCombo
  | isBroken  = 0
  | otherwise = (prevCombo + prevPrevCombo) `mod` 1000000007