//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid (tr[u].l+tr[u].r>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;

//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;

const int N=1000010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;

int n,m,s,t;
int e[N],ne[N],w[N],k[N],h[N],idx;
LL dis[N];
bool st[N];
struct Node
{
    int u;
    LL d;
    bool operator < (const Node &W) const
    {
        return d>W.d;
    }
};

void add(int a,int b,int c,int d)
{
    e[idx]=b,w[idx]=c,k[idx]=d,ne[idx]=h[a],h[a]=idx++;
}

void dijkstra()
{
    priority_queue<Node>q;
    q.push({s,0});
    memset(dis,INF,sizeof(dis));
    dis[s]=0;
    while(q.size())
    {
        Node cur=q.top(); q.pop();
        int u=cur.u; LL d=cur.d;
        if(st[u]) continue;
        st[u]=true;
        for(int i=h[u];~i;i=ne[i])
        {
            int ver=e[i];
            LL now=d;
            if(d%k[i]!=0&&d!=0) now/=k[i],now++,now=now*k[i];
            if(dis[ver]>now+w[i])
            {
                dis[ver]=now+w[i];
                q.push({ver,dis[ver]});
            }
        }
    }
}

int main()
{
//	ios::sync_with_stdio(false);
//	cin.tie(0);

    memset(h,-1,sizeof(h)); idx=0;
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int i=1;i<=m;i++)
    {
        int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d);
        add(a,b,c,d); add(b,a,c,d);
    }
    dijkstra();
    printf("%lld\n",dis[t]==0x3f3f3f3f3f3f3f3f? -1:dis[t]);



















	return 0;
}
/*

*/









#include <bits/stdc++.h>
#define F first
#define S second
#define rep(i, a, b) for(int i = (a); i < (b); ++i)
#define per(i, a, b) for(int i = (b)-1; i >= (a); --i)
#define bck(i, a, b) if ((i) >= (a) && (i) < (b))
#define trav(x, a) for (auto &x : (a))
#define sz(a) (int)(a).size()
#define all(x) (x).begin(), (x).end()
#define mp make_pair
#define pb push_back
#define eb emplace_back
using namespace std;
typedef long long ll;
typedef string str;
template<typename T> using vec = vector<T>;
template<typename T> using pq = priority_queue<T, vector<T>, std::greater<T>>;
template<typename T> using mxpq = priority_queue<T>;
typedef pair<int,int> pii;
typedef vec<int> vi;
typedef vec<pii> vii;
typedef vec<vi> vvi;
typedef pair<ll,ll> pll;
typedef vec<ll> vl;
typedef vec<pll> vll;
typedef vec<vl> vvl;
template<typename A, typename B>
istream& operator>>(istream& s, pair<A,B>& p) { return s>>p.first>>p.second; }
template<typename T>
istream& operator>>(istream& s, vec<T>& p) {
    for (T& t : p) s >> t;
    return s;
}

ll dijk(vec<vec<pair<int, pll>>> &g, int s, int e) {
    pq<pll> q;
    q.push({0, s});
    vec<bool> v(sz(g));
    while (q.size()) {
        auto [d, i] = q.top(); q.pop();
        if (v[i]) continue;
        v[i] = true;
        if (i == e) return d;
        trav(ch, g[i]) {
            int next_city = ch.F;
            ll k = ch.S.S;
            ll t = ch.S.F;
            if (!v[ch.F]) {
                ll next_train = (d + k-1) / k * k; // ceil(d / k) * k
                q.push({next_train + t, next_city});
            }
        }
    }
    return -1;
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int n, m, s, e;
    cin >> n >> m >> s >> e;

    vec<vec<pair<int, pll>>> g(n);
    rep(i, 0, m) {
        int a, b, t, k;
        cin >> a >> b >> t >> k;
        g[a-1].pb({b-1, {t, k}});
        g[b-1].pb({a-1, {t, k}});
    }
    cout<<dijk(g, s-1, e-1)<<endl;
}
