← Home
package main

import (
	"fmt"
	"sort"
	"strings"
)

var comb [65][65]int64

func initComb() {
	for i := 0; i <= 60; i++ {
		comb[i][0] = 1
		for j := 1; j <= i; j++ {
			comb[i][j] = comb[i-1][j-1] + comb[i-1][j]
		}
	}
}

func nCr(n, k int) int64 {
	if k < 0 || k > n {
		return 0
	}
	return comb[n][k]
}

type State struct {
	val   int64
	count int64
}

func compact(states []State) []State {
	if len(states) <= 1 {
		return states
	}
	sort.Slice(states, func(i, j int) bool {
		return states[i].val < states[j].val
	})
	idx := 0
	for i := 1; i < len(states); i++ {
		if states[i].val == states[idx].val {
			states[idx].count += states[i].count
		} else {
			idx++
			states[idx] = states[i]
		}
	}
	return states[:idx+1]
}

func getDiffAndCount(S string, R, C int, targetDiff int64) (int64, int64) {
	var fwd [32][]State
	fwd[0] = []State{{0, 1}}

	for step := 0; step < R+C; step++ {
		var nextFwd [32][]State
		for a := 0; a <= step; a++ {
			b := step - a
			if a > R+C || b > R+C || len(fwd[a]) == 0 {
				continue
			}

			if S[step] == 'A' || S[step] == '?' {
				if a+1 <= R+C {
					cost := nCr(a, R-1) * nCr(b, R)
					for _, st := range fwd[a] {
						nextFwd[a+1] = append(nextFwd[a+1], State{st.val + cost, st.count})
					}
				}
			}
			if S[step] == 'B' || S[step] == '?' {
				if b+1 <= R+C {
					for _, st := range fwd[a] {
						nextFwd[a] = append(nextFwd[a], State{st.val, st.count})
					}
				}
			}
		}
		for a := 0; a <= step+1; a++ {
			if a <= R+C && (step+1-a) <= R+C {
				nextFwd[a] = compact(nextFwd[a])
			}
		}
		fwd = nextFwd
	}

	var bwd [32][]State
	bwd[R+C] = []State{{0, 1}}

	for step := 2 * (R + C); step > R+C; step-- {
		var nextBwd [32][]State
		for a := 0; a <= R+C; a++ {
			b := step - a
			if b < 0 || b > R+C || len(bwd[a]) == 0 {
				continue
			}

			if S[step-1] == 'A' || S[step-1] == '?' {
				if a-1 >= 0 {
					cost := nCr(a-1, R-1) * nCr(b, R)
					for _, st := range bwd[a] {
						nextBwd[a-1] = append(nextBwd[a-1], State{st.val + cost, st.count})
					}
				}
			}
			if S[step-1] == 'B' || S[step-1] == '?' {
				if b-1 >= 0 {
					for _, st := range bwd[a] {
						nextBwd[a] = append(nextBwd[a], State{st.val, st.count})
					}
				}
			}
		}
		for a := 0; a <= R+C; a++ {
			b := (step - 1) - a
			if b >= 0 && b <= R+C {
				nextBwd[a] = compact(nextBwd[a])
			}
		}
		bwd = nextBwd
	}

	minDiff := int64(-1)
	K := nCr(R+C, R) * nCr(R+C, R)

	for a := 0; a <= R+C; a++ {
		fw := fwd[a]
		bw := bwd[a]
		if len(fw) == 0 || len(bw) == 0 {
			continue
		}
		for i := 0; i < len(fw); i++ {
			target := (K + 1) / 2 - fw[i].val
			idx := sort.Search(len(bw), func(j int) bool {
				return bw[j].val >= target
			})
			if idx < len(bw) {
				d := fw[i].val + bw[idx].val
				d = d*2 - K
				if d < 0 {
					d = -d
				}
				if minDiff == -1 || d < minDiff {
					minDiff = d
				}
			}
			if idx > 0 {
				d := fw[i].val + bw[idx-1].val
				d = d*2 - K
				if d < 0 {
					d = -d
				}
				if minDiff == -1 || d < minDiff {
					minDiff = d
				}
			}
		}
	}

	if targetDiff != -1 {
		minDiff = targetDiff
	}

	totalCount := int64(0)
	if minDiff != -1 {
		for a := 0; a <= R+C; a++ {
			fw := fwd[a]
			bw := bwd[a]
			if len(fw) == 0 || len(bw) == 0 {
				continue
			}
			for i := 0; i < len(fw); i++ {
				var targets []int64
				if (K+minDiff)%2 == 0 {
					targets = append(targets, (K+minDiff)/2-fw[i].val)
				}
				if minDiff != 0 && (K-minDiff)%2 == 0 {
					targets = append(targets, (K-minDiff)/2-fw[i].val)
				}

				for _, t := range targets {
					idx := sort.Search(len(bw), func(j int) bool {
						return bw[j].val >= t
					})
					if idx < len(bw) && bw[idx].val == t {
						totalCount += fw[i].count * bw[idx].count
					}
				}
			}
		}
	}

	return minDiff, totalCount
}

func main() {
	var R, C int
	if _, err := fmt.Scan(&R, &C); err != nil {
		return
	}
	var S string
	if _, err := fmt.Scan(&S); err != nil {
		return
	}

	initComb()

	qMarks := strings.Repeat("?", 2*(R+C))
	globalMinDiff, _ := getDiffAndCount(qMarks, R, C, -1)
	_, ans := getDiffAndCount(S, R, C, globalMinDiff)

	fmt.Println(ans)
}