Problem:
Score : 400 points

Problem Statement

We have a large square grid with H rows and W columns.
Iroha is now standing in the top-left cell.
She will repeat going right or down to the adjacent cell, until she reaches the bottom-right cell.

However, she cannot enter the cells in the intersection of the bottom A rows and the leftmost B columns. (That is, there are A×B forbidden cells.) There is no restriction on entering the other cells.

Find the number of ways she can travel to the bottom-right cell.

Since this number can be extremely large, print the number modulo 10^9+7.

Constraints

1 ≦ H, W ≦ 100,000

1 ≦ A < H

1 ≦ B < W

Input

The input is given from Standard Input in the following format:

H W A B

Output

Print the number of ways she can travel to the bottom-right cell, modulo 10^9+7.

Sample Input 1

2 3 1 1

Sample Output 1

2

We have a 2×3 grid, but entering the bottom-left cell is forbidden. The number of ways to travel is two: "Right, Right, Down" and "Right, Down, Right".

Sample Input 2

10 7 3 4

Sample Output 2

3570

There are 12 forbidden cells.

Sample Input 3

100000 100000 99999 99999

Sample Output 3

1

Sample Input 4

100000 100000 44444 55555

Sample Output 4

738162020

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;

// Snippet: FastPower
abstract class FastPower<T> {
    protected abstract T One();
    protected abstract T Times(T t1, T t2);

    public T Get(T n, long exp) {
        var answer = One();
        for (; exp != 0; exp >>= 1) {
            if ((exp & 1) != 0) answer = Times(answer, n);
            n = Times(n, n);
        }
        return answer;
    }
}

// Snippet: FastPowerModulo
class FastPowerModulo: FastPower<long> {
    public long M;
    protected override long One() => 1L;
    protected override long Times(long t1, long t2) => t1 * t2 % M;
}

// Snippet: ChooseModuloBigPrime
class ChooseModuloBigPrime {
    public static long Get(long n, long k, long modulo) {
        var fastPower = new FastPowerModulo{M = modulo};
        long answer1 = 1L, answer2 = 1L;
        for (long i = 1; i <= k; ++i) {
            answer1 = answer1 * (n + 1 - i) % modulo;
            answer2 = answer2 * i % modulo;
        }
        return answer1 * fastPower.Get(answer2, modulo - 2) % modulo;
    }

    public static long[] GetMultiple(long n1, long n2, long k, long modulo) {
        if (n2 < n1) {
            var answer2 = GetMultiple(n2, n1, k, modulo);
            Array.Reverse(answer2);
            return answer2;
        }
        var fastPower = new FastPowerModulo{M = modulo};
        var answer = new long[n2 - n1 + 1];
        answer[0] = Get(n1, k, modulo);
        for (int i = 1; i < answer.Length; ++i) {
            var answer1 = answer[i - 1] * (n1 + i) % modulo;
            var answer2 = answer1 * fastPower.Get(n1 + i - k, modulo - 2);
            answer[i] = answer2 % modulo;
        }
        return answer;
    }
}

class D {
    const long M = 1000000007;

    public static void Main() {
        var line = Console.ReadLine().Split();
        var h = long.Parse(line[0]);
        var w = long.Parse(line[1]);
        var a = long.Parse(line[2]);
        var b = long.Parse(line[3]);
        var c1 = ChooseModuloBigPrime.GetMultiple(
            h - a - 2 + w, h - a - 1 + b, h - a - 1, M);
        var c2 = ChooseModuloBigPrime.GetMultiple(
            a - 1, a - 2 + w - b, a - 1, M);
        var answer = 0L;
        for (int i = 0; i < c1.Length; ++i)
            answer = (answer + c1[i] * c2[i] % M) % M;
        Console.WriteLine(answer);
    }
}