#include<bits/stdc++.h>
#define ll long long int
using namespace std;

int main()
{
    ios::sync_with_stdio(false); cin.tie(0);
    ll n, m, X, Y;
    cin >> n >> m >> X >> Y;
    vector<tuple<ll, ll, ll>> adj[n + 1];

    for (ll i = 0; i < m; i++) {
        ll a, b, t, k;
        cin >> a >> b >> t >> k;
        adj[a].emplace_back(b, t, k);
        adj[b].emplace_back(a, t, k);
    }
    auto Dijkstra = [&](ll src, ll dest) {
        vector<ll> d(n + 1, LLONG_MAX);
        d[src] = 0;
        using pll = pair<ll, ll>;
        priority_queue <pll, vector<pll>, greater<pll>> pq;

        pq.emplace(0ll, src);
        while (!pq.empty()) {
            auto [d_v , v] = pq.top();
            pq.pop();

            if (d_v > d[v])continue;
            if (v == dest)return d_v;

            for (auto [to, t, k] : adj[v]) {
                ll departure = d_v / k;
                if (d_v % k)departure++;
                departure *= k;

                if (departure + t < d[to]) {
                    d[to] = departure + t;
                    pq.emplace(d[to], to);
                }
            }
        }
        return -1ll;
    };

    ll ans = Dijkstra(X, Y);
    cout << ans;


    return 0;
}

#pragma GCC optimize("O3")
//#pragma GCC target("avx2")
//#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include <prettyprint.hpp>
#define debug(...)  cerr << "[" << #__VA_ARGS__ << "]: ", d_err(__VA_ARGS__);
#else
#define debug(...) 83;
#endif

void d_err() {
    cerr << endl;
}

template <typename H, typename... T>
void d_err(H h, T... t) {
    cerr << h << " ";
    d_err(t...);
}

template <typename T>
void print(T x) {
    cout << x << "\n";
}

#define ALL(x) (x).begin(), (x).end()
#define FOR(i, m, n) for (ll i = (m); i < (n); ++i)
#define REVFOR(i, m, n) for (ll i = (n - 1); i >= (m); --i)
#define REP(i, n) FOR(i, 0, n)
#define REVREP(i, n) REVFOR(i, 0, n)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define eb emplace_back
#define bcnt __builtin_popcountll

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<ld> vld;
typedef pair<ll,ll> Pll;
typedef pair<int,int> Pin;

ll INF = 1e16;
int inf = 1e9;

int main(){
    cin.tie(0);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);

    ll n, m, x, y; cin >> n >> m >> x >> y;
    x--, y--;

    vector<vector<pair<ll, pair<ll, ll>>>> edge(n);
    REP(i, m) {
        ll a, b, t, k;
        cin >> a >> b >> t >> k;
        a--, b--;
        edge[a].pb({t, {b, k}});
        edge[b].pb({t, {a, k}});
    }

    vll dist(n, INF);

    priority_queue<pair<ll, ll>> q;
    q.emplace(0, x);
    dist[x] = 0;

    while(not q.empty()) {
        auto p = q.top(); q.pop();
        auto cur = p.se, time = p.fi;

        if (dist[cur] > time) continue;

        unordered_map<ll, ll> m;
        for(auto &e: edge[cur]) {
            auto nxt = e.se.fi;
            auto t = e.fi, k = e.se.se;

            ll t_s = (time + k - 1) / k * k;
            ll t_e = t_s + t;

            if (t_e >= dist[nxt]) continue;

            if (m.find(nxt) == m.end()) m[nxt] = t_e;
            else m[nxt] = min(m[nxt], t_e);
        }

        for (auto &e: m) {
            auto nxt = e.fi, t_e = e.se;

            if (t_e >= dist[nxt]) continue;

            dist[nxt] = t_e;

            q.emplace(t_e, nxt);
        }

    }

    print(dist[y] == INF ? -1 : dist[y]);
}
