#include <vector>
#include <array>
#include <stack>
#include <queue>
#include <list>
#include <bitset>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <algorithm>
#include <numeric>
#include <iostream>
#include <iomanip>
#include <string>
#include <chrono>
#include <random>
#include <cmath>
#include <cassert>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <functional>
#include <sstream>

using namespace std;


int main(int argc, char** argv) {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(12);


    int n;
    cin >> n;

    vector<pair<int,int>> S(n);
    vector<pair<int,int>> T(n);

    for (int i = 0; i < n; ++i) {
        cin >> S[i].first >> S[i].second;
    }
    for (int i = 0; i < n; ++i) {
        cin >> T[i].first >> T[i].second;
    }

    auto dis2 = [&](const pair<int,int>& P) {
        long long x = P.first, y = P.second;
        return x * x + y * y;
    };

    auto dis = [&](const pair<int,int>& A, const pair<int,int>& B) {
        long long x = A.first - B.first;
        long long y = A.second - B.second;
        return x * x + y * y;
    };

    auto crossProduct = [&](pair<int,int>& A, pair<int,int>& B) {
        return A.first * B.second - A.second * B.first;
    };

    auto cmp = [&](const pair<int,int>& l, const pair<int,int>& r) {
        auto L = atan2(l.second, l.first);
        auto R = atan2(r.second, r.first);
        if (L == R) {
            return dis2(l) < dis2(r);
        } else {
            return L < R;
        }
    };
    auto build = [&](int s, vector<pair<int,int>>& P) {
        int n = P.size();
        vector<pair<int,int>> res;
        for (int i = 0; i < n; ++i) {
            if (i == s) {
                continue;
            }
            int x = P[i].first - P[s].first;
            int y = P[i].second - P[s].second;
            res.emplace_back(x, y);
        }
        sort(res.begin(), res.end(), cmp);
        return res;
    };



    auto check = [&](vector<pair<int,int>>& A, vector<pair<int,int>>& B) {
        int n = A.size();
        if (n == 0) {
            return true;
        }
        for (int i = 0; i < n; ++i) {
            if (dis2(A[0]) != dis2(B[i])) {
                continue;
            }
            bool ok = true;
            for (int j = 1; j < n; ++j) {
                int k = (i + j) % n;
                if (dis2(A[j]) != dis2(B[k])) {
                    ok = false;
                }
                if (dis(A[j], A[0]) != dis(B[k], B[i])) {
                    ok = false;
                }
                if (crossProduct(A[j], A[0]) != crossProduct(B[k], B[i])) {
                    ok = false;
                }
                if (!ok) {
                    break;
                }
            }
            if (ok) {
                // for (auto& p : A) {
                //     cout << p.first << ',' << p.second << endl;
                // }
                // cout << i << " " << endl;
                // for (auto& p : B) {
                //     cout << p.first << "," << p.second << endl;
                // }
                // cout << "-----" <<endl;
                return true;
            }
        }
        return false;
    };

    bool res = false;
    for (int i = 0; i < n; ++i) {
        auto A = build(i, S);
        for (int j = 0; j < n; ++j) {
            auto B = build(j, T);
            if (check(A, B)) {
                res = true;
                break;
            }      
        }
        if (res) {
            break;
        }
    }

    if (res) {
        cout << "Yes\n";
    } else {
        cout << "No\n";
    }

    return 0;
}
#include <bits/stdc++.h>
#define lc (o<<1)
#define rc ((o<<1)|1)
using namespace std;
#define DebugP(x) cout << "Line" << __LINE__ << " " << #x << "=" << x << endl

typedef long long LL;
typedef complex<double> Comp;

const int maxn = 5e5 + 5;
const int inf = 0x3f3f3f3f;
const int modu = 1e9 + 7;

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

template<class T, class ...U> void read(T &x, U& ... u) { read(x); read(u...); }

struct Edge {
	int u, v;
	LL T, K;
	Edge(int u=0, int v=0, LL T=0, LL K=0):
		u(u), v(v), T(T), K(K) {}
};

vector<Edge> edges;
vector<int> G[maxn];

int n, m, x, y;

void addEdge(int u, int v, LL T, LL K) {
	edges.push_back(Edge(u, v, T, K));
	G[u].push_back(edges.size()-1);
}

LL dist[maxn];

struct Node {
	LL d;
	int id;
	Node(LL d=0, int id=0):
		d(d), id(id) {}
	bool operator<(const Node &op) const {
		return d > op.d;
	}
};

priority_queue<Node> Q;
bool vis[maxn];

int main() {
	// freopen("input.txt", "r", stdin);
	read(n, m, x, y);
	for (int i = 0; i < m; ++i) {
		int a, b, c, d;
		read(a, b, c, d);
		addEdge(a, b, c, d);
		addEdge(b, a, c, d);
	}
	memset(vis, 0, sizeof(vis));
	memset(dist, 0x3f, sizeof(dist));
	dist[x] = 0;
	Q.push(Node(dist[x], x));
	while (!Q.empty()) {
		while (!Q.empty() && vis[Q.top().id]) Q.pop();
		if (Q.empty()) break;
		int u = Q.top().id;
		Q.pop();
		vis[u] = 1;
		for (int i: G[u]) {
			Edge &e = edges[i];
			if (dist[e.v] > (dist[u]/e.K + (dist[u]%e.K > 0))*e.K + e.T) {
				dist[e.v] = (dist[u]/e.K + (dist[u]%e.K > 0))*e.K + e.T;
				Q.push(Node(dist[e.v], e.v));
			}
		}
	}
	if (dist[0] == dist[y]) printf("-1\n");
	else printf("%lld\n", dist[y]);
	return 0;
}