module main; // http://rsujskf.s602.xrea.com/?yukicoder_129 より // 組み合わせ、素因数分解、剰余 import std; immutable MOD = 10L ^^ 9; // エラトステネスの篩によってm以上n未満の素数の表を返す T[] sieve(T)(T m, T n) { T[] primes = new T[](n); foreach (i; 2 .. n) primes[i] = i; for (T i = 2; i*i < n; ++i) if (primes[i]) for (T j = i*i; j < n; j += i) primes[j] = 0; return primes.remove!(a => a < m).array; } void main() { // 入力 auto N = readln.chomp.to!long; auto M = readln.chomp.to!long; // 答えの計算 auto primes = sieve(2L, 10_000L); N /= 1000; N %= M; N = min(N, M - N); auto up = iota(M, M - N, -1).array; long ans = 1; foreach (p; primes) { long i = p; long num = 0, x = N; while (x) { x /= i; num += x; } if (!num) break; foreach (j; 0 .. N) { while (num > 0 && up[j] % i == 0) { up[j] /= i; num--; } } } foreach (u; up) { ans = (ans * u) % MOD; } // 答えの出力 writeln(ans); }