import Control.Arrow
import Data.List
import qualified Data.ByteString.Char8 as B
import Debug.Trace

main :: IO ()
main = breads >>= print . solve 

solve :: [Int] -> Int
solve [n, m] = fst $ foldl' ff (1, (0, [1])) $ traceShowId ns
    where
        ff (acc, (s, t)) x = (val $ acc * cs !! b, (a, cs))
            where
                a = n + x - 1
                b = min x $ n - 1
                cs = build a s t

        ns = sort $ calc ps m 0 []
        ps = primes m
        calc (x : xs) v c acc
            | v == 1 && c > 0 = c : acc
            | v == 1 = acc
            | b == 0 = calc (x : xs) a (c + 1) acc
            | c > 0 = calc xs v 0 $ c : acc
            | otherwise = calc xs v 0 acc
            where
                (a, b) = v `divMod` x
        calc _ _ c acc
            | c > 0 = c : acc
            | otherwise = acc 

primes :: Int -> [Int]
primes x = loop [2..x]
    where
        loop (y : ys)
            | y > m = y : ys
            | otherwise = (y :) . loop $ filter (\n -> n `mod` y /= 0) ys
        loop _ = []
        m = truncate . sqrt $ fromIntegral x

val :: Int -> Int
val = (`mod` m)
    where
        m = 10 ^ 9 + 7

breads :: IO [Int]
breads = unfoldr (\s -> second (maybe B.empty snd . B.uncons) <$> B.readInt s) <$> B.getLine

pascal :: Int -> [Int] 
pascal n = build n 0 [1]
    
build :: Int -> Int -> [Int] -> [Int]
build n m xs
    | n == m = xs
    | otherwise = build n (m + 1) $ nextPascal xs 
        
nextPascal :: [Int] -> [Int]
nextPascal = next . (0 :)
    where
        next (x : y : zs) = (val $ x + y) : next (y : zs)
        next xs = xs