#include <iostream>
#include <vector>
#include <string>
using namespace std;
const int MOD = 1000000007;
// Function to compute the number of ways s_i and s_j can be matched
int ways(char s_i, char s_j) {
// Possible matching pairs: '()', '[]', '{}'
if (s_i == '?' && s_j == '?') {
return 3; // '()', '[]', '{}'
} else if (s_i == '?') {
// s_i can be '(', '[', '{' to match s_j
if (s_j == ')') return 1; // s_i must be '('
if (s_j == ']') return 1; // s_i must be '['
if (s_j == '}') return 1; // s_i must be '{'
return 0;
} else if (s_j == '?') {
// s_j can be ')', ']', '}' to match s_i
if (s_i == '(') return 1; // s_j must be ')'
if (s_i == '[') return 1; // s_j must be ']'
if (s_i == '{') return 1; // s_j must be '}'
return 0;
} else {
// Both are specific characters
if ((s_i == '(' && s_j == ')') ||
(s_i == '[' && s_j == ']') ||
(s_i == '{' && s_j == '}'))
return 1;
else
return 0;
}
}
int main() {
int N;
string s;
cin >> N;
cin >> s;
// Edge case: if N is odd, no correct bracket sequence is possible
if (N % 2 != 0) {
cout << 0 << endl;
return 0;
}
// Initialize DP table
vector<vector<int>> dp(N + 1, vector<int>(N + 1, 0));
// Base case: empty substrings
for (int i = 0; i <= N; ++i) {
dp[i][i] = 1;
}
// DP over substring lengths
for (int len = 1; len <= N; ++len) {
for (int i = 0; i + len <= N; ++i) {
int j = i + len;
// Check for matching pair at positions i and j - 1
int w = ways(s[i], s[j - 1]);
if (w > 0) {
dp[i][j] = (dp[i][j] + (1LL * dp[i + 1][j - 1] * w) % MOD) % MOD;
}
// Split the substring into two parts and sum up the ways
for (int k = i + 1; k < j; ++k) {
dp[i][j] = (dp[i][j] + (1LL * dp[i][k] * dp[k][j]) % MOD) % MOD;
}
}
}
// Output the result modulo 1e9 + 7
cout << dp[0][N] << endl;
return 0;
}