#include <bits/stdc++.h>
using namespace std;
#define all(v) v.begin(),v.end()
#define MP make_pair
#define MT make_tuple
typedef long long ll;
#define PA pair<ll,ll>
#define TU tuple<ll,ll,ll>
#define vi vector<ll>
#define vii vector<vector<ll> >
#define rep(i,n) for(ll (i)=0; (i)<(ll)(n); (i)++)
#define rep2(i,m,n) for(ll (i)=(m); (i)<(ll)(n); (i)++)
const ll INF = 1ll<<55;
const ll INF2 = 1ll<<31;
const ll MOD = 998244353;


vi dist;
vector<bool> checked;
priority_queue<PA,vector<PA>,greater<PA>> pq;

void dijkstra(vector<vector<TU>> &graph) {
  while(!pq.empty()) {
    PA state = pq.top();
  pq.pop();
  ll time = state.first;
  ll destin = state.second;
  if(dist.at(destin)<time) continue;
  
  checked.at(destin) = true;
  
  for(auto nv: graph.at(destin)) {
    if(checked.at(get<0>(nv))) continue;
    ll new_time = (time/get<2>(nv))*get<2>(nv) + get<1>(nv);
    if(time%get<2>(nv)) {
      new_time += get<2>(nv);
    }
    if(new_time<dist.at(get<0>(nv))) {
      dist.at(get<0>(nv)) = new_time;
      pq.push(MP(new_time,get<0>(nv)));
    }
    
  }
  }
}

int main() {
  ll n,m,x,y;
  cin>>n>>m>>x>>y;
  vector<vector<TU>> graph(n,vector<TU>(0));
  rep(i,m) {
    ll a,b,t,k;
    cin>>a>>b>>t>>k;
    graph.at(a-1).push_back(MT(b-1,t,k));
    graph.at(b-1).push_back(MT(a-1,t,k));
  }
  
  dist.assign(n,INF);
  checked.assign(n,false);
  
  pq.push(MP(0,x-1));
  dist.at(x-1) = 0;
    
  dijkstra(graph);
  
  if(dist.at(y-1)==INF) cout<<-1<<endl;
  else cout<<dist.at(y-1)<<endl;
}
#include<bits/stdc++.h>
using namespace std;

int main(){
	int a,b,x,y;
  	cin>>a>>b>>x>>y;
  	if(a>b){
      cout<<x+min(y,2*x)*(a-b-1);
    }else{
    	cout<<min(y,2*x)*(b-a)+x;
    }
	return 0;
}