#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXEACH = 30;
int nraw, ncooked;
char s[2 * MAXEACH + 1];
long long C[2 * MAXEACH + 1][2 * MAXEACH + 1];
long long best;
set<long long> memfind[MAXEACH + 1][MAXEACH + 1];
void findbest(int n1, int n2, long long x1, long long x2) {
  if (x1 > x2) swap(n1, n2), swap(x1, x2);
  if (n1 < nraw || n2 < nraw) {
    best = min(best, x2 - x1);
    return;
  }
  if (x2 - x1 - C[n1][nraw] * C[n2][nraw] >= best) return;
  if (!memfind[n1][n2].insert(x2 - x1).second) return;
  findbest(n1 - 1, n2, x1 + C[n1 - 1][nraw - 1] * C[n2][nraw], x2);
  if (n1 != n2 || x1 != x2)
    findbest(n1, n2 - 1, x1, x2 + C[n1][nraw] * C[n2 - 1][nraw - 1]);
}
long long findbest() {
  best = LLONG_MAX;
  for (int i = (0); i <= (MAXEACH); ++i)
    for (int j = (0); j <= (MAXEACH); ++j) memfind[i][j].clear();
  findbest(nraw + ncooked, nraw + ncooked, 0, 0);
  return best;
}
map<long long, long long> memcount[MAXEACH + 1][MAXEACH + 1];
long long countmatch(int n1, int n2, long long x1, long long x2) {
  long long diff = abs(x2 - x1);
  if (n1 < nraw || n2 < nraw) {
    if (diff != best) return 0;
    int na = 0, nb = 0;
    for (int i = (0); i < (n1 + n2); ++i)
      if (s[i] == 'A')
        ++na;
      else if (s[i] == 'B')
        ++nb;
    return na <= n1 && nb <= n2 ? C[n1 + n2 - na - nb][n1 - na] : 0;
  } else {
    if (diff > best + C[n1][nraw] * C[n2][nraw]) return 0;
    if (memcount[n1][n2].count(x2 - x1)) return memcount[n1][n2][x2 - x1];
    long long ret = 0;
    int idx = n1 + n2 - 1;
    if (s[idx] != 'B')
      ret += countmatch(n1 - 1, n2, x1 + C[n1 - 1][nraw - 1] * C[n2][nraw], x2);
    if (s[idx] != 'A')
      ret += countmatch(n1, n2 - 1, x1, x2 + C[n1][nraw] * C[n2 - 1][nraw - 1]);
    return memcount[n1][n2][x2 - x1] = ret;
  }
}
long long countmatch() {
  for (int i = (0); i <= (MAXEACH); ++i)
    for (int j = (0); j <= (MAXEACH); ++j) memcount[i][j].clear();
  return countmatch(nraw + ncooked, nraw + ncooked, 0, 0);
}
void run() {
  scanf("%d%d%s", &nraw, &ncooked, s);
  findbest();
  long long ans = countmatch();
  printf("%lld\n", ans);
}
void precalc() {
  for (int i = (0); i <= (2 * MAXEACH); ++i) {
    C[i][0] = C[i][i] = 1;
    for (int j = (1); j < (i); ++j) C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
  }
}
void stress() {
  for (nraw = 1; nraw <= 20; ++nraw)
    for (ncooked = 1; ncooked <= 20; ++ncooked)
      if (nraw + ncooked <= 30) {
        for (int i = (0); i < (nraw + ncooked); ++i) s[i] = '?';
        s[nraw + ncooked] = '\0';
        findbest();
        long long ans = countmatch();
        printf("%d %d = %lld -> %lld\n", nraw, ncooked, best, ans);
      }
}
int main() {
  precalc();
  run();
  return 0;
}

### Prompt

Your challenge is to write a cpp solution to the following problem:

The game of Egg Roulette is played between two players. Initially 2R raw eggs and 2C cooked eggs are placed randomly into a carton. The shells are left on so there is no way to distinguish a raw egg from a cooked egg. One at a time, a player will select an egg, and then smash the egg on his/her forehead. If the egg was cooked, not much happens, but if the egg was raw, it will make quite the mess. This continues until one player has broken R raw eggs, at which point that player is declared the loser and the other player wins.

The order in which players take turns can be described as a string of 'A' and 'B' characters, where the i-th character tells which player should choose the i-th egg. Traditionally, players take turns going one after the other. That is, they follow the ordering "ABABAB...". This isn't very fair though, because the second player will win more often than the first. We'd like you to find a better ordering for the players to take their turns. Let's define the unfairness of an ordering as the absolute difference between the first player's win probability and the second player's win probability. We're interested in orderings that minimize the unfairness. We only consider an ordering valid if it contains the same number of 'A's as 'B's.

You will also be given a string S of length 2(R + C) containing only 'A', 'B', and '?' characters. An ordering is said to match S if it only differs from S in positions where S contains a '?'. Of the valid orderings that minimize unfairness, how many match S?

Input

The first line of input will contain integers R and C (1 ≤ R, C ≤ 20, R + C ≤ 30).

The second line of input will contain the string S of length 2(R + C) consisting only of characters 'A', 'B', '?'.

Output

Print the number of valid orderings that minimize unfairness and match S.

Examples

Input

1 1
??BB


Output

0


Input

2 4
?BA??B??A???


Output

1


Input

4 14
????A??BB?????????????AB????????????


Output

314

Note

In the first test case, the minimum unfairness is 0, and the orderings that achieve it are "ABBA" and "BAAB", neither of which match S. Note that an ordering such as "ABBB" would also have an unfairness of 0, but is invalid because it does not contain the same number of 'A's as 'B's.

In the second example, the only matching ordering is "BBAAABABABBA".

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXEACH = 30;
int nraw, ncooked;
char s[2 * MAXEACH + 1];
long long C[2 * MAXEACH + 1][2 * MAXEACH + 1];
long long best;
set<long long> memfind[MAXEACH + 1][MAXEACH + 1];
void findbest(int n1, int n2, long long x1, long long x2) {
  if (x1 > x2) swap(n1, n2), swap(x1, x2);
  if (n1 < nraw || n2 < nraw) {
    best = min(best, x2 - x1);
    return;
  }
  if (x2 - x1 - C[n1][nraw] * C[n2][nraw] >= best) return;
  if (!memfind[n1][n2].insert(x2 - x1).second) return;
  findbest(n1 - 1, n2, x1 + C[n1 - 1][nraw - 1] * C[n2][nraw], x2);
  if (n1 != n2 || x1 != x2)
    findbest(n1, n2 - 1, x1, x2 + C[n1][nraw] * C[n2 - 1][nraw - 1]);
}
long long findbest() {
  best = LLONG_MAX;
  for (int i = (0); i <= (MAXEACH); ++i)
    for (int j = (0); j <= (MAXEACH); ++j) memfind[i][j].clear();
  findbest(nraw + ncooked, nraw + ncooked, 0, 0);
  return best;
}
map<long long, long long> memcount[MAXEACH + 1][MAXEACH + 1];
long long countmatch(int n1, int n2, long long x1, long long x2) {
  long long diff = abs(x2 - x1);
  if (n1 < nraw || n2 < nraw) {
    if (diff != best) return 0;
    int na = 0, nb = 0;
    for (int i = (0); i < (n1 + n2); ++i)
      if (s[i] == 'A')
        ++na;
      else if (s[i] == 'B')
        ++nb;
    return na <= n1 && nb <= n2 ? C[n1 + n2 - na - nb][n1 - na] : 0;
  } else {
    if (diff > best + C[n1][nraw] * C[n2][nraw]) return 0;
    if (memcount[n1][n2].count(x2 - x1)) return memcount[n1][n2][x2 - x1];
    long long ret = 0;
    int idx = n1 + n2 - 1;
    if (s[idx] != 'B')
      ret += countmatch(n1 - 1, n2, x1 + C[n1 - 1][nraw - 1] * C[n2][nraw], x2);
    if (s[idx] != 'A')
      ret += countmatch(n1, n2 - 1, x1, x2 + C[n1][nraw] * C[n2 - 1][nraw - 1]);
    return memcount[n1][n2][x2 - x1] = ret;
  }
}
long long countmatch() {
  for (int i = (0); i <= (MAXEACH); ++i)
    for (int j = (0); j <= (MAXEACH); ++j) memcount[i][j].clear();
  return countmatch(nraw + ncooked, nraw + ncooked, 0, 0);
}
void run() {
  scanf("%d%d%s", &nraw, &ncooked, s);
  findbest();
  long long ans = countmatch();
  printf("%lld\n", ans);
}
void precalc() {
  for (int i = (0); i <= (2 * MAXEACH); ++i) {
    C[i][0] = C[i][i] = 1;
    for (int j = (1); j < (i); ++j) C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
  }
}
void stress() {
  for (nraw = 1; nraw <= 20; ++nraw)
    for (ncooked = 1; ncooked <= 20; ++ncooked)
      if (nraw + ncooked <= 30) {
        for (int i = (0); i < (nraw + ncooked); ++i) s[i] = '?';
        s[nraw + ncooked] = '\0';
        findbest();
        long long ans = countmatch();
        printf("%d %d = %lld -> %lld\n", nraw, ncooked, best, ans);
      }
}
int main() {
  precalc();
  run();
  return 0;
}

```