#include <stdio.h>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

struct V
{
    int d,t,k;
};

struct PQ
{
    int p;
    long long int t;

    bool operator < (const PQ x) const
    {
        return t>x.t;
    }
};

vector<V> v[100010];
priority_queue<PQ> pq;
int visit[100010];

int main()
{
    int n,m,x,y;
    int chk=0;

    scanf("%d%d%d%d",&n,&m,&x,&y);
    for(int i=1;i<=m;i++)
    {
        int a,b,c,d;
        scanf("%d%d%d%d",&a,&b,&c,&d);
        v[a].push_back({b,c,d});
        v[b].push_back({a,c,d});
    }
    pq.push({x,0});
    while(!pq.empty())
    {
        auto now=pq.top();
        pq.pop();
        if(visit[now.p]==1) continue;
        visit[now.p]=1;
        if(now.p==y)
        {
            printf("%lld",now.t);
            chk=1;
            break;
        }
        for(auto it : v[now.p])
        {
            if(visit[it.d]==1) continue;
            if(now.t%it.k==0) pq.push({it.d,(long long int)(now.t+it.t)});
            else pq.push({it.d,(long long int)((now.t/it.k+1)*it.k+it.t)});
        }
    }
    if(chk==0) printf("-1");
    return 0;
}

// Artur Kraska, II UWr

#include <bits/stdc++.h>

#define forr(i, n)                  for(int i=0; i<n; i++)
#define FOREACH(iter, coll)         for(auto iter = coll.begin(); iter != coll.end(); ++iter)
#define FOREACHR(iter, coll)        for(auto iter = coll.rbegin(); iter != coll.rend(); ++iter)
#define lbound(P,R,PRED)            ({typeof(P) X=P,RRR=(R), PPP = P; while(PPP<RRR) {X = (PPP+(RRR-PPP)/2); if(PRED) RRR = X; else PPP = X+1;} PPP;})
#define testy()                     int _tests; scanf("%d", &_tests); FOR(_test, 1, _tests)
#define CLEAR(tab)                  memset(tab, 0, sizeof(tab))
#define CONTAIN(el, coll)           (coll.find(el) != coll.end())
#define FOR(i, a, b)                for(int i=a; i<=b; i++)
#define FORD(i, a, b)               for(int i=a; i>=b; i--)
#define MP                          make_pair
#define PB                          push_back
#define ff                          first
#define ss                          second
#define deb(X)                      X;

#define M 1000000007
#define INF 1000000007LL

using namespace std;

int n, m, a, x, y;
priority_queue <pair<long long, int>> pq;

struct droga
{
    int cel;
    int odjazd;
    int czas;
};
droga d;

struct miasto
{
    bool byl;
    vector <droga> l;
};
miasto tab[1000007];

int main()
{
    scanf("%d %d %d %d", &n, &m, &x, &y);
    forr(i, m)
    {
        scanf("%d %d %d %d", &a, &d.cel, &d.czas, &d.odjazd);
        tab[a].l.PB(d);
        swap(a, d.cel);
        tab[a].l.PB(d);
    }
    pq.push(MP(0, x));
    while(!pq.empty())
    {
        int nr = pq.top().ss;
        long long czas = -pq.top().ff;
        pq.pop();
        if(tab[nr].byl)
            continue;
//        cout << "analizuje " << nr << endl;
        tab[nr].byl = 1;
        if(nr == y)
        {
            printf("%lld\n", czas);
            return 0;
        }

        for(auto p : tab[nr].l)
        {
            int nr2 = p.cel;
            long long odj = czas % p.odjazd;
            if(odj == 0)
                odj = czas;
            else
                odj = czas + p.odjazd - odj;
//            cout << " z " << nr << " moze jchac do " << nr2 << ", odjazd o " << odj << ", przyjazd o " << odj + p.czas << endl;
            if(!tab[nr2].byl)
                pq.push(MP(-(odj + p.czas), nr2));
        }
    }
    printf("-1\n");


    return 0;
}
