#include <bits/stdc++.h>
using namespace std;
typedef long long  ll;
typedef long double ld;
#define pb push_back
#define MAXN 100005
#define INF (ll)1e18
#define mod 1000000007 
//#define mod 998244353
#define endl '\n'
#define level 20
ll cc=0;
 
void boost()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
}

vector <pair<ll,pair<ll,ll>>> V[MAXN];
ll dis[MAXN],vis[MAXN];
priority_queue<pair<ll,ll>,vector<pair<ll,ll>>,greater<pair<ll,ll>>> pq;

int main()
{
    boost();
    
    ll i,j,k,n,t,c=0,l,r,x,y,n1,mask;
    ll ans,h,z,m,u,v,q,mm,w,mx,d,mid;
    ld f;
    
    cin>>n>>m>>l>>r;
    
    for(i=0;i<=n;i++)
    {
        dis[i]=INF;
        vis[i]=0;
    }
 
        for(i=1;i<=m;i++)
        {
            cin>>x>>y>>z>>k;
            V[x].pb(make_pair(y,make_pair(z,k)));
            V[y].pb(make_pair(x,make_pair(z,k)));
        }
        
        dis[l]=0;
        pq.push(make_pair(dis[l],l));
        
    while(!pq.empty())
    {
        u=pq.top().second;
        pq.pop();
 
        if(vis[u]==0)
        {
            vis[u]++;
 
        for(auto p: V[u])
        {
            v=p.first;
            k=p.second.first;
            z=p.second.second;
            
            w=(dis[u]%z);
            
            if(w!=0)
            {
                w=z-w;
            }
            
            k+=w;
 
            if((dis[v]>(dis[u]+k))&&(vis[v]==0))
            {
                dis[v]=dis[u]+k;
                pq.push(make_pair(dis[v],v));
            }
        }
 
    }
    
    }
    
    if(vis[r]==0)
    {
        cout<<-1<<endl;
    }
    
    else
    {
        cout<<dis[r]<<endl;
    }
        
    
    
return 0;
}
#include <bits/stdc++.h>          
using namespace std;
using ll = long long;
using ld = long double;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define repp(i, st, en) for (ll i = (ll)st; i < (ll)(en); i++)
#define repm(i, st, en) for (ll i = (ll)st; i >= (ll)(en); i--)
#define all(v) v.begin(), v.end()
void chmax(ll &x, ll y) {x = max(x,y);}
void chmin(ll &x, ll y) {x = min(x,y);}
void Yes() {cout << "Yes" << endl; exit(0);}
void No() {cout << "No" << endl; exit(0);}
template<class in_Cout> void Cout(in_Cout x) {cout << x << endl; exit(0);}

const ll inf = 1e18;
const ll mod = 1e9 + 7;

struct edge {ll to, cost, k;};

ll N, M, X, Y;

ll dijkstra(ll st, ll en, vector<vector<edge>> G) {
    vector<ll> dist(N,inf);
    dist[st] = 0LL;
    priority_queue<pair<ll,ll>,vector<pair<ll,ll>>,greater<pair<ll,ll>>> que;
    que.push({0,st});
    while (que.size()) {
        pair<ll,ll> p = que.top();
        que.pop();
        ll now = p.second, d = p.first;
        if (dist[now]<d) continue;
        for (auto e : G[now]) {
            ll to = e.to, cost = e.cost, k = e.k;
            ll dt = (k-(dist[now]%k))%k;
            ll nd = dist[now] + dt + cost;
            if (dist[to]<=nd) continue;
            dist[to] = nd;
            que.push({nd,to});
        }
    }
    ll res = dist[en];
    if (res==inf) res = -1LL;
    return res;
}

int main() {
    cin >> N >> M >> X >> Y;
    X--; Y--;
    vector<vector<edge>> G(N);
    rep(i,M) {
        ll a, b, t, k; cin >> a >> b >> t >> k;
        a--; b--;
        G[a].push_back({b,t,k});
        G[b].push_back({a,t,k});
    }

    ll ans = dijkstra(X,Y,G);

    cout << ans << endl;
}