#include <bits/stdc++.h>
using namespace std;
 
#define REP(i, a, b) for(int i = (a); i <= (b); i++)
#define PER(i, a, b) for(int i = (a); i >= (b); i--)
#define rep(i, a, b) for(int i = (a); i < (b); i++)
#define all(S) (S).begin(), (S).end()
#define pb push_back
#define mk make_pair
#define S second
#define F first
typedef long long ll;
typedef long double lf;
typedef pair<int, int> ii;

// Euclides Estendido
ll gcd(ll A, ll B, ll &X, ll &Y) {
	if(B == 0) {
		X = 1; Y = 0;
		return A;
	}
	ll x1, y1;
	ll G = gcd(B, A % B, x1, y1);
	X = y1; Y = x1 - (A / B) * y1;
	return G;
}

// Acha a primeira vez que dois eventos ocorrem ao mesmo tempo
// Os eventos acontecem a cada:
// A * T1 + Z1 e B * T2 + Z2
ll solve(ll A, ll B, ll Z1, ll Z2) {
	if(Z2 > Z1) swap(A, B), swap(Z1, Z2);
	ll X, Y, ans = 0;
	ll G = gcd(A, B, X, Y), C = Z2-Z1;
	if(C%G) return 1LL << 62;	// impossivel
	C /= G; X *= C; Y *= C;
	// Acho o primeiro X positivo
	if(X >= 0) {
		ll K = (X * G) / B;
		ans = A * (X - K * (B / G)) + Z1;
	} else {
		ll K = (-X * G + B - 1) / B;
		ans = A * (X + K * (B / G)) + Z1;
	}
	// retorna um par na forma (A, Z)
	// A -> novo tamanho do ciclo
	// Z -> primeira vez que acontece
	// return mk(A * (B / G), ans);
	return ans;
}

// Anotação importante, Há duas formas de alterar as soluções:
// (1) -> X = X + K * (B / G) e Y = Y - K * (A / G)
// (2) -> X = X - K * (B / G) e Y = Y + K * (A / G)

int main(int argc, char** argv) {
	int T, X, Y, P, Q;
	scanf("%d", &T);
	rep(t, 0, T) {
		ll ans = (1LL <<62);
		scanf("%d%d", &X, &Y);
		scanf("%d%d", &P, &Q);
		rep(y, 0, Y) rep(q, 0, Q)
			ans = min(ans, solve(2*X+2*Y, P+Q, X + y, P + q));
		if(ans != (1LL << 62))
			printf("%lld\n", ans);
		else puts("infinity");
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
//const long nPrime = 1000000007;
//const long nPrime = 998244353;

long GCD(const long n, const long m){
    long a = abs(n), b = abs(m);
    if(a<b){
        swap(a,b);
    }
    while (b > 0) {
        long t = a / b;
        a -= t * b;
        swap(a, b);
    }
    return a;    
}

long Inverse(const long n, const long nPrime){
    long a = n, b = nPrime, u = 1, v = 0;
    while (b > 0) {
        long t = a / b;
        a -= t * b;
        swap(a, b);
        u -= t * v;
        swap(u, v);
    }
    u %= nPrime;
    if (u < 0){
        u += nPrime;
    }
    return u;    
}

// k≡n(mod p), k≡m(mod q)なるkを求める(p,qは互いに素,0<=k<pq)
long CRT_Prime(const long n, const long p, const long m, const long q){
    long i = (n-m) * Inverse(q, p);
    i %= p;
    i *= q;
    i += m;
    i %= (p*q);
    if(i < 0){
        i += p*q;
    }
    return i;
}

// k≡n(mod p), k≡m(mod q)なるkを求める(p,qは互いに素,0<=k<LCM(p,q))
long CRT(long n, const long p, long m, const long q){
    if(p == 0 || q == 0){
        return LONG_MAX; // 存在しないのでInfを返す
    }
    n %= p;
    m %= q;
    if(n < 0){
        n+= p;
    }
    if(m < q){
        m += q;
    }
  
    long iGCD = GCD(p,q);
    long iLCM = (p/iGCD) * q;
    if((n-m) % iGCD != 0){
        return LONG_MAX; // 存在しないのでInfを返す
    }
    
    long nRemain = n % iGCD;
    long n1 = (n-nRemain) / iGCD;
    long m1 = (m-nRemain) / iGCD;
    long p1 = p / iGCD;
    long q1 = q / iGCD;
    
    long nReturn = CRT_Prime(n1,p1,m1,q1) * iGCD + nRemain;
    nReturn %= iLCM;
    if(nReturn < 0){
        nReturn += iLCM;
    }
    return nReturn;
    
}

int main() {
    int t;
    cin >> t;
    while(t--){
        long x,y,p,q;
        cin >> x >> y >> p >> q;
        long nAns = 2e18;
        for(long i = 0; i < y; i++){
            nAns = min(nAns, CRT(x+i, 2*(x+y), p, p+q));
        }
        for(long i = 0; i < q; i++){
            nAns = min(nAns, CRT(x, 2*(x+y), p+i, p+q));
        }
        if(nAns < 2e18){
            cout << nAns << endl;
        }
        else {
           cout << "infinity" << endl;
        }
    }
    return 0;
}