#include <cstdio>
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <map>
#include <set>

#define MIN_INT -2147483648
#define MAX_INT 2147483647
#define MIN_LONG -9223372036854775808L
#define MAX_LONG 9223372036854775807L
#define PI 3.141592653589793238462643383279502884L

#define MOD 1000000007L

#define long long long int

using std::vector;
using std::map;
using std::string;
using std::pair;
using std::cin;
using std::cout;
using std::cerr;

long max(long a, long b) {
    return a > b ? a : b;
}

long min(long a, long b) {
    return a < b ? a : b;
}

// @author: pashka
int main() {
    std::ios::sync_with_stdio(false);

    long b[3], d;
    cin >> b[0] >> b[1] >> b[2] >> d;

    long x[4] = {0, 0, 0};
    long l[4] = {0, 0, 0};
    long r[4] = {0, 0, 0};

    bool g[3];

    for (int i = 0; i < 3; i++) {
        g[i] = (b[i] - 1 > d);
    }

    int ng = 0;
    for (int i = 0; i < 3; i++) {
        if (g[i]) ng++;
    }

    long res = 1;
    for (int i = 0; i < 3; i++) if (g[i]) {
        r[i] = min(b[i], d + 1);
        res *= r[i];
        res %= MOD;
    }

    if (ng > 0)
        while (true) {
//            cout << x[0] << " " << x[1] << " " << x[2] << " " << res << "\n";
            bool ok = true;
            for (int i = 0; i < 3; i++) {
                if (x[i] < b[i] - 1) {
                    ok = false;
                }
            }
            if (ok) break;

            ok = true;
            for (int i = 0; i < 3; i++) {
                if (g[i] && (l[i] != x[i] - d || r[i] != x[i] + d + 1)) {
                    ok = false;
                }
            }
            if (ok) {

//                cout << x[0] << " " << x[1] << " " << x[2] << "\n";

                long dd = 2 * d + 1;

                long d2 = 1;
                for (int i = 0; i < ng - 1; i++) {
                    d2 = (d2 * dd) % MOD;
                }
                long sx = 0;
                for (int i = 0; i < 3; i++) {
                    if (g[i]) sx += x[i];
                }

                long ss = (d2 * (dd + sx)) % MOD;
                long e = (ss - res) % MOD;

//                cout << d2 << " " << sx << " " << ss << " " << e << "\n";

                if (e < 0) e += MOD;

                sx = 0;
                for (int i = 0; i < 3; i++) {
                    if (g[i]) sx += b[i] - 1;
                    sx %= MOD;
                }
                ss = (d2 * (dd + sx)) % MOD;

                res = ss - 2 * e;
                while (res < 0) {
                    res += MOD;
                }

//                cout << ss << " " << res << "\n";
                break;
            }

            bool c[3] = {true, true, true};
            for (int i = 0; i < 3; i++) {
                for (int j = i + 1; j < 3; j++) {
                    if ((x[i] + 1) * b[j] > (x[j] + 1) * b[i]) {
                        c[i] = false;
                    } else {
                        c[j] = false;
                    }
                }
            }

//        cout << c[0] << " " << c[1] << " " << c[2] << "\n";

            ok = false;
            for (int i = 0; i < 3; i++) {
                if (c[i]) {

                    long L = 0;
                    long R = b[i] - x[i];

                    while (R > L + 1) {
                        long M = (L + R) / 2;
                        bool c[3] = {true, true, true};
                        x[i] = x[i] + M;
                        for (int i = 0; i < 3; i++) {
                            for (int j = i + 1; j < 3; j++) {
                                if ((x[i] + 1) * b[j] > (x[j] + 1) * b[i]) {
                                    c[i] = false;
                                } else {
                                    c[j] = false;
                                }
                            }
                        }
                        x[i] = x[i] - M;
                        if (c[i]) {
                            L = M;
                        } else {
                            R = M;
                        }
                    }

                    ok = true;
                    if (g[i]) {
                        long s = 1;
                        for (int j = 0; j < 3; j++)
                            if (g[j] && i != j) {
                                s *= (r[j] - l[j]);
                            }
                        long q = min(R, b[i] - 1 - d - x[i]) % MOD;
                        if (q > 0)
                            res += (s * q) % MOD;
                        while (res >= MOD) {
                            res -= MOD;
                        }
                    }
                    x[i] += R;
                    l[i] = max(x[i] - d, 0);
                    r[i] = min(x[i] + d + 1, b[i]);
                }
            }
            if (!ok) {
                return 1;
            }
        }
    else res = 1;

    for (int i = 0; i < 3; i++) {
        if (!g[i]) {
            res *= b[i];
            res %= MOD;
        }
    }

    cout << res << "\n";

    return 0;
}

Measured memory_bytes: 384