#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <cassert>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
// head

ll a,b,c,d,px,py,pz,ret,prx,pry,prz;
vector<PII> v;
void add(int a) {
	if (a>=123456) {
		for (int i=1;i<=d;i++) v.pb(mp(i,a));
		for (int i=a-1-d;i<a;i++) v.pb(mp(i,a));
	} else {
		for (int i=1;i<a;i++) v.pb(mp(i,a));
	}
}
ll seg(ll p,ll q,ll a) {
	return min(p+d+1,a)-min(q+d+1,a);
}
int main() {
	scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
	add(a); add(b); add(c);
	sort(all(v),[&](PII a,PII b){ return (ll)a.fi*b.se<(ll)a.se*b.fi; });
	px=min(a,d+1); py=min(b,d+1); pz=min(c,d+1);
	ret=px*py%mod*pz%mod;
	prx=0, pry=0, prz=0;
	for (auto p:v) {
		ll curx=p.fi*a/p.se,cury=p.fi*b/p.se,curz=p.fi*c/p.se;
		ret=(ret+seg(curx,prx,a)*py%mod*pz+seg(cury,pry,b)*px%mod*pz+seg(curz,prz,c)*px%mod*py)%mod;
		px=min(curx+d,a-1)-max(curx-d,0ll)+1;
		py=min(cury+d,b-1)-max(cury-d,0ll)+1;
		pz=min(curz+d,c-1)-max(curz-d,0ll)+1;
		prx=curx; pry=cury; prz=curz;
	}
	printf("%lld\n",ret);
}
