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

import Data.Bits
import Data.Maybe (fromJust)
import Data.List
import Data.Array  --変数衝突
import Data.Array.Unboxed
import Data.Array.MArray
import Data.Array.ST
import Data.Graph
--import Data.Vector as V　--変数衝突
import qualified Data.ByteString.Lazy.Char8 as B
import qualified Data.Vector.Unboxed as V
import Control.Monad
import Control.Monad.State
import Control.Monad.ST
import Debug.Trace

type DP s = STUArray s (Int,Int) Int

dp_i :: DP s -> Int -> [Char] -> Int -> ST s ()
dp_i dparr n [] _ = return ()
dp_i dparr n (c:s) k = do
  if c == '<'
    then forM [1..n-1] $ \i -> do
      (forM [1..i] $ \j -> readArray dparr (k,j)) >>= writeArray dparr (k+1,i) .mod'.sum
    else forM [1..n-1] $ \i -> do
      (forM [i+1..n] $ \j -> readArray dparr (k,j)) >>= writeArray dparr (k+1,i).mod' .sum
  dp_i dparr (n-1) s (k+1)

solve :: Int -> String -> ST s Int
solve n s = do
  dparr <- newArray ((1,1),(n,n)) 0
  forM_ [1..n] $ \i -> writeArray dparr (1,i) 1
  dp_i dparr n s 1
  forM [1..n] (\i -> readArray dparr (n,i)) >>= return.mod'. sum

readBInt :: B.ByteString -> Int
readBInt = fst . fromJust . B.readInt

main0 :: B.ByteString -> Int
main0 cont =
   let remLines0 = map B.words (B.lines cont)
       [n']:remLines1 = remLines0
       n = readBInt n'
       [line2]:remLines2 = remLines1
       s = B.unpack line2
   in mod' $ runST $ solve n s

main :: IO ()
main = print . main0 =<< B.getContents

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