#include<cstdio>
const int N = 200000 + 5;
const int MOD = (int)1e9 + 7;
int F[N], Finv[N], inv[N];//F是阶乘,Finv是逆元的阶乘
void init(){
inv[1] = 1;
for(int i = 2; i < N; i ++){
inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD;
}
F[0] = Finv[0] = 1;
for(int i = 1; i < N; i ++){
F[i] = F[i-1] * 1ll * i % MOD;
Finv[i] = Finv[i-1] * 1ll * inv[i] % MOD;
}
}
int comb(int n, int m){//comb(n, m)就是C(n, m)
if(m < 0 || m > n) return 0;
return F[n] * 1ll * Finv[n - m] % MOD * Finv[m] % MOD;
}
int main(){
init();
}
C(n, m) = C(n -1, m - 1) + C(n - 1, m)
C[1][0] = C[1][1] = 1;
for (int i = 2; i < N; i++){
C[i][0] = 1;
for (int j = 1; j < N; j++)
C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]);
}
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
ll mod_pow(ll x, ll n, ll p){
ll res = 1;
while(n){
if(n & 1) res =res * x % p;
x = x * x % p;
n >>= 1;
}
return res;
}
ll comb(ll n, ll m, ll p){
if(m > n) return 0;
ll ret = 1;
m = min(n - m, m);
for(int i = 1; i <= m; i ++){
ll a = (n + i - m) % p;
ll b = i % p;
ret = ret * (a * mod_pow(b, p - 2, p) % p) % p;
}
return ret;
}
ll Lucas(ll n, ll m, ll p){
if(m == 0) return 1;
return comb(n % p, m % p, p) * Lucas(n / p, m / p, p) % p;
}
int main(){
int T;
ll n, m, p;
scanf("%d", &T);
while(T--){
scanf("%I64d%I64d%I64d", &n, &m, &p);
printf("%I64d\n", Lucas(n, m, p));
}
return 0;
}
//组合数打表模板,适用于N<=3000
//c[i][j]表示从i个中选j个的选法。
long long C[N][N];
void get_C(int maxn)
{
C[0][0] = 1;
for(int i=1;i<=maxn;i++)
{
C[i][0] = 1;
for(int j=1;j<=i;j++)
C[i][j] = C[i-1][j]+C[i-1][j-1];
//C[i][j] = (C[i-1][j]+C[i-1][j-1])%MOD;
}
}
for (int i = 0; i <= n; ++i) {
C[i][0] = 1 % P;
for (int j = 1; j <= i; ++j) {
C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % P;
}
}
#include<cstdio>
const int N = 2000 + 5;
const int MOD = (int)1e9 + 7;
int comb[N][N];//comb[n][m]就是C(n,m)
void init(){
for(int i = 0; i < N; i ++){
comb[i][0] = comb[i][i] = 1;
for(int j = 1; j < i; j ++){
comb[i][j] = comb[i-1][j] + comb[i-1][j-1];
comb[i][j] %= MOD;
}
}
}
int main(){
init();
}
组合数总结