func_code_string: #include <bits/stdc++.h>   using namespace std;   vector<pair<int, int> > anom;   long long int fact[200005];   long long int invfact[200005];   long long int MOD = 1000000007;   long long int dp[2005][25];   long long int invmod(long long int i) {     long long int ans = 1;     long long int mult = i;     long long int exp = MOD - 2;     while (exp > 0) {       if (exp % 2 == 1) {         ans = (ans * mult) % MOD;       }       mult = (mult * mult) % MOD;       exp /= 2;     }     return ans;   }   void precomp() {     fact[0] = 1;     invfact[0] = 1;     for (long long int i = 1; i < 200005; i++) {       fact[i] = (fact[i - 1] * i) % MOD;       invfact[i] = (invfact[i - 1] * invmod(i)) % MOD;     }   }   long long int comb(int a, int b) {     long long int ans = (fact[a] * invfact[b]) % MOD;     ans = (ans * invfact[a - b]) % MOD;     return ans;   }   long long int paths(int a, int b, int c, int d) {     if (a <= c && b <= d) {       return comb(c - a + d - b, c - a);     }     return 0;   }   int main() {     precomp();     int n, m, k, s;     cin >> n >> m >> k >> s;     if (k == 0) {       cout << s << endl;       return 0;     }     int limred = ceil(log2(s)) + 1;     int a, b;     for (int i = 0; i < k; i++) {       cin >> a >> b;       anom.push_back({a, b});     }     sort(anom.begin(), anom.end());     bool beginanom = true;     if (k > 0 && anom[k] != make_pair(1, 1)) {       anom.push_back({1, 1});       beginanom = false;       k++;     }     sort(anom.begin(), anom.end());     for (int i = k - 1; i >= 0; i--) {       dp[i][0] = paths(anom[i].first, anom[i].second, n, m);       for (int j = i + 1; j < k; j++) {         dp[i][0] = (dp[i][0] -                     (dp[j][0] * paths(anom[i].first, anom[i].second,                                       anom[j].first, anom[j].second)) %                         MOD +                     MOD) %                    MOD;       }     }     for (int i = 1; i <= limred; i++) {       for (int j = k - 1; j >= 0; j--) {         dp[j][i] = paths(anom[j].first, anom[j].second, n, m);         for (int p = j + 1; p < k; p++) {           dp[j][i] = (dp[j][i] -                       (dp[p][i] * paths(anom[j].first, anom[j].second,                                         anom[p].first, anom[p].second)) %                           MOD +                       MOD) %                      MOD;         }         for (int p = 0; p < i; p++) {           dp[j][i] = (dp[j][i] - dp[j][p] + MOD) % MOD;         }       }     }     int prevs;     long long int expsum = 0;     long long int numways = 0;     for (int i = 0; i <= limred; i++) {       prevs = s;       s = ceil(s / 2.0);       if (beginanom) {         expsum = (expsum + (s * dp[0][i]) % MOD) % MOD;       } else {         expsum = (expsum + (prevs * dp[0][i]) % MOD) % MOD;       }       numways = (numways + dp[0][i]) % MOD;     }     long long int leftways = paths(1, 1, n, m);     leftways = (leftways - numways + MOD) % MOD;     expsum = (expsum + leftways) % MOD;     long long int ans = (expsum * invmod(comb(n + m - 2, n - 1))) % MOD;     cout << ans << endl;   }   