using static System.Math;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System;
using System.Runtime.CompilerServices;

class Program
{
    #region Reader
    static string ReadStr => Console.ReadLine();
    static string[] ReadStrs => Console.ReadLine().Split(' ');
    static int ReadInt => Convert.ToInt32(Console.ReadLine().Trim());
    static int[] ReadInts => Console.ReadLine().Trim().Split(' ').Select(s => Convert.ToInt32(s)).ToArray();
    static long ReadLong => Convert.ToInt64(Console.ReadLine().Trim());
    static long[] ReadLongs => Console.ReadLine().Trim().Split(' ').Select(s => Convert.ToInt64(s)).ToArray();
    static List<int[]> ReadPairs(int N)
    {
        List<int[]> ans = new List<int[]>();
        for (int i = 0; i < N; i++) { ans.Add(ReadInts); }
        return ans;
    }
    static List<long[]> ReadPairsLong(int N)
    {
        List<long[]> ans = new List<long[]>();
        for (int i = 0; i < N; i++) { ans.Add(ReadLongs); }
        return ans;
    }
    #endregion
    #region Method
    const int mod = 1000000007;
    public static int Mod(int a, int mod) { return a % mod >= 0 ? a % mod : a % mod + mod; }
    public static long Mod(long a, long mod = mod) { return a % mod >= 0 ? a % mod : a % mod + mod; }
    bool eq<T, U>() => typeof(T).Equals(typeof(U));
    T ct<T, U>(U a) => (T)Convert.ChangeType(a, typeof(T));
    T cv<T>(string s) => eq<T, int>() ? ct<T, int>(int.Parse(s))
                       : eq<T, long>() ? ct<T, long>(long.Parse(s))
                       : eq<T, double>() ? ct<T, double>(double.Parse(s))
                       : eq<T, char>() ? ct<T, char>(s[0])
                                         : ct<T, string>(s);
    void Multi<T>(out T a) => a = cv<T>(ReadStr);
    void Multi<T, U>(out (T,U) ans)
    {
        var ar = ReadStrs;
        ans =(cv<T>(ar[0]), cv<U>(ar[1]));
    }
    void Multi<T, U, V>(out (T,U,V) ans)
    {
        var ar = ReadStrs; 
        ans =(cv<T>(ar[0]), cv<U>(ar[1]),cv<V>(ar[2]));
    }
    void Multi<T,U>(out T a,out U b)
    {
        var ar = ReadStrs; 
        a = cv<T>(ar[0]);  b = cv<U>(ar[1]);
    }
    void Multi<T, U, V>(out T a,out U b,out V c)
    {
        var ar = ReadStrs;
        a = cv<T>(ar[0]);  b = cv<U>(ar[1]);  c = cv<V>(ar[2]);
    }
    #endregion


    #region Mod
    //public static long GetInv(long a, long mod = 1000000007)
    //{
    //    return PowerMod(a, mod - 2);
    //}
    //public static long Combination(long a, long b, long mod = 1000000007)
    //{
    //    if (b < 0 || b > a) return 0;
    //    if (b > a / 2) b = a - b;
    //    long numerator = Factorial(a, mod);
    //    long denominator = (Factorial(b, mod) * Factorial(a - b, mod)) % mod;

    //    return (numerator * GetInv(denominator, mod)) % mod;
    //}

    static ModInt Combination(long a, long b)
    {
        if (b < 0 || b > a) return 0;
        if (b > a / 2) b = a - b;
        ModInt numerator = Factorial(a);
        ModInt denominator = Factorial(b) * Factorial(a - b);

        return numerator /denominator;
    }

    //public static long Factorial(long n, long mod = 1000000007)
    //{
    //    if (n == 0) return 1;
    //    if (n == 1) return 1;
    //    long ans = n;
    //    for (int i = 2; i < n; i++)
    //    {
    //        ans = (ans * i) % mod;
    //    }

    //    return ans;
    //}
    static ModInt Factorial(long n)
    {
        if (n == 0) return 1;
        if (n == 1) return 1;
        ModInt ans = n;
        for (ModInt i = 2; i < n; i++)
        {
            ans = ans * i;
        }

        return ans;
    }


    private static ModInt PowerMod(long a, long n)
    {
        if (n == 0) return 1;
        if (n == 1) return a;

        ModInt p = PowerMod(a, n / 2);
        if (n % 2 == 1) return p*p*a ;
        else return p*p;
    }

    //static long[] nCi(long N)
    //{
    //    var ans = new long[N + 1];
    //    ans[0] = 1;

    //    for (int i = 1; i <= N; i++)
    //    {
    //        ans[i] = Mod(ans[i - 1] * (N - i + 1));
    //        ans[i] *= GetInv(i);
    //        ans[i] = Mod(ans[i]);
    //    }
    //    return ans;
    //}

    static ModInt[] nCi(long N)
    {
        var ans = new ModInt[N + 1];
        ans[0] = 1;

        for (int i = 1; i <= N; i++)
        {
            ans[i] = ans[i - 1] * (N - i + 1)/i;
        }
        return ans;
    }


    struct ModInt
    {
        const int MOD = 1000000007;
        long Data;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public ModInt(long data) { if ((Data = data % MOD) < 0) Data += MOD; }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static implicit operator long(ModInt modInt) => modInt.Data;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static implicit operator ModInt(long val) => new ModInt(val);
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static ModInt operator +(ModInt a, ModInt b)
        {
            long res = a.Data + b.Data;
            return new ModInt() { Data = res >= MOD ? res - MOD : res };
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static ModInt operator +(ModInt a, long b) => a.Data + b;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static ModInt operator -(ModInt a, ModInt b)
        {
            long res = a.Data - b.Data;
            return new ModInt() { Data = res < 0 ? res + MOD : res };
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static ModInt operator -(ModInt a, long b) => a.Data - b;
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static ModInt operator *(ModInt a, ModInt b) => new ModInt() { Data = a.Data * b.Data % MOD };
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static ModInt operator /(ModInt a, ModInt b) => a.Data * GetInverse(b);

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public override string ToString() => Data.ToString();

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        static long GetInverse(long a)
        {
            long div;
            long p = MOD;
            long x1 = 1, y1 = 0, x2 = 0, y2 = 1;
            while (true)
            {
                if (p == 1) return x2;
                div = a / p;
                x1 -= x2 * div;
                y1 -= y2 * div;
                a %= p;
                if (a == 1) return x1;
                div = p / a;
                x2 -= x1 * div;
                y2 -= y1 * div;
                p %= a;
            }
        }
    }

    #endregion


    
    static void Main()
    {
        int[] HWAB = ReadInts;
        int H = HWAB[0];
        int W = HWAB[1];
        int A = HWAB[2];
        int B = HWAB[3];

        List<(int h, int w)> checkPoints = new List<(int h, int w)>();

        for (int i = 0; i < H-A; i++)
        {
            if (B + i >= W) break;
            checkPoints.Add( (A + i, B + i));
        }

        ModInt ans = 0;

        var comb1 = nCi(H - checkPoints[0].h - 1 + checkPoints[0].w);
        var comb2 = nCi(checkPoints[0].h + W - checkPoints[0].w - 1);


        foreach (var item in checkPoints)
        {
            ans += comb1[item.w]*comb2[item.h];
        }

        WriteLine(ans);
    }



}



Measured memory_bytes: 31568