#include <bits/stdc++.h>
using namespace std;
//ofstream cout("output.out");

#define fast() {ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);}
#define pb push_back
#define vi vector<int>
#define vl vector<ll>					
#define vii vector<vector<int>>
#define mii map<int, int>
#define pii pair<int, int>
#define qii priority_que<int, vector<int>, greater<int>>				
#define For(i, n) for(int i = 0; i < n; ++i)
#define For1(i, n) for(int i = 1; i <= n; ++i)
#define Forlr(i, l, r) for(int i = l; i <= r; ++i)
#define Forrl(i, r, l) for(int i = r; i >= l; --i)
#define o(a) { cout << #a << ":" << (a) <<" ";}
#define ov(a) {For(i, a.size()) cout << a[i] <<" ";}
#define ovv(a) {For(i, a.size()) {For(j, a[i].size()) cout << a[i][j] <<" ";cout <<"\n";}}
using ll = long long;
int n, m, k, q;
const int INF = 1e9 + 5;
const int nax = 1e5 + 5;
pair<int, int> a[5 * nax];
int g[1505][1505];
ll rs = 0;
void dfs(int x, int y){
	int nx = x, ny = y;
	if(!g[nx][ny]) rs ++, g[nx][ny] = 3;
	while(1){
		nx ++;
		if(nx <= n && g[nx][ny] != 1 && g[nx][ny] != 3){
			if(!g[nx][ny]) rs ++;
			g[nx][ny] = 1;
		}
		else{
			break;
		}
	}
	nx = x;
	while(1){
		nx --;
		if(nx >= 1 && g[nx][ny] != 1 && g[nx][ny] != 3){
			if(!g[nx][ny]) rs ++;
			g[nx][ny] = 1;
		}
		else{
			break;
		}
	}
	nx = x;
	while(1){
		ny ++;
		if(ny <= m && g[nx][ny] != 3  && g[nx][ny] != 2){
			if(!g[nx][ny]) rs ++;
			g[nx][ny] = 2;
		}
		else{
			break;
		}
	}
	ny = y;
	while(1){
		ny --;
		if(ny >= 1 && g[nx][ny] != 3  && g[nx][ny] != 2){
			if(!g[nx][ny]) rs ++;
			g[nx][ny] = 2;
		}
		else{
			break;
		}
	}
}
int main()
{
	fast();
	cin >> n >> m;
	int na, nb;
	cin  >> na >> nb;
	For(i, na){
		cin >> a[i].first >> a[i].second;
	}
	For(i, nb){
		int x, y;
		cin >> x >> y;
		g[x][y] = 3;
	}
	For(i, na){
		dfs(a[i].first, a[i].second);
	}
	// For(i, n){
	// 	For(j, m){
	// 		cout << g[i + 1][j + 1] <<" "; 
	// 	}
	// 	cout <<"\n";
	// }
	cout << rs;
}
#include<bits/stdc++.h>

using namespace std;
using ll = long long;
using pint = pair<ll,ll>;
const ll INF = 1e18;

ll N, M, S, T;
vector<tuple<ll,ll,ll,ll>> edge;


//経路復元なしDijkstra法
vector<ll> dijkstra(ll start, const vector<vector<pair<ll,ll>>>& Hen){

	ll N = Hen.size();
	vector<ll> dist(N, INF);
	dist[start] = 0;
	priority_queue<pair<ll,ll>, vector<pair<ll,ll>>, greater<pair<ll,ll>>> que;
	que.push({0, start});
	while(que.size()) {
		ll ver = que.top().second;
		ll cost = que.top().first; que.pop();
		if(cost != dist[ver])continue;

		for(auto i : Hen[ver]) {
			auto [u, v, t, k] = edge[i.second]; //t := 長さ, k := インターバル
			auto req = cost + (k - cost % k) % k + t;

			if(dist[i.first] > req) {
				dist[i.first] = req;
				que.push({dist[i.first], i.first});
			}
		}
	}
	return dist;
}

int main()
{
	cin >> N >> M >> S >> T;
	edge.resize(M);
	vector<vector<pair<ll,ll>>> hen(N);
	S--,T--;
	for(ll i = 0; i < M; i++) {
		ll u, v, t, k ;cin >> u >> v >> t >> k;
		u--,v--;
		hen[u].push_back({v, i});
		hen[v].push_back({u, i});
		edge[i] = {u, v, t, k};
	}

	auto dist = dijkstra(S, hen);
	cout << (dist[T] == INF ? -1 : dist[T])<< endl;
	
	
}