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;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AtCoder
{
    class Modulo
    {
        public readonly int M = 1000000007;
        private readonly int[] m_facs;
        public Modulo(int n)
        {
            m_facs = new int[n + 1];
            m_facs[0] = 1;
            for (int i = 1; i <= n; ++i)
            {
                m_facs[i] = (int)(Math.BigMul(m_facs[i - 1], i) % M);
            }
        }
        public int Fac(int n)
        {
            return m_facs[n];
        }
        public int Pow(int a, int m)
        {
            switch (m)
            {
            case 0:
                return 1;
            case 1:
                return a;
            default:
                int p1 = Pow(a, m / 2);
                long p2 = Math.BigMul(p1, p1) % M;
                return (int)(((m & 1) == 0) ? p2 : p2 * a % M);
            }
        }
        public long Ncr(int n, int r)
        {
            if (n < r) { return 0; }
            if (n == r) { return 1; }
            long res = Fac(n);
            res *= Pow(Fac(r), M - 2);
            res %= M;
            res *= Pow(Fac(n - r), M - 2);
            res %= M;
            return res;
        }
    }

    class Program
    {
        private const int MODULO = 1000000007;
        private static string Read() { return Console.ReadLine(); }
        private static int ReadInt() { return int.Parse(Read()); }
        private static long ReadLong() { return long.Parse(Read()); }
        private static double ReadDouble() { return double.Parse(Read()); }
        private static int[] ReadInts() { return Array.ConvertAll(Read().Split(), int.Parse); }
        private static long[] ReadLongs() { return Array.ConvertAll(Read().Split(), long.Parse); }
        private static double[] ReadDoubles() { return Array.ConvertAll(Read().Split(), double.Parse); }

        static long Solve(int H, int W, int A, int B)
        {
            var modulo = new Modulo(H + W);
            Func<int, int, long> Path = (x, y) => modulo.Ncr(x + y, x);
            long sum = 0;
            for (int x = B; x < W; ++x)
            {
                sum += Path(x, H - A - 1) * Path(W - x - 1, A - 1);
                sum %= MODULO;
            }
            return sum;
        }
        static void Main(string[] args)
        {
            int[] v = ReadInts();
            Console.WriteLine(Solve(v[0], v[1], v[2], v[3]));
        }
    }
}