Problem:


Score : 100 points

Problem Statement

Let N be a positive integer.
You are given a string s of length N - 1, consisting of < and >.

Find the number of permutations (p_1, p_2, \ldots, p_N) of (1, 2, \ldots, N) that satisfy the following condition, modulo 10^9 + 7:

For each i (1 \leq i \leq N - 1), p_i < p_{i + 1} if the i-th character in s is <, and p_i > p_{i + 1} if the i-th character in s is >.

Constraints

N is an integer.

2 \leq N \leq 3000

s is a string of length N - 1.

s consists of < and >.

Input

Input is given from Standard Input in the following format:

N
s

Output

Print the number of permutations that satisfy the condition, modulo 10^9 + 7.

Sample Input 1

4
<><

Sample Output 1

5

There are five permutations that satisfy the condition, as follows:

(1, 3, 2, 4)

(1, 4, 2, 3)

(2, 3, 1, 4)

(2, 4, 1, 3)

(3, 4, 1, 2)

Sample Input 2

5
<<<<

Sample Output 2

1

There is one permutation that satisfies the condition, as follows:

(1, 2, 3, 4, 5)

Sample Input 3

20
>>>><>>><>><>>><<>>

Sample Output 3

217136290

Be sure to print the number modulo 10^9 + 7.



Sample input:
4
<><


Sample output:
5

Submission status: Runtime Error

Solution code:
n = int(input())
s = input()
M = 10**9 + 7

dp = [[None] * n for _ in range(n)]
def dfs(zk, i=0):
    if dp[zk][i] is not None:
        return dp[zk][i]

    if i == n - 1:
        dp[zk][i] = 1
        return 1

    zj = n - i - zk - 1
    cnt = 0

    if s[i] == "<":
        for v in range(zk):
            cnt += dfs(v, i + 1)
    else:
        for v in range(zj):
            cnt += dfs(zk + v, i + 1)
    dp[zk][i] = cnt
    return cnt

def mod(v):
    if v >= M:
        return v % M
    return v

def cumsum(array):
    array = array[:]
    for i in range(len(array) - 1):
        array[i + 1] = mod(array[i + 1] + array[i])
    return array + [0]

for i in reversed(range(n)):
    for zk in range(n):
        if i == n - 1:
            dp[i][zk] = 1
            continue

        zj = n - i - zk - 1
        cnt = 0

        if s[i] == "<":
                # cnt = mod(cnt + dp[i + 1][v])
                cnt = cs[v]
        else:
                # cnt = mod(cnt + dp[i + 1][zk + v])
                cnt = cs[zk + zj - 1] - cs[zk - 1]
        dp[i][zk] = cnt
    cs = cumsum(dp[i])

# for i in range(n):
#     print(dfs(i))
# print(sum(dfs(i) for i in range(n - 1)) % M)
print(sum(dp[0]) % M)

Submission status: Runtime Error

Solution code:
n = int(input())
s = input()
M = 10**9 + 7

dp = [[None] * n for _ in range(n)]
def dfs(zk, i=0):
    if dp[zk][i] is not None:
        return dp[zk][i]

    if i == n - 1:
        dp[zk][i] = 1
        return 1

    zj = n - i - zk - 1
    cnt = 0

    if s[i] == "<":
        for v in range(zk):
            cnt += dfs(v, i + 1)
    else:
        for v in range(zj):
            cnt += dfs(zk + v, i + 1)
    dp[zk][i] = cnt
    return cnt

def mod(v):
    if v >= M:
        return v % M
    return v

def cumsum(array):
    array = array.copy()
    for i in range(len(array) - 1):
        array[i + 1] = mod(array[i + 1] + array[i])
    return array + [0]

for i in reversed(range(n)):
    for zk in range(n):
        if i == n - 1:
            dp[i][zk] = 1
            continue

        zj = n - i - zk - 1
        cnt = 0

        if s[i] == "<":
            for v in range(zk):
                # cnt = mod(cnt + dp[i + 1][v])
                cnt = cs[v]
        else:
            for v in range(zj):
                # cnt = mod(cnt + dp[i + 1][zk + v])
                cnt = cs[zk + zj - 1] - cs[zk - 1]
        dp[i][zk] = cnt
    cs = cumsum(dp[i])

# for i in range(n):
#     print(dfs(i))
# print(sum(dfs(i) for i in range(n - 1)) % M)
print(sum(dp[0]) % M)

Submission status: Runtime Error

Solution code:
#include <bits/stdc++.h>

static struct FASTIO {

  char READ_CHARACTER; bool REMAINING_CHARACTER = false;

  inline void ignore(); inline void flush();

  template <typename T> inline bool READ_INT(T &x); template <typename T> inline bool READ_STRING(T &x);
  /*                                                          Fast I/O Code Optimizer                                                          */
  template<size_t N> inline bool READ_CHAR_ARRAY(char (&x)[N]); template<size_t N> inline bool READ_VAR(char (&x)[N]);
  /*                    A tool to optimize execution time of C++ codes by replacing methods of reading and writing variables                   */
  template <typename T> inline bool READ_CHAR(T &x); inline bool READ_CHAR_ARRAY(char*& x); inline bool READ_GETLINE(std::string &x);
  /*                                                    Use it on fastio.pythonanywhere.com                                                    */
  template <typename T> inline bool READ_FLOAT(T &x); template <typename T> inline bool READ_DOUBLE(T &x);
  /*                                          Github Project: github.com/bfs07/Fast-IO-Code-Optimizer                                          */
  template<std::size_t N> inline bool READ_BITSET(std::bitset<N> &bit); template<std::size_t N> inline bool READ_VAR(std::bitset<N> &bit);
  inline bool READ_VAR(bool &x); inline bool READ_VAR(short int &x); inline bool READ_VAR(int &x); 
  inline bool READ_VAR(long int &x); inline bool READ_VAR(long long int &x); inline bool READ_VAR(unsigned short int &x);
  inline bool READ_VAR(unsigned int &x); inline bool READ_VAR(unsigned long &x); inline bool READ_VAR(unsigned long long &x);
  inline bool READ_VAR(std::string &x); inline bool READ_VAR(char &x); inline bool READ_VAR(char*& x); inline bool READ_VAR(float &x);
  inline bool READ_VAR(double &x); inline bool READ_VAR(long double &x); template <typename T> inline void WRITE_INT(T x);
  inline void WRITE_STRING(std::string &x); inline void WRITE_CHAR(char x); inline void WRITE_CHAR_ARRAY(const char *x);
  inline void WRITE_FLOAT(float x); template <typename T> inline void WRITE_DOUBLE(T x); inline void WRITE_VAR(bool x);
  inline void WRITE_VAR(short int x); inline void WRITE_VAR(int x); inline void WRITE_VAR(long int x); inline void WRITE_VAR(long long int x);
  inline void WRITE_VAR(unsigned short int x); inline void WRITE_VAR(unsigned int x); inline void WRITE_VAR(unsigned long x);
  inline void WRITE_VAR(unsigned long long x); inline void WRITE_VAR(char x); inline void WRITE_VAR(const char *x); 
  inline void WRITE_VAR(std::string &x); inline void WRITE_VAR(float x); inline void WRITE_VAR(double x); inline void WRITE_VAR(long double x);
  template<std::size_t N> inline void WRITE_VAR(std::bitset<N> &bit); template<std::size_t N> inline void WRITE_BITSET(std::bitset<N> &bit);

} __FIO__;


#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <random>
#include <cmath>
#include <chrono>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cassert>
using namespace std;
using LL = long long;
#define eps 1e-8
#define fi first
#define se second
#define eb emplace_back
#define close 0,0,0
#define FOR(i, x, y) for (LL i = (x), _##i = (y); i < _##i; ++i)
#define FORD(i, x, y) for (LL i = (x), _##i = (y); i > _##i; --i)
#define SORT_UNIQUE(c) (sort(c.begin(),c.end()), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#define CASET int ___T; scanf("%d", &___T); for(int __CS=1;__CS<=___T;__CS++)
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
mt19937 dlsrand(random_device{}());
mt19937 mrand(std::chrono::system_clock::now().time_since_epoch().count()); 
int rnd(int x) { return mrand() % x;}
LL bin(LL x, LL n, LL MOD) {LL ret = MOD != 1;for (x %= MOD; n; n >>= 1, x = x * x % MOD)if (n & 1) ret = ret * x % MOD;return ret;}
inline LL get_inv(LL x, LL p) { return bin(x, p - 2, p); }
const double PI = acos(-1.0);
constexpr int maxn = 3050;
constexpr int INF = 0x3f3f3f3f;
constexpr ll linf = 0x3f3f3f3f3f3f3f3f;
constexpr int mod = 1e9+7;
void add(int &a,int b) {a+=b; if(a>=mod) a-=mod;}
int n , dp[maxn][maxn], ans;
char c[maxn];
 
int main()
{
    __FIO__.READ_VAR(n);
    scanf("%s",c+1);
    dp[1][1] = 1;
    for(int i = 2; i <= n; i++){
        if(c[i-1] == '<'){
            for(int j = 2; j <= i; j++){
                dp[i][j] = (dp[i][j-1]+dp[i-1][j-1]) % mod;
            }
        }else {
            for(int j = i-1; j ; j--){
                dp[i][j] = (dp[i][j+1]+dp[i-1][j]) % mod;
            }
        }
    }
    for(int i = 1; i <= n; i++){
        add(ans, dp[n][i]);
    }
    __FIO__.WRITE_VAR(ans), putchar('\n');
}

#undef FOR
#undef FORD
#undef SORT_UNIQUE
#undef eps
#undef fi
#undef se
#undef eb
#undef close
#undef FOR
#undef FORD
#undef SORT_UNIQUE
#undef CASET

inline void FASTIO::ignore() {
  if(REMAINING_CHARACTER == true) REMAINING_CHARACTER = false; else READ_CHARACTER = getchar();
}

inline void FASTIO::flush() {
  fflush(stdout);
}

// cin modifications

template <typename T>
inline bool FASTIO::READ_INT(T &x) {
  x = 0; T sig = 1;
  if(!REMAINING_CHARACTER) READ_CHARACTER = getchar(), REMAINING_CHARACTER = true; else REMAINING_CHARACTER = false;
  while (!isdigit(READ_CHARACTER) && READ_CHARACTER != EOF) sig = (READ_CHARACTER == '-' ? -sig : sig), READ_CHARACTER = getchar();
  if(READ_CHARACTER == EOF) return REMAINING_CHARACTER = false, false;
  while (isdigit(READ_CHARACTER)) x = x * 10 + READ_CHARACTER - '0', READ_CHARACTER = getchar();
  x *= sig; REMAINING_CHARACTER = true;
  return true;
}

template <typename T>
inline bool FASTIO::READ_STRING(T &x) {
  x = "";
  if(!REMAINING_CHARACTER) READ_CHARACTER = getchar(), REMAINING_CHARACTER = true; else REMAINING_CHARACTER = false;
  while ((READ_CHARACTER == '\n' || READ_CHARACTER == '\t' || READ_CHARACTER == ' ')) READ_CHARACTER = getchar();
  if(READ_CHARACTER == EOF) return REMAINING_CHARACTER = false, false;
  while ((READ_CHARACTER != '\n' && READ_CHARACTER != '\t' && READ_CHARACTER != ' ' && READ_CHARACTER != EOF)) x += READ_CHARACTER, READ_CHARACTER = getchar();
  REMAINING_CHARACTER = true;
  return true;
}

inline bool FASTIO::READ_GETLINE(std::string &x) {
  x = "";
  if(!REMAINING_CHARACTER) READ_CHARACTER = getchar(), REMAINING_CHARACTER = true; else REMAINING_CHARACTER = false;
  if(READ_CHARACTER == EOF) return REMAINING_CHARACTER = false, false;
  while ((READ_CHARACTER != '\n' && READ_CHARACTER != EOF)) x += READ_CHARACTER, READ_CHARACTER = getchar();
  REMAINING_CHARACTER = false;
  return true;
}

template <typename T>
inline bool FASTIO::READ_CHAR(T &x) {
  if(!REMAINING_CHARACTER) READ_CHARACTER = getchar(), REMAINING_CHARACTER = true; else REMAINING_CHARACTER = false;
  if(READ_CHARACTER == EOF) return REMAINING_CHARACTER = false, false;
  while ((READ_CHARACTER == '\n' || READ_CHARACTER == '\t' || READ_CHARACTER == ' ')) READ_CHARACTER = getchar();
  x = READ_CHARACTER; REMAINING_CHARACTER = false;
  return true;
}


template<size_t N>
inline bool FASTIO::READ_CHAR_ARRAY(char (&x)[N]) {
  if(!REMAINING_CHARACTER) READ_CHARACTER = getchar(), REMAINING_CHARACTER = true; else REMAINING_CHARACTER = false;
  while ((READ_CHARACTER == '\n' || READ_CHARACTER == '\t' || READ_CHARACTER == ' ')) READ_CHARACTER = getchar();
  if(READ_CHARACTER == EOF) return REMAINING_CHARACTER = false, false;
  char *ptr = &x[0];
  while ((READ_CHARACTER != '\n' && READ_CHARACTER != '\t' && READ_CHARACTER != ' ' && READ_CHARACTER != EOF)) *ptr++ = READ_CHARACTER, READ_CHARACTER = getchar();
  *ptr = '\0', REMAINING_CHARACTER = true;
  return true;
}

inline bool FASTIO::READ_CHAR_ARRAY(char*& x) {
  std::string y;
  if(READ_STRING(y) == false)
    return false;
  x = new char[(int)y.size() + 1];
  strcpy(x, y.c_str());
  return true;
}

template <typename T>
inline bool FASTIO::READ_FLOAT(T &x) {
  return (scanf("%f", &x) != EOF);
}

template <typename T>
inline bool FASTIO::READ_DOUBLE(T &x) {
  double y;
  if(scanf("%lf", &y) == EOF) return false;
  x = y;
  return true;
}

template<std::size_t N>
inline bool FASTIO::READ_BITSET(std::bitset<N> &x) {
  if(!REMAINING_CHARACTER) READ_CHARACTER = getchar(), REMAINING_CHARACTER = true; else REMAINING_CHARACTER = false;
  while ((READ_CHARACTER == '\n' || READ_CHARACTER == '\t' || READ_CHARACTER == ' ')) READ_CHARACTER = getchar();
  if(READ_CHARACTER == EOF) return REMAINING_CHARACTER = false, false;
  int i = 0; REMAINING_CHARACTER = true;
  while (READ_CHARACTER == '0' || READ_CHARACTER == '1') x[i++] = READ_CHARACTER - '0', READ_CHARACTER = getchar();
  return true;
}

inline bool FASTIO::READ_VAR(short int &x) {
  return READ_INT(x);    
}

inline bool FASTIO::READ_VAR(int &x) {
  return READ_INT(x);    
}

inline bool FASTIO::READ_VAR(long int &x) {
  return READ_INT(x);    
}

inline bool FASTIO::READ_VAR(long long int &x) {
  return READ_INT(x);    
}

inline bool FASTIO::READ_VAR(unsigned short int &x) {
  return READ_INT(x);    
}

inline bool FASTIO::READ_VAR(unsigned int &x) {
  return READ_INT(x);    
}

inline bool FASTIO::READ_VAR(unsigned long &x) {
  return READ_INT(x);    
}

inline bool FASTIO::READ_VAR(unsigned long long &x) {
  return READ_INT(x);    
}

inline bool FASTIO::READ_VAR(std::string &x) {
  return READ_STRING(x);    
}

inline bool FASTIO::READ_VAR(char &x) {
  return READ_CHAR(x);
}

template<size_t N>
inline bool FASTIO::READ_VAR(char (&x)[N]) {
  return READ_CHAR_ARRAY(x);
}

inline bool FASTIO::READ_VAR(char*& x) {
  return READ_CHAR_ARRAY(x);
}

inline bool FASTIO::READ_VAR(float &x) {
  return READ_FLOAT(x);
}

inline bool FASTIO::READ_VAR(double &x) {
  return READ_DOUBLE(x);
}

inline bool FASTIO::READ_VAR(long double &x) {
  return READ_DOUBLE(x);
}

template<std::size_t N>
inline bool FASTIO::READ_VAR(std::bitset<N> &x) {
  return READ_BITSET(x);
}

// cout modifications

template <typename T>
inline void FASTIO::WRITE_INT(T x) {
  if (x < 0) {putchar('-'); x = -x; }
  char writeBuffer[20], *writePtr = writeBuffer;
  do {
    *writePtr++ = '0' + x % 10;
    x /= 10;
  }
  while (x);
  do  { putchar(*--writePtr); }
  while (writePtr > writeBuffer);
}

inline void FASTIO::WRITE_CHAR(char x) {
  putchar(x);
}

inline void FASTIO::WRITE_CHAR_ARRAY(const char *x) {
  while(*x != '\0')
    putchar(*x++);
}

inline void FASTIO::WRITE_STRING(std::string &x) {
  for(char c: x) 
    putchar(c);
}

inline void FASTIO::WRITE_FLOAT(float x) {
  printf("%f", x);
}

template <typename T>
inline void FASTIO::WRITE_DOUBLE(T x) {
  printf("%lf", (double)x);
}

template<std::size_t N>
inline void FASTIO::WRITE_BITSET(std::bitset<N> &x) {
  for(int i = (int)x.size() - 1; i >= 0; i--)
    putchar(x[i] + 48);
}

inline void FASTIO::WRITE_VAR(bool x) {
  WRITE_INT(x);
}

inline void FASTIO::WRITE_VAR(short int x) {
  WRITE_INT(x);    
}

inline void FASTIO::WRITE_VAR(int x) {
  WRITE_INT(x);    
}

inline void FASTIO::WRITE_VAR(long int x) {
  WRITE_INT(x);    
}

inline void FASTIO::WRITE_VAR(long long int x) {
  WRITE_INT(x);    
}

inline void FASTIO::WRITE_VAR(unsigned short int x) {
  WRITE_INT(x);    
}

inline void FASTIO::WRITE_VAR(unsigned int x) {
  WRITE_INT(x);    
}

inline void FASTIO::WRITE_VAR(unsigned long x) {
  WRITE_INT(x);    
}

inline void FASTIO::WRITE_VAR(unsigned long long x) {
  WRITE_INT(x);    
}

inline void FASTIO::WRITE_VAR(std::string &x) {
  WRITE_STRING(x);    
}

inline void FASTIO::WRITE_VAR(char x) {
  WRITE_CHAR(x);
}

inline void FASTIO::WRITE_VAR(const char *x) {
  WRITE_CHAR_ARRAY(x);
}

inline void FASTIO::WRITE_VAR(float x) {
  WRITE_FLOAT(x);
}

inline void FASTIO::WRITE_VAR(double x) {
  WRITE_DOUBLE(x);
}

inline void FASTIO::WRITE_VAR(long double x) {
  WRITE_DOUBLE(x);
}

template<std::size_t N>
inline void FASTIO::WRITE_VAR(std::bitset<N> &x) {
  WRITE_BITSET(x);
}

Submission status: Runtime Error

Solution code:
#include <algorithm>
#include <cmath>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <set>
#include <tuple>
#include <vector>

using namespace std;

#define rep(i, n) for (int64_t i = 0; i < (n); i++)
#define irep(i, n) for (int64_t i = 0; i <= (n); i++)
#define rrep(i, n) for (int64_t i = (n)-1; i >= 0; i--)
#define rirep(i, n) for (int64_t i = n; i >= 0; i--)

const int64_t MOD = 1e9 + 7;

int main()
{
    int n;
    string s;
    cin >> n >> s;

    vector<vector<int64_t>> dp(n, vector<int64_t>(n));
    vector<int64_t> dpsum(n + 1);
    rep(i, n)
    {
        if (i == 0) {
            rep(j, n)
            {
                dp[i][j] = j == 0 ? 1 : 0;
            }
        } else {
            rep(j, n)
            {
                if (j > i) {
                    dp[i][j] = 0;
                } else {
                    if (s[i - 1] == '>') {
                        dp[i][j] = (dpsum[i] - dpsum[j] + MOD) % MOD;
                    } else {
                        dp[i][j] = (dpsum[j] - dpsum[0] + MOD) % MOD;
                    }
                }
            }
        }
        dpsum[0] = 0;
        rep(j, n)
        {
            dpsum[j + 1] = (dpsum[j] + dp[i][j]) % MOD;
        }
    }
    cout << dpsum[n] << endl;

    return 0;
}

Submission status: Runtime Error

Solution code:
import numpy as np
mod = 10**9+7
N = int(input())
s = input()
dp = [[0]*N for _ in range(N)]
for i in range(N):
    dp[0][i] = 1
for i in range(1, N):
    if s[i-1] == '>':
        dp[i][0] = dp[i-1][0]
        for j in range(1, N-i):
            dp[i][j] = (dp[i][j-1] + dp[i-1][j])%mod
    else:
        for j in range(N-1)[::-1]:
            dp[i][j] = (dp[i][j+1]+dp[i-1][j+1])%mod
print(sum(dp[-1])%mod)

Submission status: Runtime Error

Solution code:
#from https://ikatakos.com/pot/programming_algorithm/contest_history/atcoder/2019/0106_educational_dp_3
from  itertools import accumulate
mod=1000000007
n=int(input())
s=input()
dp=[1]*n
for i in range(n-1):
    if s[i]==">":
        dp.reverese()
        dp=list(accumulate(dp[:-1]))
        dp.reverse()
    else:
        dp=list(accumulate(dp[:-1]))
    for j in range(len(dp)):
        dp[j]%=mod
print(dp[0])

Submission status: Runtime Error

Solution code:
#include <cstdio>
#include <cstring>
using namespace std;

const int N = 3005;
const int MOD = 1e9 + 7;
int n;

void add(int& a, int b) {
    a += b;
    if (a >= MOD) a -= MOD;
}

char p[N];
int dp[N][N];
// dp[i][j]: the count of permutations that with length i, 
//           ending with j

void solve() {
    memset(dp, 0, sizeof dp);
    dp[0][0] = 1; // only one way to have permutation length 1
    for (int i = 1; i < n; ++i) {
        int cnt = 0;
        if (p[i] == '>') {
            for (int j = i; ~j; --j) {
                add(cnt, dp[i - 1][j]);
                add(dp[i][j], cnt);
            }
        } else {
            for (int j = 0; j <= i; ++j) {
                add(dp[i][j], cnt);
                add(cnt, dp[i - 1][j]);
            }
        }
    }
    int ans = 0;
    for (int j = 0; j < n; ++j) add(ans, dp[n - 1][j]);
    printf("%d\n", ans);
}

void debug() {
    for (int i = 0; i < n; ++i, putchar('\n')) {
        for (int j = 0; j < n; ++j) {
            printf("%6d ", dp[i][j]);
        }
    }
}

int main() {
    while (~scanf("%d%s", &n, p + 1)) {
        solve();
        // debug();
    }
    return 0;
}

Submission status: Runtime Error

Solution code:
md = 10 ** 9 + 7
n = int(input())
s = input()
dp = [1] * n
for i in range(n - 1):
    if s[i] == "<":
        s = dp[0]
        for dpi in range(1, n - i - 1):
            dp[dpi] = s = (dp[dpi] + s) % md
        dp = dp[:-1]
    else:
        s = dp[-1]
        for dpi in range(n - i - 2, 0, -1):
            dp[dpi] = s = (dp[dpi] + s) % md
        dp = dp[1:]
print(dp[0])

Submission status: Runtime Error

Solution code:
def cnt(i, p, ns):
    if i == n - 1:
        return 1
    t = (p, ns)
    if t in memo:
        return memo[t]
    re = 0
    if s[i] == "<":
        st, ed = p + 1, n
    else:
        st, ed = 0, p
    for k in range(st, ed):
        if ns & (1 << k):
            re += cnt(i + 1, k, ns - (1 << k))
    memo[t] = re = re % md
    return re


memo = {}
md = 10 ** 9 + 7
n = int(input())
s = input()
ans = 0
for p in range(n):
    ans += cnt(0, p, ((1 << n) - 1) - (1 << p))
print(ans % md)

Submission status: Runtime Error

Solution code:
# coding: utf-8
from itertools import accumulate as accum
import sys
input = sys.stdin.readline

def f(N, s):
    MOD = int(1e9 + 7)
    dp = [[0] * N for _ in range(N)]
    for j in range(N):
        dp[0][j] = 1
    for i in range(1, N):
        dpi = dp[i]
        csum = list(accum(dp[i - 1], lambda x, y: (x + y) % MOD))
        csum_ = csum[N - i]
        for j in range(N - i):  # N-(i+1)+1 = N-i
            if s[i - 1] == "<":
                dpi[j] = (dpi[j] + csum_ - csum[j]) % MOD
            else:
                dpi[j] = (dpi[j] + csum[j]) % MOD
    return(dp[-1][0])

N = int(input()) # 2 <= N <= 30000
s = input().rstrip() # len(s) = N - 1

print(f(N, s))