#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
const ll MOD = 1e9+7;
const ll INF = 1e18;
#define rep(i,m,n) for(ll i = (m); i <= (n); i++)
#define zep(i,m,n) for(ll i = (m); i < (n); i++)
#define rrep(i,m,n) for(ll i = (m); i >= (n); i--)
#define print(x) cout << (x) << endl;
#define printa(x,m,n) for(int i = (m); i <= n; i++){cout << (x[i]) << " ";} cout<<endl;

long long extGcd(long long a, long long b, long long &p, long long &q) {  
    if (b == 0) { p = 1; q = 0; return a; }  
    long long d = extGcd(b, a%b, q, p);  
    q -= a/b * p;  
    return d;  
}

pair<long long, long long> ChineseRem(long long b1, long long m1, long long b2, long long m2) {
  long long p, q;
  long long d = extGcd(m1, m2, p, q);
  if ((b2 - b1) % d != 0) return make_pair(0, -1);
  long long m = m1 * (m2/d);
  long long tmp = (b2 - b1) / d * p % (m2/d);
  long long r = ((b1 + m1 * tmp) % m + m) % m;
  return make_pair(r, m);
}

int main(){
    cin.tie(0); ios::sync_with_stdio(false);
    
    ll t; cin >> t;
    while(t--){
        ll x, y, p, q; cin >> x >> y >> p >> q;
        
        ll ans = -1;
        zep(i, x, x + y){
            zep(j, p, p + q){
                auto res = ChineseRem(i, 2 * (x + y), j, p + q);
                if(res.second != -1 && (ans == -1 || ans > res.first)){
                    ans = res.first;
                }
            }
        }
        if(ans == -1){
            print("infinity")
        }else{
            print(ans)
        }
    }
    
    return 0;
}
#include <bits/stdc++.h>
using namespace std;

template<class Cost = int>
struct Edge {
    int from, to;
    Cost cost;
    Edge(const int &from = -1, const int &to = -1, const Cost &cost = 1)
        : from(from), to(to), cost(cost) {}

    bool operator<(const Edge<Cost> &rhs) const { return this->cost < rhs.cost; }
    bool operator>(const Edge<Cost> &rhs) const { return this->cost > rhs.cost; }
};

template<class Cost = int>
struct Graph : vector<vector<Edge<Cost>>> {
    int n;
    Graph(int _n = 0) : n(_n) { this->resize(n); }

    void add_edge(const int &src, const int &dst, const Cost &cost = 1) {
        assert(0 <= src && src < n && 0 <= dst && dst < n);
        (*this)[src].emplace_back(src, dst, cost);
    }
    void add_biedge(const int &src, const int &dst, const Cost &cost = 1) {
        add_edge(src, dst, cost), add_edge(dst, src, cost);
    }
};

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int N, M, X, Y; cin >> N >> M >> X >> Y;
    using Info = pair<long long, long long>;
    Graph<Info> G(N+1);
    for (int i = 0; i < M; i++) {
        int a, b, t, k;
        cin >> a >> b >> t >> k;
        G.add_biedge(a, b, Info(t, k));
    }
    
    set<pair<long long, int>> S;
    vector<long long> T(N+1, 1e18);
    T[X] = 0;
    S.emplace(0, X);
    while (!S.empty()) {
        auto u = *S.begin();
        int C = u.second;
        long long now = u.first;
        S.erase(S.begin());
        if (T[C] < now) continue;
        for (auto &e: G[C]) {
            auto [t, k] = e.cost;
            long long nx = (now + k - 1) / k * k + t;
            if (T[e.to] > nx) {
                T[e.to] = nx;
                S.emplace(T[e.to], e.to);
            }
        }
    }
    if (T[Y] == 1e18) cout << -1 << "\n";
    else cout << T[Y] << "\n";
    return 0;
}