#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string.h>
#include<algorithm>
#include<unordered_map>
#include<queue>
#include<set>
using namespace std;
#define cin(x) scanf("%d", &x)
typedef pair<int, int> PII;
const int N = 45000, M = 50;
int primes[N], cnt;
bool st[N];
PII zhifac_b1[M];//存b1所有的质因子
int cntf;
int divider[N], cntd;//divider存b1所有的因子
void xian_primes(int n) {//线筛法
for (int i = 2; i <= n; i++) {
if (!st[i])primes[cnt++] = i;
for (int j = 0; primes[j] <= n / i; j++) {
st[primes[j] * i] = true;
if (i % primes[j] == 0)break;
}
}
}
int gcd(int a, int b) {
return b ? gcd(b, a % b) : a;
}
void dfs(int u, int p) {//dfs,用b1的质因子把b1内所有的因子扫出来
if (u > cntf) {//超出了质因子个数,返回
divider[cntd++] = p;//别忘了存这个p
return;
}
for (int i = 0; i <= zhifac_b1[u].second; i++) {
dfs(u + 1, p);
p *= zhifac_b1[u].first;
}
}
int main() {
xian_primes(N);//预处理出1~45000的质数
int n;
cin >> n;
while (n--) {
int a0, a1, b0, b1;
scanf("%d%d%d%d", &a0, &a1, &b0, &b1);
int d = b1;//初始化,很重要
cntf = 0;//初始化,很重要
for (int i = 0; primes[i] <= d / primes[i]; i++) {//求出b1的所有质因子
int p = primes[i];
if (d % p == 0) {
int s = 0;
while (d % p == 0)s++, d /= p;
zhifac_b1[++cntf] = { p, s };
}
}
if (d > 1)zhifac_b1[++cntf] = { d, 1 };//别漏了较大的一项
cntd = 0;//初始化,很重要
dfs(1, 1);//从第一个质因子开始遍历
int res = 0;
for (int i = 0; i < cntd; i++) {//一个个试,试出答案
int x = divider[i];
if (gcd(x, a0) == a1 && (long long)x * b0 / gcd(x, b0) == b1)
res++;
}
printf("%d\n", res);
}
}