#include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<ll> vll;
typedef pair<int,int> pint;

#define DE 1
#define FI first
#define SE second
#define PB push_back
#define MP make_pair
#define ALL(s) (s).begin(),(s).end()
#define REP(i,n) for (int i = 0; i < (int)(n); ++i)
#define EACH(i,s) for (typeof((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<<endl

template<class T1, class T2> ostream& operator<<(ostream &s, pair<T1,T2> P){return s<<'<'<<P.first<<", "<<P.second<<'>';}
template<class T> ostream& operator<<(ostream &s, vector<T> P) {s<<"{ ";for(int i=0;i<P.size();++i){if(i>0)s<<", ";s<<P[i];}return s<<" }"<<endl;}
template<class T1, class T2> ostream& operator<<(ostream &s, map<T1,T2> P) {s<<"{ ";for(typeof(P.begin()) it=P.begin();it!=P.end();++it){if(it!=P.begin())s<<", ";s<<'<'<<it->first<<"->"<<it->second<<'>';}return s<<" }"<<endl;}





// 130705（AOJ 1131）
// 分数クラス
int gcd(int a, int b) {
    if (b == 0) return a;
    if (a < 0) a = -a; if (b < 0) b = -b;
    return gcd(b, a % b);
}
struct frac {
    int first, second;

    frac normalize() {
        if (second < 0) {first = -first; second = -second;}
        int d = gcd(first, second);
        if (d == 0) {first = 0; second = 1;}
        else {first /= d; second /= d;}
        return *this;
    }
    frac(int f = 1, int s = 1) : first(f), second(s) {normalize();}
    
    inline const frac& operator = (int a);
    inline const frac& operator += (const frac& a);
    inline const frac& operator += (int a);
    inline const frac& operator -= (const frac& a);
    inline const frac& operator -= (int a);
    inline const frac& operator *= (const frac& a);
    inline const frac& operator *= (int a);
    inline const frac& operator /= (const frac& a);
    inline const frac& operator /= (int a);
    friend ostream& operator << (ostream& s, const frac& f) {s << f.first << "/" << f.second; return s;}
};

frac tofrac(int a) {
    return frac(a, 1);
}
inline const frac& frac::operator = (int a) {
    *this = tofrac(a);
    return *this;
}
bool operator < (const frac& a, const frac& b) {
    return (long long)a.first * b.second < (long long)a.second * b.first;
}
bool operator > (const frac& a, const frac& b) {
    return b < a;
}
bool operator <= (const frac& a, const frac& b) {
    return !(b < a);
}
bool operator >= (const frac& a, const frac& b) {
    return !(a < b);
}
bool operator != (const frac& a, const frac& b) {
    return a < b || b < a;
}
bool operator == (const frac& a, const frac& b) {
    return !(a < b) && !(b < a);
}
frac operator + (const frac& a, const frac& b) {
    frac res;
    res.first = a.first * b.second + a.second * b.first;
    res.second = a.second * b.second;
    //res.normalize();
    return res;
}
frac operator + (const frac& a, int b) {
    return a + tofrac(b);
}
frac operator - (const frac& a, const frac& b) {
    frac res;
    res.first = a.first * b.second - a.second * b.first;
    res.second = a.second * b.second;
    //res.normalize();
    return res;
}
frac operator - (const frac& a, int b) {
    return a - tofrac(b);
}
frac operator * (const frac& a, const frac& b) {
    frac res;
    res.first = a.first * b.first;
    res.second = a.second * b.second;
    //res.normalize();
    return res;
}
frac operator * (const frac& a, int b) {
    return a * tofrac(b);
}
frac operator / (const frac& a, const frac& b) {
    frac res;
    res.first = a.first * b.second;
    res.second = a.second * b.first;
    //res.normalize();
    return res;
}
frac operator / (const frac& a, int b) {
    return a / tofrac(b);
}
inline const frac& frac::operator += (const frac& x) {*this = *this + x; return *this;}
inline const frac& frac::operator += (int x) {*this = *this + x; return *this;}
inline const frac& frac::operator -= (const frac& x) {*this = *this - x; return *this;}
inline const frac& frac::operator -= (int x) {*this = *this + x; return *this;}
inline const frac& frac::operator *= (const frac& x) {*this = *this * x; return *this;}
inline const frac& frac::operator *= (int x) {*this = *this * x; return *this;}
inline const frac& frac::operator /= (const frac& x) {*this = *this / x; return *this;}
inline const frac& frac::operator /= (int x) {*this = *this / x; return *this;}



// 分数fを、con個以下の個数で、分母はnum以上で、分母積はmul以下となるように作る方法の数

int p, q, a, n;
int rec(frac f, int con, int num, int mul) {
    if (con == 1) {
        if (f.FI == 0) return 1;
        int t = f.SE/f.FI;
        if (f.SE % f.FI == 0 &&t >= num && t <= mul) return 1;
    }
    
    if (f.FI == 0) return 1;
    //if (f > frac(1,num)*con) return 0;
    
    int res = 0;
    int start = max((f.SE-1)/f.FI+1, num);
    frac temp = con/f;
    int goal = min(temp.FI/temp.SE, mul);
    for (int i = start; i <= goal; ++i) {
        int rem = mul/i;
        frac rf = f - frac(1,i);
        
        res += rec(rf, con-1, i, rem);
    }
    
    return res;
}


int main() {
    //freopen( "/Users/macuser/Documents/Programming/Contest/input.in", "r", stdin );

    while (cin >> p >> q >> a >> n) {
        if (p == 0 && q == 0) break;
        
        frac start(p, q);
        int res = rec(start, n, 1, a);
        
        cout << res << endl;
    }
    
    
    return 0;
}


Measured memory_bytes: 1160