#include<bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define ll long long
#define P pair<ll,int>
#define PI 3.141592653589793
#define pb push_back
const int INF = 1001001001;
const ll MX = 1e18;
const int mod = 998244353;
template<class T> inline bool chmax(T& a, T b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}

int main() {
	int n, m, x, y;
	cin >> n >> m >> x >> y;
	x--; y--;
	vector<vector<ll>> b(n), t(n), k(n);
	vector<ll> mp(n, MX);

	rep(i, m) {
		int ai, bi, ti, ki;
		cin >> ai >> bi >> ti >> ki;
		ai--; bi--;
		b[ai].pb(bi);
		t[ai].pb(ti);
		k[ai].pb(ki);
		b[bi].pb(ai);
		t[bi].pb(ti);
		k[bi].pb(ki);
	}
	priority_queue<P> q;//（現在時刻*-1、場所）
	q.push(P(0, x));
	while (!q.empty()) {
		ll nt = q.top().first;
		nt *= -1;
		int now= q.top().second;
		q.pop();

		rep(i, b[now].size()) {
			ll next = nt + t[now][i] + k[now][i] - nt % k[now][i];
			if (nt % k[now][i] == 0) {
				next = nt + t[now][i];
			}

			if (next < mp[b[now][i]]) {
				mp[b[now][i]] = next;
				q.push(P(-next, b[now][i]));
			}
		}
	}

	if (mp[y] == MX) cout << -1 << endl;
	else cout << mp[y] << endl;
}

#include <bits/stdc++.h>
using namespace std;
 
#define all(x) x.begin(), x.end()
#define sz(x) (int) x.size()
#define pb push_back
#define endl '\n'
#define snd second
#define fst first
#define fastio cin.tie(NULL),cout.sync_with_stdio(true)
 
typedef long long int ll;
typedef unsigned long long int ull;
typedef vector <int> vi;
typedef pair <ll,ll> ii;
typedef vector<vector<ll>> matrix;
 
const int mod = 1e9 + 7;
const ll INF = 1e18;
const double EPSILON = 1e-9;
const int N = 2*1e5+5;
vector<pair<int, ii>> adj[N];
priority_queue <ii, vector <ii>, greater <ii>> pq;
int main(){
    fastio;
    int n,m,x,y;
    cin >> n >> m >> x >> y;
    for(int i = 0; i < m; i++){
        int u,v,c,t; cin >> u >> v >> c >> t;
        adj[u].pb({v, {c,t}});
        adj[v].pb({u, {c,t}});
    }
    vector<ll> see(n+1, INF);
    pq.push({0, x});
    see[x] = 0;
    while(!pq.empty()){
        ll d = pq.top().fst;
        int v = pq.top().snd;
        pq.pop();
        if(d > see[v])
            continue;
        for(auto i:adj[v]){
            ll cost = i.snd.fst + (i.snd.snd*((d+i.snd.snd-1)/i.snd.snd) - d);
            if(see[i.fst] > d + cost){
                see[i.fst] = d + cost;
                pq.push({see[i.fst], i.fst});
            }
        }
    }
    cout << (see[y] == INF ? -1 : see[y]) << '\n';
    return 0;
}