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

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

solve :: [Int] -> Int
solve [n, m] = prodOnVal . map mf . group $ sort es
    where
        mf x = fact (calcH $ head x) (length x)
        prodOnVal = foldl' (\l r -> val $ l * r) 1

        calcH v = val $ x * y
            where
                x = prodOnVal [n..(n + v - 1)]
                y = prodOnVal $ map inv [2..v]

        es = edit $ dcmp m [2..m]
        hm = truncate . sqrt $ fromIntegral m
        edit [] = [1]
        edit xs = xs
        
        dcmp v (x : xs)
            | x > v = []
            | v `mod` x /= 0 = dcmp v xs
            | otherwise = c : dcmp w xs
            where
                (c, w) = count x v
        dcmp _ _ = []

        
        count = loop 0
            where
                loop acc x v
                    | b == 0 = loop (acc + 1) x a
                    | otherwise = (acc, v)
                    where
                        (a, b) = v `divMod` x

inv :: Int -> Int 
inv = (`fact` m)
    where
        m = 10 ^ 9 + 5

fact :: Int -> Int -> Int
fact b e
    | e == 0 = 1
    | odd e = val $ b * fact b (e - 1)
    | otherwise = val $ v * v
    where
        v = fact b $ e `div` 2

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