#include<bits/stdc++.h>
#define ll long long int
#define M 1000000007
#define mod 998244353
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define pi pair<ll,ll>
#define endl "\n"
using namespace std;
const ll N=200010;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

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

    vector<pi> val;
    vector<pi> adj[n+1];

    for(ll i=0;i<m;++i){
        ll a,b,t,k;
        cin>>a>>b>>t>>k;
        adj[a].pb(mp(b,i));
        adj[b].pb(mp(a,i));
        val.pb(mp(t,k));
    }

    vector<ll> dis(n+1,LLONG_MAX);

    set<pi> s;
    s.insert(mp(0,x));

    while(!s.empty()){
        ll v=(*s.begin()).second;
        ll d=(*s.begin()).first;
        s.erase(s.begin());
        if(d>=dis[v]){
            continue;
        }
        dis[v]=d;
        for(auto x:adj[v]){
            ll u=x.first;
            ll idx=x.second;
            ll k=val[idx].second;
            ll t=val[idx].first;
            ll cost=d+t;
            if(d%k!=0){
                cost+=(k-d%k);
            }
            if(cost<dis[u]){
                s.insert(mp(cost,u));
            }
        }
    }

    if(dis[y]==LLONG_MAX){dis[y]=-1;}
    cout<<dis[y];

    return 0;
}

#include <bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
//using namespace atcoder;
 
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
 
#define rep(i,cc,n) for(int i=cc;i<n;++i)
#define lrep(i,cc,n) for(long long i=cc;i<n;++i)
#define sqrep(i,cc,n) for(long long i=cc;i*i<=n;++i)
#define rrep(i,cc,n) for(int i=cc;i>=n;--i)
#define pii pair<int, int>
#define pll pair<long long, long long>
 
using ll = long long;

const vector<int> dx = {1, 0, 1};
const vector<int> dy = {0, 1, 1};

const vector<int> dx2 = {1, 1,  1, 0,  0, 0, -1, -1, -1};
const vector<int> dy2 = {1, 0, -1, 1, -1, 0,  1,  0, -1};
const double PI = 3.1415926535;
const ll inf = 1001001001;
const ll e9  = 1000000000;
const ll mod = 1000000007;
const ll mod2 = 998244353;
 
const int MAX = 1000000;
const int MOD = 1000000007;
const ll big = (1ll<<60);

ll gcd(ll x, ll y) { return (x % y)? gcd(y, x % y): y; }

struct Edge {
    ll to;
    ll cost;
    ll k;
};

int main(){
    int n, m, x, y;
    cin >> n >> m >> x >> y;
    x--,y--;
    vector<vector<Edge>>G(n);
    rep(i, 0, m){
      ll a, b;
      ll ti, ki;
      cin >> a >> b >> ti >> ki;
      a--,b--;
      Edge ed1, ed2;
      ed1.to = b;
      ed1.cost = ti;
      ed1.k = ki;
      G[a].push_back(ed1);

      ed2.to = a;
      ed2.cost = ti;
      ed2.k = ki;
      G[b].push_back(ed2);
    }
    priority_queue<pll,vector<pll>,greater<pll>>que;
    que.emplace(0,x);
    vector<ll>time(n, big);
    vector<bool>visit(n,false);
    time[x] = 0;
    while(!que.empty()){
      pll temp = que.top();
      que.pop();
      if(visit[temp.second])continue;
      visit[temp.second] = true;

      if(time[temp.second]<temp.first)continue;
      for(auto p:G[temp.second]){
        ll temp_time = ((temp.first+p.k-1)/p.k)*p.k + p.cost;
        if(time[p.to]>temp_time){
          time[p.to] = temp_time;
          que.push({time[p.to],p.to});
        }
      }
    }
    if(time[y]==big){
      cout << -1 << endl;
    }else cout << time[y] << endl;
}