package main import ( "bufio" "fmt" "os" "sort" "strconv" ) func Assert(ok bool) { if !ok { panic("assertion failed") } } var sc = func() *bufio.Scanner { sc := bufio.NewScanner(os.Stdin) sc.Split(bufio.ScanWords) return sc }() func Str() string { sc.Scan() return sc.Text() } func Int() int { x, _ := strconv.Atoi(Str()) return x } func Float() float64 { x, _ := strconv.ParseFloat(Str(), 64) return x } var wr = bufio.NewWriter(os.Stdout) func Out(a ...interface{}) { fmt.Fprintln(wr, a...) } func Format(a []int) string { s := fmt.Sprint(a) return s[1 : len(s)-1] } func Chmin(a *int, b int) bool { if b < *a { *a = b return true } return false } func Chmax(a *int, b int) bool { if b > *a { *a = b return true } return false } func Max(a ...int) int { mx := a[0] for _, x := range a { if x > mx { mx = x } } return mx } func Min(a ...int) int { mn := a[0] for _, x := range a { if x < mn { mn = x } } return mn } func Sum(a ...int) int { s := 0 for _, x := range a { s += x } return s } // truncated func Divmod(a, b int) (int, int) { q := a / b r := a - q*b return q, r } func Lb(a []int, x int) int { n := len(a) f := func(i int) bool { return a[i] >= x } return sort.Search(n, f) } func Ub(a []int, x int) int { n := len(a) f := func(i int) bool { return a[i] > x } return sort.Search(n, f) } func main() { defer wr.Flush() t := 1 // t := Int() for ; t > 0; t-- { Solve() } } func Iota(n int) []int { a := make([]int, n) for i := 0; i < n; i++ { a[i] = i } return a } func Egcd(a, b int) (int, int, int) { if b == 0 { if a < 0 { return -a, -1, 0 } else { return a, 1, 0 } } q, r := Divmod(a, b) g, s, t := Egcd(b, r) return g, t, s - q*t } func Inv(m, a int) int { Assert(0 < a && a < m) g, x, _ := Egcd(a, m) Assert(g == 1) if x < 0 { x += m } return x } const Mod = 998_244_353 func Tables(n int) (f, fi, inv []int) { f = make([]int, n) fi = make([]int, n) inv = make([]int, n) f[0] = 1 fi[0] = 1 for i := 1; i < n; i++ { f[i] = f[i-1] * i % Mod } fi[n-1] = Inv(Mod, f[n-1]) for i := n - 1; i > 0; i-- { fi[i-1] = fi[i] * i % Mod inv[i] = fi[i] * f[i-1] % Mod } return } var Fact, IFact, Invs []int func InitTables(n int) { Fact, IFact, Invs = Tables(n) } func Perm(n, k int) int { if k < 0 || n < k { return 0 } return Fact[n] * IFact[n-k] % Mod } func Choose(n, k int) int { if k < 0 { return 0 } return Perm(n, k) * IFact[k] % Mod } func Solve() { x, y := Int(), Int() z, w := Int(), Int() Chmax(&z, 1) Chmax(&w, 1) InitTables(1 << 20) ans := Fact[x+y-z-w] ans *= Choose(x, z) ans %= Mod ans *= Choose(y, w) ans %= Mod Out(ans) }