#include <bits/stdc++.h> using namespace std; #define FOR(i,a,b) for (int i = (a); i < (b); i++) #define REP(i,n) for(int i = 0; i < (n); i++) #define SZ(x) ((int)((x).size())) #define ALL(c) (c).begin(),(c).end() #define PB push_back #define MP make_pair #define FILL(a,v) memset(a,v,sizeof(a)) #define FF first #define SS second #define DEBUG(a) cerr <<#a<<" : " << a<<endl; typedef long long LL; typedef long double LD; typedef vector<int> VI; typedef vector<string> VS; typedef pair<int,int> PII; // Main code starts Now. LL mod = 2004; map <pair <LL, LL> , LL> mp; /* // This is another cool method. LL ncr (LL n, LL k) { if (mp.find (MP (n, k)) != mp.end()) return mp[MP (n, k)]; if (n < 0 || k < 0) return 0; if (k > n) return 0; if (n == 0) { if (k == 0) return 1; else return 0; } if (n & 1) { LL ans = (ncr (n - 1, k) + ncr (n - 1, k - 1)); if (ans >= mod) ans -= mod; mp[MP(n, k)] = ans; return ans; } else { LL ans = 0; REP (j, k + 1) { LL temp = (ncr (n / 2, j) * ncr (n / 2, k - j)); temp %= mod; ans += temp; if (ans >= mod) ans -= mod; } mp[MP (n, k)] = ans; return ans; } } */ LL A[15]; vector <pair<int, int> > fact[15]; LL ncr (LL p, LL q) { if (q > p) return 0; if (q == 0) return 1; REP (i, q) { A[i] = p - i; } REP (i, SZ(fact[q])) { int tot = fact[q][i].second; REP (j, q) { while (tot && A[j] % fact[q][i].first == 0) { tot --; A[j] /= fact[q][i].first; } } assert (tot == 0); } LL ans = 1; REP (i, q) { ans *= A[i]; ans %= mod; } return ans; } int isPrime (int n) { for (int i = 2; i * i <= n; i++) if (n % i == 0) return false; return true; } int getAns (int n, int k) { int ans = 0; while (n) { ans += (n / k); n /= k; } return ans; } int main () { vector <int> prime; REP (i, 11) { FOR (j, 2, 11) { if (isPrime (j)) { int tot = getAns (i, j); // cout << i << " " << j << " " << tot << endl; if (tot > 0) fact[i].PB (make_pair (j, tot)); } } } for (int i = 0; i <= 10; i++) { for (int j = 0; j < fact[i].size(); j++) { cout << fact[i][j].first << " " << fact[i][j].second << " , "; } cout << endl; } LL N, M; while (scanf ("%lld %lld", &N, &M) != EOF) { cout << ncr (N, M) << endl; } return 0; }