#include <bits/stdc++.h>
using namespace std;

#define INF 1e18
typedef pair<long long, int> iPair; 

const int maxN = 1e5;
vector<pair<int,pair<int,int> > > adj[maxN];
 
void shortestPath(int n, int src,int dest) 
{ 

    priority_queue< iPair, vector <iPair> , greater<iPair> > pq; 
  
    vector<long long> dist(n, INF); 

    pq.push(make_pair(0, src)); 
    dist[src] = 0; 

    while (!pq.empty()) 
    { 
        int u = pq.top().second; 
        pq.pop(); 
  		
  		if(u == dest)
  		{
  			cout<<dist[dest]<<endl;
			return;	
		}
  		
        for (auto pr:adj[u]) 
        { 
            int v = pr.first; 
			long long t = pr.second.first;
			long long k = pr.second.second;
			
			long long curr_dist = ((dist[u] + k-1)/k)*k;
			
            if (dist[v] > curr_dist + t) 
            { 
                dist[v] = curr_dist + t; 
                pq.push(make_pair(dist[v], v)); 
            } 
        } 
    } 
 
   	cout<<-1<<endl;
} 

int main()
{   
    int n,m,x,y;
    cin>>n>>m>>x>>y;
    x--,y--;
    
    int u,v;
    int t,k;
    
    while(m--)
    {
    	cin>>u>>v>>t>>k;
		u--,v--;
		
		adj[u].push_back({v,{t,k}});
		adj[v].push_back({u,{t,k}});	
	}
	
	shortestPath(n,x,y);
	
	return 0;
}
// Author: HarshKumar

#include <bits/stdc++.h>
using namespace std;
#define ll int64_t
const ll N = 1e6 + 6, M = 1e9 + 7;
const ll INF = (1LL << 62) - 1;
vector<vector<tuple<ll, ll, ll>>> G;
vector<ll> dijkstra(ll v)
{
    vector<ll> ans(G.size(), INF), vis(G.size());
    ans[v] = 0;
    priority_queue<pair<ll, ll>> que;
    que.push({0, v});
    while (!que.empty())
    {
        auto [x, u] = que.top();
        que.pop();
        if (vis[u])
            continue;
        vis[u] = 1;
        for (auto [v, w, d] : G[u])
        {
            ll x = max(0LL, llround(ceil(sqrtl(d))) - ans[u] - 1);
            w += ans[u] + x + d / (x + ans[u] + 1);
            if (w < ans[v])
                ans[v] = w, que.push({-ans[v], v});
        }
    }
    return ans;
}
int main()
{
    ios::sync_with_stdio(false), cin.tie(nullptr);
    ll n, m;
    cin >> n >> m;
    G.resize(n);
    while (m--)
    {
        ll a, b, c, d;
        cin >> a >> b >> c >> d;
        a--;
        b--;
        G[a].push_back({b, c, d});
        G[b].push_back({a, c, d});
    }
    auto d = dijkstra(0);
    if (d.back() < INF)
        cout << d.back();
    else
        cout << -1;
}