#include using namespace std; using ll = long long; using ull = unsigned long long; int dp[1001][1001]; int jumps[1001]; int main() { ios::sync_with_stdio(0); cin.tie(0); int N, M; string s, reg; cin >> N >> s >> M >> reg; for (int i = 0; i < 1001; ++i) { for (int j = 0; j < 1001; ++j) { dp[i][j] = -1; } } for (int i = 0; i < 1001; ++i) { jumps[i] = -1; } int last_par = -1; int last_block = -1; for (int i = 0; i < M; i++) { switch(reg[i]) { case '(': last_par = i; break; case '[': last_block = i; break; case '*': switch (reg[i - 1]) { case ')': jumps[i] = last_par; jumps[last_par] = i + 1; last_par = -1; case ']': jumps[i] = last_block; jumps[last_block] = i + 1; last_block = -1; default: jumps[i] = i - 1; jumps[i-1] = i + 1; } break; } } dp[0][0] = 0; for (int i = 0; i < N; i++) { bool is_block = false; bool matched = false; for (int j = 0; j < M; j++) { if (!is_block) { matched = false; dp[i + 1][j] = max(dp[i][j], dp[i+1][j]); } if (jumps[j] != -1) { dp[i][jumps[j]] = max(dp[i][j], dp[i][jumps[j]]); } switch (reg[j]) { case '[': is_block = true; break; case ']': is_block = false; break; case '(': case ')': break; case '*': dp[i+1][jumps[j]] = max(dp[i+1][jumps[j]], dp[i][j]); break; case '?': matched = true; break; default: matched = s[i] == reg[j]; break; } if (is_block) { dp[i][j+1] = max(dp[i][j] + (matched ? 1 : 0), dp[i][j+1]); } if (matched && !is_block) { dp[i+1][j+1] = max(dp[i][j] + 1, dp[i+1][j+1]); } } dp[i+1][M] = max(dp[i+1][M], dp[i][M]); continue; for (int i = 0; i <= N; ++i) { for (int j = 0; j <= M; ++j) { cout << dp[i][j] << ' '; } cout << '\n'; } cout << '\n'; } cout << dp[N][M] << '\n'; return 0; }