#include<iostream>
#include<stdlib.h>
#include<vector>
#include<algorithm>
#include<stdio.h>
#include<string>
#include<map>
#include<math.h>
#include<iomanip>
#include<set>

#define rep(i,n) for(ll i = 0; i < (ll)n; i++)
#define swap(a,b) a^=b;b^=a;a^=b;
//#define for(i,a,b) for (ll i=(a);i<(ll)b; i++)
#define print(x) std::cout << x << std::endl;

using namespace std;

typedef long long ll;

template<class T, class U> std::string replace(std::string s, const T& target, const U& replacement, bool replace_first = 0, bool replace_empty = 0);
bool isContain(int value, int under, int top);
vector<int> range(int x);

/*
int get_ab(string str) {
	bool isA = false;
	int res = 0;
	if (str[0] == 'A') isA = true;
	for (int i = 1; i < str.length(); i++) {
		if (isA && str[i] == 'B') { res++; isA = false; }
		else if (str[i] == 'A') isA = true;
	}
	return res;
}
*/

int main(void) {
	//Program Start	

	int R, G, B, N;
	cin >> R >> G >> B >> N;

	int ans = 0;

	for (int r = 0; r*R <= N; r++) {
		for (int g = 0; r*R + g * G <= N; g++) {
			if ((N - (r * R + g * G)) % B == 0) ans++;
		}
	}

	cout << ans << endl;

	/*
	int N; cin >> N;
	vector<string> s(N);

	rep(i, N) cin >> s[i];

	int ans = 0;
	rep(i, N) ans += get_ab(s[i]);

	int numA = 0, numB = 0;

	bool a, b;
	bool ismin = false;

	rep(i, N) {
		a = s[i][s[i].length() - 1] == 'A';
		b = s[i][0] == 'B';
		if (a && b) ismin = true;
		if (a) numA++;
		if (b) numB++;
	}
	
	ans += (std::min(numA, numB) - (ismin ? 1 : 0));
	cout << ans << endl;
	*/



ProgramEndPointLabel:;


	//Program End
	system("pause");

	return 0;
}


vector<int> range(int y) {
	vector<int> result(y);
	for (int i = 0; i < y; i++)
		result[i] = i;
	return result;
}

bool isContain(int value, int under, int top) {
	if (under <= value && value <= top) return true;
	return false;
}

template<class T, class U> std::string replace(std::string s, const T& target, const U& replacement, bool replace_first, bool replace_empty) {
	using S = std::string;
	using C = std::string::value_type;
	using N = std::string::size_type;
	struct {
		auto len(const S& s) { return s.size(); }
		auto len(const C* p) { return std::char_traits<C>::length(p); }
		auto len(const C  c) { return 1; }
		auto sub(S* s, const S& t, N pos, N len) { s->replace(pos, len, t); }
		auto sub(S* s, const C* t, N pos, N len) { s->replace(pos, len, t); }
		auto sub(S* s, const C  t, N pos, N len) { s->replace(pos, len, 1, t); }
		auto ins(S* s, const S& t, N pos) { s->insert(pos, t); }
		auto ins(S* s, const C* t, N pos) { s->insert(pos, t); }
		auto ins(S* s, const C  t, N pos) { s->insert(pos, 1, t); }
	} util;

	N target_length = util.len(target);
	N replacement_length = util.len(replacement);
	if (target_length == 0) {
		if (!replace_empty || replacement_length == 0) return s;
		N n = s.size() + replacement_length * (1 + s.size());
		s.reserve(!replace_first ? n : s.size() + replacement_length);
		for (N i = 0; i < n; i += 1 + replacement_length) {
			util.ins(&s, replacement, i);
			if (replace_first) break;
		}
		return s;
	}

	N pos = 0;
	while ((pos = s.find(target, pos)) != std::string::npos) {
		util.sub(&s, replacement, pos, target_length);
		if (replace_first) return s;
		pos += replacement_length;
	}
	return s;
}


Measured memory_bytes: 504