#include <bits/stdc++.h>

#define f first
#define s second
#define loop(i, n) for (int i = 0; i < n; ++i)
#define read(a, n) loop($, n) cin >> a[$];
#define show(a, n)                  \
    loop($, n) cout << a[$] << " "; \
    cout << endl;

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

/*	// RANDOM NUMBER GENERATOR
// rng() generates u.a.r. from [0, 2^32 - 1]
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
*/

/* // TIME
auto start = chrono::high_resolution_clock::now();
// ...
auto stop = chrono::high_resolution_clock::now();
auto duration = chrono::duration_cast<chrono::microseconds>(stop - start);
cout << duration.count() << endl;
*/

struct con{
    ull d, k, t;
};

void dijkstra(int n, int s, vector<con> G[], ll d[]){
    priority_queue<pair<ll, int>, vector<pair<ll, int> >, greater<pair<ll, int> > > H;
    H.push({0, s});
    while(n && !H.empty()){
        int v = H.top().s;
        ll t = H.top().f;
        H.pop();
        if(d[v] == -1){
            --n;
            d[v] = t;
            for(con c : G[v]){
                if(d[c.d] == -1){
                    H.push({t + (c.k - t % c.k) % c.k + c.t, c.d});
                }
            }
        }
    }
}

int main(){
	/*	// IO
	ios_base::sync_with_stdio(false);	// unsync C- and C++-streams (stdio, iostream)
	cin.tie(NULL);	// untie cin from cout (no automatic flush before read)
	*/
    int n, m, s, t;
    cin >> n >> m >> s >> t;
    --s; --t;
    vector<con> G[n];
    loop(i, m){
        int u, v, l, k;
        cin >> u >> v >> l >> k;
        G[u - 1].push_back({v - 1, k, l});
        G[v - 1].push_back({u - 1, k, l});
    }
    ll d[n];
    loop(i, n){
        d[i] = -1;
    }
    dijkstra(n, s, G, d);
    cout << d[t] << endl;
    return 0;
}
#include<bits/stdc++.h>
#define MAX 100000
#define MOD 1000000007
using namespace std;
vector<pair<int,pair<int,int>>> v[MAX+10];
long long sp[MAX+10];
set<pair<long long,int>> st;
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	int n,m,x,y;
	cin>>n>>m>>x>>y;
	while(m--)
	{
		int a, b,t,k;
		cin>>a>>b>>t>>k;
		v[a].push_back({b,{t,k}});
		v[b].push_back({a,{t,k}});
	}
	for(int i=1;i<=n;++i)
		sp[i] = LLONG_MAX;
	sp[x] = 0;
	st.insert({0,x});
	while(!st.empty())
	{
		pair<long long,int> p = *(st.begin());
		st.erase(st.begin());
		for(pair<int,pair<int,int>> x:v[p.second])
		{	
			long long tm = x.second.first;
			if(sp[p.second]%x.second.second)
				tm += x.second.second*1LL-1LL*(sp[p.second]%x.second.second);
			if(tm+sp[p.second]<sp[x.first])
			{
				set<pair<long long,int>>::iterator it = st.find({sp[x.first],x.first});
				if(it!=st.end())
					st.erase(it);
				sp[x.first] = tm+sp[p.second];
				st.insert({sp[x.first],x.first});
			}
		}
	}
	cout<<(sp[y]==LLONG_MAX?-1:sp[y])<<endl;
	return 0;
}