{-# LANGUAGE BangPatterns      #-} --引数に!
{-# LANGUAGE MultiWayIf        #-}
{-# LANGUAGE TupleSections     #-}

import Data.List
import Data.Array
import Data.Array.MArray
import Data.Array.ST
import qualified Data.Vector.Unboxed as V (last,(!),fromList,Vector)
import Control.Monad
import Control.Monad.State
import Control.Monad.ST
import Debug.Trace

type Table = Array Int [Int] -- True == White, x <= y
type DP s = STUArray s (Bool,Int) Int

--TLE!!!
--DFS
dp_i :: DP s -> Table -> Int -> Int -> Int -> ST s ()
dp_i dparr table n prev v = do
  let nh = filter (/=prev) (table!v)
  if nh == []
      then forM_ [False,True] $ \c -> writeArray dparr (c,v) 1
      else do
        ls <- forM nh $ \v' -> do
          dp_i dparr table n v v'
          nextF <- readArray dparr (False,v')
          nextT <- readArray dparr (True,v')
          return (nextT+nextF,nextT)
        let ls' = foldl1' (\(a,b) (c,d) -> (mod0 $ a*c,mod0 $ b*d)) ls
        writeArray dparr (False,v) $ mod0 $ snd ls'
        writeArray dparr (True,v)  $ mod0 $ fst ls'

setArr :: Int -> [(Int,Int)] -> Table
setArr n xs = runST $ do
  arr <- newArray (1,n) [] :: ST s (STArray s Int [Int])
  setArrsub arr xs >>= freeze
    where
      setArrsub :: (STArray s Int [Int]) -> [(Int,Int)] -> ST s (STArray s Int [Int])
      setArrsub arr' [] = return arr'
      setArrsub arr' ((a,b):as) = do
        readArray arr' a >>= (writeArray arr' a).(b:)
        readArray arr' b >>= (writeArray arr' b).(a:)
        setArrsub arr' as

solve :: [(Int,Int)] -> Int -> ST s Int
solve ls n = do
  let table = setArr n ls
  dparr  <- newArray ((False,1),(True,n)) 0
  dp_i dparr table n (-1) 1
  ans0 <- forM [False,True] $ \c -> readArray dparr (c,1)
  return $ mod0 $ sum ans0


main :: IO ()
main = do
   n <- read <$> getLine
   ls <- replicateM (n-1) $ do
     (x:y:_) <- map read.words <$> getLine
     return (x,y)
   putStrLn $ show $ runST $ solve ls n

mod0 :: Int -> Int
mod0 n = if n < 1000000007 then n else mod n 1000000007
