#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>

template <class T>
inline void read(T &x) {
    x = 0;
    int f = 0;
    char ch = getchar();
    while (!isdigit(ch))    { f |= ch == '-'; ch = getchar(); }
    while (isdigit(ch))     { x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar(); }
    x = f ? -x : x;
    return ;
}

typedef unsigned long long uLL;
typedef long long LL;

struct Edge {
    int to;
    LL w, k;
} ;

struct Node {
    int pos;
    LL dis;
    friend bool operator < (const Node &a, const Node &b) {
        return a.dis > b.dis;
    }
} ;

std::vector<Edge> g[100010];
std::priority_queue<Node> q;
LL dis[100010], k[100010];
int n, m, x, y;
bool vis[100010];

LL dist(LL a, LL b) {
    if (a % b == 0)    return 0;
    LL p = a / b;
    return (p + 1) * b - a;
}

int main() {
    read(n), read(m), read(x), read(y);
    for (int i = 1, u, v, w, k; i <= m; ++i) {
        read(u), read(v), read(w), read(k);
        g[u].push_back((Edge){v, w * 1LL, k * 1LL});
        g[v].push_back((Edge){u, w * 1LL, k * 1LL});
    }
    for (int i = 1; i <= n; ++i)    dis[i] = 1e18;
    dis[x] = 0;
    q.push((Node){x, 0});
    while (!q.empty()) {
        Node top = q.top();
        q.pop();
        if (vis[top.pos])    continue;
        vis[top.pos] = true;
        for (auto i : g[top.pos]) {
            if (dis[i.to] > dis[top.pos] + i.w + dist(dis[top.pos], i.k)) {
                dis[i.to] = dis[top.pos] + i.w + dist(dis[top.pos], i.k);
                q.push((Node){i.to, dis[i.to]});
            }
        }
    }
    printf("%lld\n", dis[y] == 1e18 ? -1 : dis[y]);
    return 0;
}
#include<bits/stdc++.h>
#define pb push_back
#define mk make_pair
#define ll long long
#define ss second
#define ff first
#define mod 1000000007
#define w(x) ll x; cin>>x; while(x--)
#define ps(x,y) fixed<<setprecision(y)<<x;
#define fo(i, j, k, in) for (ll i=j ; i<k ; i+=in)
#define re(i, j) fo(i, 0, j, 1)
#define pi acos(-1)
#define all(cont) cont.begin(), cont.end()
#define countbit(x) __builtin_popcount(x)
#define mod 1000000007
#define de(n) ll n;cin>>n;
#define def(a,n) ll n;cin>>n;ll a[n];re(i,n){cin>>a[i];}
#define defi(a,n,k) ll n;cin>>n; ll k;cin>>k;ll a[n];re(i,n){cin>>a[i];}
#define deb(x) cout<<#x<<"="<<x<<endl;
#define tr(it,a) for(auto it=a.begin();it!=a.end();it++)
#define nl cout<<endl;
using namespace std;
//912B 1009B 1350C 20C 1333C 1234D 1327C 1305B 1304B (or in matrix) 1216-C(26) 21
void cp()
{
    ios ::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
}
ll N=200005;
class union_find
{
	ll n;
	vector<ll> par;
	vector<ll> sz;
public:
	union_find(ll nval)
	{
		n = nval;
		par.resize(n + 1);
		sz.resize(n + 1);

		for (ll i = 1; i <= n; ++i)
			par[i] = i, sz[i] = 1;
	}

	//O(1) ammortized
	ll root(ll x)
	{
		/*while(x!=par[x])
			x=par[x];
		return x;*/

		if (x == par[x])
			return x;

		return par[x] = root(par[x]);
	}

	//O(1) ammortized
	bool find(ll a,ll b)
	{
		return root(a) == root(b);
	}

	//O(1) ammortized
	void un(ll a,ll b)
	{
		ll ra = root(a);
		ll rb = root(b);
		if (ra == rb)
			return;

		if (sz[ra] > sz[rb])
			swap(ra, rb);

		par[ra] = rb;
		sz[rb] += sz[ra];
		sz[ra]=0;
	}
    ll sq()
    {
        ll k=0;
        for(ll i=1;i<=n;i++)
        {
            if(sz[i]!=0)
            k+=(sz[i]-1);
        }
        return k;
    }
	
};
int main()
{
   cp();
    //sieve();
    //w(x)
    {
        de(n);
        ll a[n];
        union_find dsu(N);
        re(i,n)
        cin>>a[i];
        for(ll i=0;i< (n/2) ;i++)
        {
            dsu.un(a[i],a[n-1-i]);
        }
        cout<<dsu.sq();
    }

}