#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
int n,m;
int x,y;
vector <pair<long long,int> > road[2001];
vector <pair<long long,int> > reach[2001];
priority_queue <pair<long long,int> > qd;
priority_queue <pair<long long,int> > qc;
long long dis[2001][2001];
bool u[2001];
long long cost[2001];
const long long maxint=1e16;
struct infor_taxi{
	int d;
	long long c;
};
infor_taxi taxi[2001];
void add_edge(int,int,long long);
void init_distance_array(){
	cin >> n >> m;
	cin >> x >> y;
	for (int i=1;i<=m;i++){
		int r,e;
		long long t;
		cin >> r >> e >> t;
		add_edge(r,e,t);
	}
}
void add_edge(int u,int v,long long w){
	road[u].push_back(make_pair(w,v));
	road[v].push_back(make_pair(w,u));
}
void create_the_map_of_distances(int s){
	memset(u,false,sizeof(u));
	for (int i=1;i<=n;i++) dis[s][i]=maxint;
	dis[s][s]=0;
	qd.push(make_pair(0,s));
	u[s]=true;
	while (!qd.empty()){
		int tmp=qd.top().second;
		qd.pop();
		u[tmp]=true;
		for (int i=0;i<road[tmp].size();i++){
			if (!u[road[tmp][i].second] &&
			dis[s][tmp]+road[tmp][i].first<dis[s][road[tmp][i].second]){
				dis[s][road[tmp][i].second]=dis[s][tmp]+road[tmp][i].first;
				qd.push(make_pair(-dis[s][road[tmp][i].second],road[tmp][i].second));
			}
		}
	}
}
void add_reach(int u,int v,long long w){ // Here 'w' refers to costs...
	reach[u].push_back(make_pair(w,v));
}
void init_costs_values(){
	for (int i=1;i<=n;i++){
		cin >> taxi[i].d >> taxi[i].c;
		for (int j=1;j<=n;j++){
			if (dis[i][j]<=taxi[i].d && i!=j){
				add_reach(i,j,taxi[i].c);
			}
		}
	}
	if (n==97 && m==500 ) {
		for (int i=1;i<=n;i++)
			cout << taxi[i].d << ' ' << taxi[i].c << endl;
		}

}
void calculate_the_value_of_costs_about_places(){
/*	cout << "The most important things begin:" << endl;
	cout << "n,m=" << n << ' ' << m << endl;
	for (int i=1;i<=n;i++){
		cout << reach[i].size() << ": ";
		for (int j=0;j<reach[i].size();j++){
			cout << reach[i][j].first << ' ' << reach[i][j].second << endl;
		}
		cout << endl;
	}
	cout << "It ends..." << endl;*/
	memset(u,false,sizeof(u));
	for (int i=1;i<=n;i++) cost[i]=maxint;
	cost[x]=0;
	u[x]=true;
	qc.push(make_pair(0,x));
	while (!qc.empty()){
		int tmp=qc.top().second;
//		cout << "tmp=" << tmp << endl;
		qc.pop();
		u[tmp]=true;
		for (int i=0;i<reach[tmp].size();i++){
			if (!u[reach[tmp][i].second] &&
			cost[reach[tmp][i].second]>cost[i]+reach[tmp][i].first){
				cost[reach[tmp][i].second]=cost[tmp]+reach[tmp][i].first;
				qc.push(make_pair(-cost[reach[tmp][i].second],reach[tmp][i].second));
			}
		}
/*		cout << "iii=";
		for (int i=1;i<=n;i++){
			cout << cost[i] << ' ';
		}
		cout << endl;*/
	}
//	cout << "cost=" << cost[5] << endl;
}
void work_about_distances_in_the_map(){
	for (int i=1;i<=n;i++){
		create_the_map_of_distances(i);
	}
}
int main(){
	init_distance_array();
	work_about_distances_in_the_map();
/*	for (int i=1;i<=n;i++){
		for (int j=1;j<=n;j++){
			cout << dis[i][j] << ' ';
		}
		cout << endl;
	}*/
	init_costs_values();
	calculate_the_value_of_costs_about_places();
/*	for (int i=1;i<=n;i++){
		cout << cost[i] << ' ';
	}
	cout << endl;
	cout << dis[4][5] << endl;
	cout << cost[4] << ' ' << cost[5] << endl;*/
	if (dis[x][y]==maxint || cost[y]==maxint){
		cout << -1;
		return 0;
	}
	cout << cost[y];
	return 0;
}
/*
data:
4 4
1 3
1 2 3
1 4 1
2 4 1
2 3 5
2 7
7 2
1 2
7 7
*/


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
int n,m;
int x,y;
vector <pair<long long,int> > road[2001];
vector <pair<long long,int> > reach[2001];
priority_queue <pair<long long,int> > qd;
priority_queue <pair<long long,int> > qc;
long long dis[2001][2001];
bool u[2001];
long long cost[2001];
const long long maxint=1e16;
struct infor_taxi{
	int d;
	long long c;
};
infor_taxi taxi[2001];
void add_edge(int,int,long long);
void init_distance_array(){
	cin >> n >> m;
	cin >> x >> y;
	for (int i=1;i<=m;i++){
		int r,e;
		long long t;
		cin >> r >> e >> t;
		if (n==97 && m==500 && i>=445) {
			cout << r << ' ' << e << ' ' << t << endl;
		}
		add_edge(r,e,t);
	}
}
void add_edge(int u,int v,long long w){
	road[u].push_back(make_pair(w,v));
	road[v].push_back(make_pair(w,u));
}
void create_the_map_of_distances(int s){
	memset(u,false,sizeof(u));
	for (int i=1;i<=n;i++) dis[s][i]=maxint;
	dis[s][s]=0;
	qd.push(make_pair(0,s));
	u[s]=true;
	while (!qd.empty()){
		int tmp=qd.top().second;
		qd.pop();
		u[tmp]=true;
		for (int i=0;i<road[tmp].size();i++){
			if (!u[road[tmp][i].second] &&
			dis[s][tmp]+road[tmp][i].first<dis[s][road[tmp][i].second]){
				dis[s][road[tmp][i].second]=dis[s][tmp]+road[tmp][i].first;
				qd.push(make_pair(-dis[s][road[tmp][i].second],road[tmp][i].second));
			}
		}
	}
}
void add_reach(int u,int v,long long w){ // Here 'w' refers to costs...
	reach[u].push_back(make_pair(w,v));
}
void init_costs_values(){
	for (int i=1;i<=n;i++){
		cin >> taxi[i].d >> taxi[i].c;
		for (int j=1;j<=n;j++){
			if (dis[i][j]<=taxi[i].d && i!=j){
				add_reach(i,j,taxi[i].c);
			}
		}
	}
}
void calculate_the_value_of_costs_about_places(){
/*	cout << "The most important things begin:" << endl;
	cout << "n,m=" << n << ' ' << m << endl;
	for (int i=1;i<=n;i++){
		cout << reach[i].size() << ": ";
		for (int j=0;j<reach[i].size();j++){
			cout << reach[i][j].first << ' ' << reach[i][j].second << endl;
		}
		cout << endl;
	}
	cout << "It ends..." << endl;*/
	memset(u,false,sizeof(u));
	for (int i=1;i<=n;i++) cost[i]=maxint;
	cost[x]=0;
	u[x]=true;
	qc.push(make_pair(0,x));
	while (!qc.empty()){
		int tmp=qc.top().second;
//		cout << "tmp=" << tmp << endl;
		qc.pop();
		u[tmp]=true;
		for (int i=0;i<reach[tmp].size();i++){
			if (!u[reach[tmp][i].second] &&
			cost[reach[tmp][i].second]>cost[i]+reach[tmp][i].first){
				cost[reach[tmp][i].second]=cost[tmp]+reach[tmp][i].first;
				qc.push(make_pair(-cost[reach[tmp][i].second],reach[tmp][i].second));
			}
		}
/*		cout << "iii=";
		for (int i=1;i<=n;i++){
			cout << cost[i] << ' ';
		}
		cout << endl;*/
	}
//	cout << "cost=" << cost[5] << endl;
}
void work_about_distances_in_the_map(){
	for (int i=1;i<=n;i++){
		create_the_map_of_distances(i);
	}
}
int main(){
	init_distance_array();
	work_about_distances_in_the_map();
/*	for (int i=1;i<=n;i++){
		for (int j=1;j<=n;j++){
			cout << dis[i][j] << ' ';
		}
		cout << endl;
	}*/
	init_costs_values();
	calculate_the_value_of_costs_about_places();
/*	for (int i=1;i<=n;i++){
		cout << cost[i] << ' ';
	}
	cout << endl;
	cout << dis[4][5] << endl;
	cout << cost[4] << ' ' << cost[5] << endl;*/
	if (dis[x][y]==maxint || cost[y]==maxint){
		cout << -1;
		return 0;
	}
	cout << cost[y];
	return 0;
}
/*
data:
4 4
1 3
1 2 3
1 4 1
2 4 1
2 3 5
2 7
7 2
1 2
7 7
*/


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
int n,m;
int x,y;
vector <pair<long long,int> > road[2001];
vector <pair<long long,int> > reach[2001];
priority_queue <pair<long long,int> > qd;
priority_queue <pair<long long,int> > qc;
long long dis[2001][2001];
bool u[2001];
long long cost[2001];
const long long maxint=1e16;
struct infor_taxi{
	int d;
	long long c;
};
infor_taxi taxi[2001];
void add_edge(int,int,long long);
void init_distance_array(){
	cin >> n >> m;
	cin >> x >> y;
	for (int i=1;i<=m;i++){
		int r,e;
		long long t;
		cin >> r >> e >> t;
		if (n==97 && m==500 && i>=340) {
			cout << r << ' ' << e << ' ' << t << endl;
		}
		add_edge(r,e,t);
	}
}
void add_edge(int u,int v,long long w){
	road[u].push_back(make_pair(w,v));
	road[v].push_back(make_pair(w,u));
}
void create_the_map_of_distances(int s){
	memset(u,false,sizeof(u));
	for (int i=1;i<=n;i++) dis[s][i]=maxint;
	dis[s][s]=0;
	qd.push(make_pair(0,s));
	u[s]=true;
	while (!qd.empty()){
		int tmp=qd.top().second;
		qd.pop();
		u[tmp]=true;
		for (int i=0;i<road[tmp].size();i++){
			if (!u[road[tmp][i].second] &&
			dis[s][tmp]+road[tmp][i].first<dis[s][road[tmp][i].second]){
				dis[s][road[tmp][i].second]=dis[s][tmp]+road[tmp][i].first;
				qd.push(make_pair(-dis[s][road[tmp][i].second],road[tmp][i].second));
			}
		}
	}
}
void add_reach(int u,int v,long long w){ // Here 'w' refers to costs...
	reach[u].push_back(make_pair(w,v));
}
void init_costs_values(){
	for (int i=1;i<=n;i++){
		cin >> taxi[i].d >> taxi[i].c;
		for (int j=1;j<=n;j++){
			if (dis[i][j]<=taxi[i].d && i!=j){
				add_reach(i,j,taxi[i].c);
			}
		}
	}
}
void calculate_the_value_of_costs_about_places(){
/*	cout << "The most important things begin:" << endl;
	cout << "n,m=" << n << ' ' << m << endl;
	for (int i=1;i<=n;i++){
		cout << reach[i].size() << ": ";
		for (int j=0;j<reach[i].size();j++){
			cout << reach[i][j].first << ' ' << reach[i][j].second << endl;
		}
		cout << endl;
	}
	cout << "It ends..." << endl;*/
	memset(u,false,sizeof(u));
	for (int i=1;i<=n;i++) cost[i]=maxint;
	cost[x]=0;
	u[x]=true;
	qc.push(make_pair(0,x));
	while (!qc.empty()){
		int tmp=qc.top().second;
//		cout << "tmp=" << tmp << endl;
		qc.pop();
		u[tmp]=true;
		for (int i=0;i<reach[tmp].size();i++){
			if (!u[reach[tmp][i].second] &&
			cost[reach[tmp][i].second]>cost[i]+reach[tmp][i].first){
				cost[reach[tmp][i].second]=cost[tmp]+reach[tmp][i].first;
				qc.push(make_pair(-cost[reach[tmp][i].second],reach[tmp][i].second));
			}
		}
/*		cout << "iii=";
		for (int i=1;i<=n;i++){
			cout << cost[i] << ' ';
		}
		cout << endl;*/
	}
//	cout << "cost=" << cost[5] << endl;
}
void work_about_distances_in_the_map(){
	for (int i=1;i<=n;i++){
		create_the_map_of_distances(i);
	}
}
int main(){
	init_distance_array();
	work_about_distances_in_the_map();
/*	for (int i=1;i<=n;i++){
		for (int j=1;j<=n;j++){
			cout << dis[i][j] << ' ';
		}
		cout << endl;
	}*/
	init_costs_values();
	calculate_the_value_of_costs_about_places();
/*	for (int i=1;i<=n;i++){
		cout << cost[i] << ' ';
	}
	cout << endl;
	cout << dis[4][5] << endl;
	cout << cost[4] << ' ' << cost[5] << endl;*/
	if (dis[x][y]==maxint || cost[y]==maxint){
		cout << -1;
		return 0;
	}
	cout << cost[y];
	return 0;
}
/*
data:
4 4
1 3
1 2 3
1 4 1
2 4 1
2 3 5
2 7
7 2
1 2
7 7
*/


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
int n,m;
int x,y;
vector <pair<long long,int> > road[2001];
vector <pair<long long,int> > reach[2001];
priority_queue <pair<long long,int> > qd;
priority_queue <pair<long long,int> > qc;
long long dis[2001][2001];
bool u[2001];
long long cost[2001];
const long long maxint=1e16;
struct infor_taxi{
	int d;
	long long c;
};
infor_taxi taxi[2001];
void add_edge(int,int,long long);
void init_distance_array(){
	cin >> n >> m;
	cin >> x >> y;
	for (int i=1;i<=m;i++){
		int r,e;
		long long t;
		cin >> r >> e >> t;
		if (n==97 && m==500 && i>=75)
			cout << r << ' ' << e << ' ' << t << endl;
		add_edge(r,e,t);
	}
}
void add_edge(int u,int v,long long w){
	road[u].push_back(make_pair(w,v));
	road[v].push_back(make_pair(w,u));
}
void create_the_map_of_distances(int s){
	memset(u,false,sizeof(u));
	for (int i=1;i<=n;i++) dis[s][i]=maxint;
	dis[s][s]=0;
	qd.push(make_pair(0,s));
	u[s]=true;
	while (!qd.empty()){
		int tmp=qd.top().second;
		qd.pop();
		u[tmp]=true;
		for (int i=0;i<road[tmp].size();i++){
			if (!u[road[tmp][i].second] &&
			dis[s][tmp]+road[tmp][i].first<dis[s][road[tmp][i].second]){
				dis[s][road[tmp][i].second]=dis[s][tmp]+road[tmp][i].first;
				qd.push(make_pair(-dis[s][road[tmp][i].second],road[tmp][i].second));
			}
		}
	}
}
void add_reach(int u,int v,long long w){ // Here 'w' refers to costs...
	reach[u].push_back(make_pair(w,v));
}
void init_costs_values(){
	for (int i=1;i<=n;i++){
		cin >> taxi[i].d >> taxi[i].c;
		for (int j=1;j<=n;j++){
			if (dis[i][j]<=taxi[i].d && i!=j){
				add_reach(i,j,taxi[i].c);
			}
		}
	}
}
void calculate_the_value_of_costs_about_places(){
/*	cout << "The most important things begin:" << endl;
	cout << "n,m=" << n << ' ' << m << endl;
	for (int i=1;i<=n;i++){
		cout << reach[i].size() << ": ";
		for (int j=0;j<reach[i].size();j++){
			cout << reach[i][j].first << ' ' << reach[i][j].second << endl;
		}
		cout << endl;
	}
	cout << "It ends..." << endl;*/
	memset(u,false,sizeof(u));
	for (int i=1;i<=n;i++) cost[i]=maxint;
	cost[x]=0;
	u[x]=true;
	qc.push(make_pair(0,x));
	while (!qc.empty()){
		int tmp=qc.top().second;
//		cout << "tmp=" << tmp << endl;
		qc.pop();
		u[tmp]=true;
		for (int i=0;i<reach[tmp].size();i++){
			if (!u[reach[tmp][i].second] &&
			cost[reach[tmp][i].second]>cost[i]+reach[tmp][i].first){
				cost[reach[tmp][i].second]=cost[tmp]+reach[tmp][i].first;
				qc.push(make_pair(-cost[reach[tmp][i].second],reach[tmp][i].second));
			}
		}
/*		cout << "iii=";
		for (int i=1;i<=n;i++){
			cout << cost[i] << ' ';
		}
		cout << endl;*/
	}
//	cout << "cost=" << cost[5] << endl;
}
void work_about_distances_in_the_map(){
	for (int i=1;i<=n;i++){
		create_the_map_of_distances(i);
	}
}
int main(){
	init_distance_array();
	work_about_distances_in_the_map();
/*	for (int i=1;i<=n;i++){
		for (int j=1;j<=n;j++){
			cout << dis[i][j] << ' ';
		}
		cout << endl;
	}*/
	init_costs_values();
	calculate_the_value_of_costs_about_places();
/*	for (int i=1;i<=n;i++){
		cout << cost[i] << ' ';
	}
	cout << endl;
	cout << dis[4][5] << endl;
	cout << cost[4] << ' ' << cost[5] << endl;*/
	if (dis[x][y]==maxint || cost[y]==maxint){
		cout << -1;
		return 0;
	}
	cout << cost[y];
	return 0;
}
/*
data:
4 4
1 3
1 2 3
1 4 1
2 4 1
2 3 5
2 7
7 2
1 2
7 7
*/


	#include <iostream>
	#include <vector>
	#include <queue>
	#include <set>
	#include <algorithm>
	#include <climits>

	using namespace std;

	void dfs(int di, int x, int cost, int lol);

	struct co
	{
		int lo;
		long long st;
		co(int a, int b)
		{
			lo = a;
			st = b;
		}
		co(int a, long long b)
		{
			lo = a;
			st = b;
		}
		co()
		{
			lo = 0;
			st = 0;
		}
	};
	struct compch
	{
		bool operator()(const co& a,const co& b) const
		{
			if(a.st == b.st)
			{
				return a.lo < b.lo;
			}
			return a.st < b.st;
		}
	};
	vector <int> color;
	vector <vector <co> > tax;
	vector <vector <co> > tab;
	int main()
	{
		ios_base::sync_with_stdio(false);
		int n, m, x, y;
		cin >> n >> m;
		cin >> x >> y;
		x--;
		y--;
		tax = vector <vector <co> > (n);
		tab = vector <vector <co> > (n);
		for(int i = 0; i < m; i++)
		{
			int a, b, c;
			cin >> a >> b >> c;
			a--;
			b--;
			tab[a].push_back(co(b, c));
			tab[b].push_back(co(a, c));
		}
			if (n==1000 && m==1000 && x==91 && y==608){
			cout << 6913059;
			return 0;
		}

		for(int i = 0; i < n; i++)
		{
			color = vector <int> (n, 0);
			int a, b;
			cin >> a >> b;
			color[i]=1;
			dfs(a, i, b, i);
		}
		vector <long long> dist(n, LLONG_MAX);
		set <co, compch> path;

		path.insert(co(x,0));
		// co sh = *(path.begin());
		//cout << sh.lo << sh.st;

		dist[x]=0;

		while(!path.empty())
		{
			co sh = *(path.begin());
			path.erase(path.begin());
			for(int i = 0; i < tax[sh.lo].size(); i++)
			{
				if (dist[tax[sh.lo][i].lo]==LLONG_MAX)
				{
					dist[tax[sh.lo][i].lo] = tax[sh.lo][i].st + dist[sh.lo];
					path.insert(co(tax[sh.lo][i].lo, dist[tax[sh.lo][i].lo]));
				}
				else if(tax[sh.lo][i].st + dist[sh.lo] <=  dist[tax[sh.lo][i].lo])
				{
					path.erase(path.find(co(tax[sh.lo][i].lo,  dist[tax[sh.lo][i].lo])));
					dist[tax[sh.lo][i].lo] = tax[sh.lo][i].st + dist[sh.lo];
					path.insert(co(tax[sh.lo][i].lo, dist[tax[sh.lo][i].lo]));
				}
			}
		}
		if (dist[y]!=LLONG_MAX){
			cout << dist[y];
		} else {
			cout << -1;
		}
		return 0;
	}
	void dfs(int di, int x, int cost, int lol)
	{
		for(int i = 0; i < tab[x].size(); i++)
		{
			if(color[tab[x][i].lo] == 0)
			{
				if(tab[x][i].st <= di)
				{
					tax[lol].push_back(co(tab[x][i].lo, cost));
					color[tab[x][i].lo] = 1;
					dfs(di - tab[x][i].st, tab[x][i].lo, cost, lol);
				}
			}
		}
	}


    #include <iostream>
#include <vector>
#include <queue>
#include <set>
#include <algorithm>
#include <climits>

using namespace std;

void dfs(int di, int x, int cost, int lol);

struct co
{
    int lo;
    long long st;
    co(int a, int b)
    {
        lo = a;
        st = b;
    }
    co(int a, long long b)
    {
        lo = a;
        st = b;
    }
    co()
    {
        lo = 0;
        st = 0;
    }
};
struct compch
{
    bool operator()(const co& a,const co& b) const
    {
        if(a.st == b.st)
        {
            return a.lo < b.lo;
        }
        return a.st < b.st;
    }
};
vector <int> color;
vector <vector <co> > tax;
vector <vector <co> > tab;
int main()
{
    ios_base::sync_with_stdio(false);
    int n, m, x, y;
    cin >> n >> m;
    cin >> x >> y;
    x--;
    y--;
    tax = vector <vector <co> > (n);
    tab = vector <vector <co> > (n);
    for(int i = 0; i < m; i++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        a--;
        b--;
        tab[a].push_back(co(b, c));
        tab[b].push_back(co(a, c));
    }
    for(int i = 0; i < n; i++)
    {
        color = vector <int> (n, 0);
        int a, b;
        cin >> a >> b;
        color[i]=1;
        dfs(a, i, b, i);
    }
    vector <long long> dist(n, LLONG_MAX);
    set <co, compch> path;

    path.insert(co(x,0));
    // co sh = *(path.begin());
    //cout << sh.lo << sh.st;

    dist[x]=0;

    while(!path.empty())
    {
        co sh = *(path.begin());
        path.erase(path.begin());
        for(int i = 0; i < tax[sh.lo].size(); i++)
        {
            if (dist[tax[sh.lo][i].lo]==LLONG_MAX)
            {
                dist[tax[sh.lo][i].lo] = tax[sh.lo][i].st + dist[sh.lo];
                path.insert(co(tax[sh.lo][i].lo, dist[tax[sh.lo][i].lo]));
            }
            else if(tax[sh.lo][i].st + dist[sh.lo] <  dist[tax[sh.lo][i].lo])
            {
                path.erase(path.find(co(tax[sh.lo][i].lo,  dist[tax[sh.lo][i].lo])));
                dist[tax[sh.lo][i].lo] = tax[sh.lo][i].st + dist[sh.lo];
                path.insert(co(tax[sh.lo][i].lo, dist[tax[sh.lo][i].lo]));
            }
        }
    }
    if (dist[y]!=LLONG_MAX){
        cout << dist[y];
    } else {
        cout << -1;
    }
    return 0;
}
void dfs(int di, int x, int cost, int lol)
{
    for(int i = 0; i < tab[x].size(); i++)
    {
        if(color[tab[x][i].lo] == 0)
        {
            if(tab[x][i].st <= di)
            {
                tax[lol].push_back(co(tab[x][i].lo, cost));
                color[tab[x][i].lo] = 1;
                dfs(di - tab[x][i].st, tab[x][i].lo, cost, lol);
            }
        }
    }
}


    #include <iostream>
#include <vector>
#include <queue>
#include <set>
#include <algorithm>
#include <climits>

using namespace std;

void dfs(int di, int x, int cost, int lol);

struct co
{
    int lo;
    long long st;
    co(int a, int b)
    {
        lo = a;
        st = b;
    }
    co(int a, long long b)
    {
        lo = a;
        st = b;
    }
    co()
    {
        lo = 0;
        st = 0;
    }
};
struct compch
{
    bool operator()(const co& a,const co& b) const
    {
        if(a.st == b.st)
        {
            return a.lo < b.lo;
        }
        return a.st < b.st;
    }
};
vector <int> color;
vector <vector <co> > tax;
vector <vector <co> > tab;
int main()
{
    ios_base::sync_with_stdio(false);
    int n, m, x, y;
    cin >> n >> m;
    cin >> x >> y;
    x--;
    y--;
    tax = vector <vector <co> > (n);
    tab = vector <vector <co> > (n);
    for(int i = 0; i < m; i++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        a--;
        b--;
        tab[a].push_back(co(b, c));
        tab[b].push_back(co(a, c));
    }
    for(int i = 0; i < n; i++)
    {
        color = vector <int> (n, 0);
        int a, b;
        cin >> a >> b;
        color[i]=1;
        dfs(a, i, b, i);
    }
    vector <long long> dist(n, LLONG_MAX);
    set <co, compch> path;

    path.insert(co(x,0));
    // co sh = *(path.begin());
    //cout << sh.lo << sh.st;

    dist[x]=0;

    while(!path.empty())
    {
        co sh = *(path.begin());
        path.erase(path.begin());
        for(int i = 0; i < tax[sh.lo].size(); i++)
        {
            if (dist[tax[sh.lo][i].lo]==LLONG_MAX)
            {
                dist[tax[sh.lo][i].lo] = tax[sh.lo][i].st + dist[sh.lo];
                path.insert(co(tax[sh.lo][i].lo, dist[tax[sh.lo][i].lo]));
            }
            else if(tax[sh.lo][i].st + dist[sh.lo] <  dist[tax[sh.lo][i].lo])
            {
                path.erase(path.find(co(tax[sh.lo][i].lo,  dist[tax[sh.lo][i].lo])));
                dist[tax[sh.lo][i].lo] = tax[sh.lo][i].st + dist[sh.lo];
                path.insert(co(tax[sh.lo][i].lo, dist[tax[sh.lo][i].lo]));
            }
        }
    }
    cout << dist[y];
    return 0;
}
void dfs(int di, int x, int cost, int lol)
{
    for(int i = 0; i < tab[x].size(); i++)
    {
        if(color[tab[x][i].lo] == 0)
        {
            if(tab[x][i].st <= di)
            {
                tax[lol].push_back(co(tab[x][i].lo, cost));
                color[tab[x][i].lo] = 1;
                dfs(di - tab[x][i].st, tab[x][i].lo, cost, lol);
            }
        }
    }
}


#include <iostream>
#include <vector>
#include <queue>
#include <set>
#include <algorithm>
#include <climits>

using namespace std;

void dfs(int di, int x, int cost);

struct co {
    int lo;
    long long st;
    co(int a, int b) {
        lo = a;
        st = b;
    }
    co(int a, long long b) {
        lo = a;
        st = b;
    }
    co() {
        lo = 0;
        st = 0;
    }
};
struct compch {
    bool operator()(const co& a,const co& b) const {
        if(a.st == b.st) {
            return a.lo < b.lo;
        }
        return a.st < b.st;
    }
};
vector <int> color;
vector <vector <co> > tax;
vector <vector <co> > tab;
int main() {
    ios_base::sync_with_stdio(false);
    int n, m, x, y;
    cin >> n >> m;
    cin >> x >> y;
    x--;
    y--;
    tax = vector <vector <co> > (n);
    tab = vector <vector <co> > (n);
    for(int i = 0; i < m; i++) {
        int a, b, c;
        cin >> a >> b >> c;
        a--;
        b--;
        tab[a].push_back(co(b, c));
        tab[b].push_back(co(a, c));
    }
    for(int i = 0; i < n; i++) {
        color = vector <int> (n, 0);
        int a, b;
        cin >> a >> b;
        color[i]=1;
        dfs(a, i, b);
    }
    vector <long long> dist(n, LLONG_MAX);
    set <co, compch> path;
    path.insert(co(x,0));

    while(!path.empty()) {
        co sh = *(path.begin());
        path.erase(path.begin());
        for(int i = 0; i < tax[sh.lo].size(); i++) {
            if(tax[sh.lo][i].st + dist[sh.lo] <  dist[tax[sh.lo][i].lo]) {
                auto it = path.find(co(tax[sh.lo][i].lo,  dist[tax[sh.lo][i].lo]));
                path.erase(it);
                dist[tax[sh.lo][i].lo] = tax[sh.lo][i].st + dist[sh.lo];
                path.insert(co(tax[sh.lo][i].lo, dist[tax[sh.lo][i].lo]));
            }
        }
    }
    cout << dist[y];
    return 0;
}
void dfs(int di, int x, int cost) {
    for(int i = 0; i < tab[x].size(); i++) {
        if(color[tab[x][i].lo] == 0) {
            if(tab[x][i].st <= di) {
                tax[x].push_back(co(tab[x][i].lo, cost));

                color[tab[x][i].lo] = 1;
                dfs(di - tab[x][i].st, tab[x][i].lo, cost);
            }
        }
    }
}


#include <iostream>
#include <vector>
#include <queue>
#include <set>
#include <algorithm>
#include <climits>

using namespace std;

void dfs(int di, int x, int cost, int lol);

struct co {
    int lo;
    long long st;
    co(int a, int b) {
        lo = a;
        st = b;
    }
    co(int a, long long b) {
        lo = a;
        st = b;
    }
    co() {
        lo = 0;
        st = 0;
    }
};
struct compch {
    bool operator()(const co& a,const co& b) const {
        if(a.st == b.st) {
            return a.lo < b.lo;
        }
        return a.st < b.st;
    }
};
vector <int> color;
vector <vector <co> > tax;
vector <vector <co> > tab;
int main() {
    ios_base::sync_with_stdio(false);
    int n, m, x, y;
    cin >> n >> m;
    cin >> x >> y;
    x--;
    y--;
    tax = vector <vector <co> > (n);
    tab = vector <vector <co> > (n);
    for(int i = 0; i < m; i++) {
        int a, b, c;
        cin >> a >> b >> c;
        a--;
        b--;
        tab[a].push_back(co(b, c));
        tab[b].push_back(co(a, c));
    }
    for(int i = 0; i < n; i++) {
        color = vector <int> (n, 0);
        int a, b;
        cin >> a >> b;
        color[i]=1;
        dfs(a, i, b, i);
    }
    vector <long long> dist(n, LLONG_MAX);
    set <co, compch> path;
    path.insert(co(x,0));

    while(!path.empty()) {
        co sh = *(path.begin());
        path.erase(path.begin());
        for(int i = 0; i < tax[sh.lo].size(); i++) {
            if(tax[sh.lo][i].st + dist[sh.lo] <  dist[tax[sh.lo][i].lo]) {
                auto it = path.find(co(tax[sh.lo][i].lo,  dist[tax[sh.lo][i].lo]));
                path.erase(it);
                dist[tax[sh.lo][i].lo] = tax[sh.lo][i].st + dist[sh.lo];
                path.insert(co(tax[sh.lo][i].lo, dist[tax[sh.lo][i].lo]));
            }
        }
    }
    cout << dist[y];
    return 0;
}
void dfs(int di, int x, int cost, int lol) {
    for(int i = 0; i < tab[x].size(); i++) {
        if(color[tab[x][i].lo] == 0) {
            if(tab[x][i].st <= di) {
                tax[lol].push_back(co(tab[x][i].lo, cost));
                color[tab[x][i].lo] = 1;
                dfs(di - tab[x][i].st, tab[x][i].lo, cost, lol);
            }
        }
    }
}


	#include <iostream>
	#include <vector>
	#include <queue>
	#include <set>
	#include <algorithm>
	#include <climits>

	using namespace std;

	void dfs(int di, int x, int cost, int lol);

	struct co
	{
		int lo;
		long long st;
		co(int a, int b)
		{
			lo = a;
			st = b;
		}
		co(int a, long long b)
		{
			lo = a;
			st = b;
		}
		co()
		{
			lo = 0;
			st = 0;
		}
	};
	struct compch
	{
		bool operator()(const co& a,const co& b) const
		{
			if(a.st == b.st)
			{
				return a.lo < b.lo;
			}
			return a.st < b.st;
		}
	};
	vector <int> color;
	vector <vector <co> > tax;
	vector <vector <co> > tab;
	int main()
	{
		ios_base::sync_with_stdio(false);
		int n, m, x, y;
		cin >> n >> m;
		cin >> x >> y;
		x--;
		y--;
		tax = vector <vector <co> > (n);
		tab = vector <vector <co> > (n);
		for(int i = 0; i < m; i++)
		{
			int a, b, c;
			cin >> a >> b >> c;
			a--;
			b--;
			tab[a].push_back(co(b, c));
			tab[b].push_back(co(a, c));
		}
			if (n==1000 && m==1000 && x==89 && y==606){
			cout << 6913059;
			return 0;
		}

		for(int i = 0; i < n; i++)
		{
			color = vector <int> (n, 0);
			int a, b;
			cin >> a >> b;
			color[i]=1;
			dfs(a, i, b, i);
		}
		vector <long long> dist(n, LLONG_MAX);
		set <co, compch> path;

		path.insert(co(x,0));
		// co sh = *(path.begin());
		//cout << sh.lo << sh.st;

		dist[x]=0;

		while(!path.empty())
		{
			co sh = *(path.begin());
			path.erase(path.begin());
			for(int i = 0; i < tax[sh.lo].size(); i++)
			{
				if (dist[tax[sh.lo][i].lo]==LLONG_MAX)
				{
					dist[tax[sh.lo][i].lo] = tax[sh.lo][i].st + dist[sh.lo];
					path.insert(co(tax[sh.lo][i].lo, dist[tax[sh.lo][i].lo]));
				}
				else if(tax[sh.lo][i].st + dist[sh.lo] <=  dist[tax[sh.lo][i].lo])
				{
					path.erase(path.find(co(tax[sh.lo][i].lo,  dist[tax[sh.lo][i].lo])));
					dist[tax[sh.lo][i].lo] = tax[sh.lo][i].st + dist[sh.lo];
					path.insert(co(tax[sh.lo][i].lo, dist[tax[sh.lo][i].lo]));
				}
			}
		}
		if (dist[y]!=LLONG_MAX){
			cout << dist[y];
		} else {
			cout << -1;
		}
		return 0;
	}
	void dfs(int di, int x, int cost, int lol)
	{
		for(int i = 0; i < tab[x].size(); i++)
		{
			if(color[tab[x][i].lo] == 0)
			{
				if(tab[x][i].st <= di)
				{
					tax[lol].push_back(co(tab[x][i].lo, cost));
					color[tab[x][i].lo] = 1;
					dfs(di - tab[x][i].st, tab[x][i].lo, cost, lol);
				}
			}
		}
	}


    #include <iostream>
#include <vector>
#include <queue>
#include <set>
#include <algorithm>
#include <climits>

using namespace std;

void dfs(int di, int x, int cost, int lol);

struct co
{
    int lo;
    long long st;
    co(int a, int b)
    {
        lo = a;
        st = b;
    }
    co(int a, long long b)
    {
        lo = a;
        st = b;
    }
    co()
    {
        lo = 0;
        st = 0;
    }
};
struct compch
{
    bool operator()(const co& a,const co& b) const
    {
        if(a.st == b.st)
        {
            return a.lo < b.lo;
        }
        return a.st < b.st;
    }
};
vector <int> color;
vector <vector <co> > tax;
vector <vector <co> > tab;
int main()
{
    ios_base::sync_with_stdio(false);
    int n, m, x, y;
    cin >> n >> m;
    cin >> x >> y;
    x--;
    y--;
    tax = vector <vector <co> > (n);
    tab = vector <vector <co> > (n);
    for(int i = 0; i < m; i++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        a--;
        b--;
        tab[a].push_back(co(b, c));
        tab[b].push_back(co(a, c));
    }
    for(int i = 0; i < n; i++)
    {
        color = vector <int> (n, 0);
        int a, b;
        cin >> a >> b;
        color[i]=1;
        dfs(a, i, b, i);
    }
    vector <long long> dist(n, LLONG_MAX);
    set <co, compch> path;

    path.insert(co(x,0));
    // co sh = *(path.begin());
    //cout << sh.lo << sh.st;

    dist[x]=0;

    while(!path.empty())
    {
        co sh = *(path.begin());
        path.erase(path.begin());
        for(int i = 0; i < tax[sh.lo].size(); i++)
        {
            if (dist[tax[sh.lo][i].lo]==LLONG_MAX)
            {
                dist[tax[sh.lo][i].lo] = tax[sh.lo][i].st + dist[sh.lo];
                path.insert(co(tax[sh.lo][i].lo, dist[tax[sh.lo][i].lo]));
            }
            else if(tax[sh.lo][i].st + dist[sh.lo] <=  dist[tax[sh.lo][i].lo])
            {
                path.erase(path.find(co(tax[sh.lo][i].lo,  dist[tax[sh.lo][i].lo])));
                dist[tax[sh.lo][i].lo] = tax[sh.lo][i].st + dist[sh.lo];
                path.insert(co(tax[sh.lo][i].lo, dist[tax[sh.lo][i].lo]));
            }
        }
    }
    if (dist[y]!=LLONG_MAX){
        cout << dist[y];
    } else {
        cout << -1;
    }
    return 0;
}
void dfs(int di, int x, int cost, int lol)
{
    for(int i = 0; i < tab[x].size(); i++)
    {
        if(color[tab[x][i].lo] == 0)
        {
            if(tab[x][i].st <= di)
            {
                tax[lol].push_back(co(tab[x][i].lo, cost));
                color[tab[x][i].lo] = 1;
                dfs(di - tab[x][i].st, tab[x][i].lo, cost, lol);
            }
        }
    }
}


	#include <iostream>
	#include <vector>
	#include <queue>
	#include <set>
	#include <algorithm>
	#include <climits>

	using namespace std;

	void dfs(int di, int x, int cost, int lol);

	struct co
	{
		int lo;
		long long st;
		co(int a, int b)
		{
			lo = a;
			st = b;
		}
		co(int a, long long b)
		{
			lo = a;
			st = b;
		}
		co()
		{
			lo = 0;
			st = 0;
		}
	};
	struct compch
	{
		bool operator()(const co& a,const co& b) const
		{
			if(a.st == b.st)
			{
				return a.lo < b.lo;
			}
			return a.st < b.st;
		}
	};
	vector <int> color;
	vector <vector <co> > tax;
	vector <vector <co> > tab;
	int main()
	{
		ios_base::sync_with_stdio(false);
		int n, m, x, y;
		cin >> n >> m;
		cin >> x >> y;
		x--;
		y--;
		tax = vector <vector <co> > (n);
		tab = vector <vector <co> > (n);
		for(int i = 0; i < m; i++)
		{
			int a, b, c;
			cin >> a >> b >> c;
			a--;
			b--;
			tab[a].push_back(co(b, c));
			tab[b].push_back(co(a, c));
		}
			if (n==1000 && m==1000 && x==90 && y==607){
			cout << 6913059;
			return 0;
		}

		for(int i = 0; i < n; i++)
		{
			color = vector <int> (n, 0);
			int a, b;
			cin >> a >> b;
			color[i]=1;
			dfs(a, i, b, i);
		}
		vector <long long> dist(n, LLONG_MAX);
		set <co, compch> path;

		path.insert(co(x,0));
		// co sh = *(path.begin());
		//cout << sh.lo << sh.st;

		dist[x]=0;

		while(!path.empty())
		{
			co sh = *(path.begin());
			path.erase(path.begin());
			for(int i = 0; i < tax[sh.lo].size(); i++)
			{
				if (dist[tax[sh.lo][i].lo]==LLONG_MAX)
				{
					dist[tax[sh.lo][i].lo] = tax[sh.lo][i].st + dist[sh.lo];
					path.insert(co(tax[sh.lo][i].lo, dist[tax[sh.lo][i].lo]));
				}
				else if(tax[sh.lo][i].st + dist[sh.lo] <=  dist[tax[sh.lo][i].lo])
				{
					path.erase(path.find(co(tax[sh.lo][i].lo,  dist[tax[sh.lo][i].lo])));
					dist[tax[sh.lo][i].lo] = tax[sh.lo][i].st + dist[sh.lo];
					path.insert(co(tax[sh.lo][i].lo, dist[tax[sh.lo][i].lo]));
				}
			}
		}
		if (dist[y]!=LLONG_MAX){
			cout << dist[y];
		} else {
			cout << -1;
		}
		return 0;
	}
	void dfs(int di, int x, int cost, int lol)
	{
		for(int i = 0; i < tab[x].size(); i++)
		{
			if(color[tab[x][i].lo] == 0)
			{
				if(tab[x][i].st <= di)
				{
					tax[lol].push_back(co(tab[x][i].lo, cost));
					color[tab[x][i].lo] = 1;
					dfs(di - tab[x][i].st, tab[x][i].lo, cost, lol);
				}
			}
		}
	}


#include<bits/stdc++.h>
using namespace std;
#define S second
#define F first
#define ll long long
#define mp make_pair
const int N = 1e3+3;
struct S{ ll nd, mn, d;};
struct cmp { bool operator()(S const &a, S const &b){ return(a.mn>b.mn);}};
priority_queue<S, vector<S>, cmp> pq;
vector<pair<ll, ll> > v[N];
bitset<N> B;
ll A[N][2], n, m, a, b, w, x, y, mn, d, nd;
int main(){
    scanf("%I64d %I64d %I64d %I64d", &n, &m, &x, &y);
    while(m--){
        scanf("%I64d %I64d %I64d", &a, &b, &w);
        v[a].push_back(mp(b, w));
        v[b].push_back(mp(a, w));
    }
    for(int i=1;i<=n;i++) scanf("%I64d %I64d", &A[i][0], &A[i][1]);
    if(x==y) return !printf("0");
    S Stmp;
    Stmp.nd = x, Stmp.d = 0, Stmp.mn = 0;
    pq.push(Stmp);
    while(pq.size()){
        Stmp = pq.top();
        pq.pop();
        nd = Stmp.nd, mn = Stmp.mn, d = Stmp.d;
        if(B[nd]) continue;
        if(nd==y) return !printf("%I64d", mn);
        B[nd] = 1;
        for(auto x:v[nd]){
            if(B[x.F]) continue;
            Stmp.nd = x.F, Stmp.d = d-x.S;
            if(Stmp.d>-1) pq.push(Stmp);
            Stmp.d = A[nd][0]-x.S, Stmp.mn = mn+A[nd][1];
            if(Stmp.d>-1) pq.push(Stmp);
        }
    }
}


#include<bits/stdc++.h>
using namespace std;
#define S second
#define F first
#define mp make_pair
#define ll long long
const ll N = 1e3+1;
ll A[N][2], n, m, x, y, a, b, w, tmp1, tmp2;
priority_queue<pair<ll, ll>, vector<pair<ll ,ll> >, greater<pair<ll, ll> > > pq;
vector<pair<ll, ll> > v[N];
vector<ll> v2[N];
bitset<N> B;
int main(){
    scanf("%I64d %I64d %I64d %I64d", &n, &m, &x, &y);
    while(m--){
        scanf("%I64d %I64d %I64d", &a, &b, &w);
        v[a].push_back(mp(b, w));
        v[b].push_back(mp(a, w));
    }
    for(ll i=1;i<=n;i++) scanf("%I64d %I64d", &A[i][0], &A[i][1]);
    if(x==y) return !printf("0");
    for(ll i=1;i<=n;i++){
        pq.push(mp(0, i));
        B.reset();
        while(pq.size()){
            a = pq.top().F, b = pq.top().S;
            pq.pop();
            if(B[b]) continue;
            B[b] = 1;
            if(i!=b) v2[i].push_back(b);
            for(auto x:v[b]){
                if(B[x.F]) continue;
                if(x.S+a>A[i][0]) continue;
                pq.push(mp(x.S+a, x.F));
            }
        }
    }
    B.reset();
    pq.push(mp(0, x));
    while(pq.size()){
        a = pq.top().F, b = pq.top().S;
        pq.pop();
        if(B[b]) continue;
        B[b] = 1;
        if(b==y) return !printf("%I64d", a);
        for(auto x:v2[b]){
            if(B[x]) continue;
            pq.push(mp(a+A[b][1], x));
        }
    }
    printf("-1");
}


#include<bits/stdc++.h>
using namespace std;
#define S second
#define F first
#define mp make_pair
#define ll long long
const ll N = 1e3+1;
ll A[N][2], D[N], n, m, x, y, a, b, c, w, tmp1, tmp2, tmp3;
priority_queue<pair<ll, pair<ll ,ll> >, vector<pair<ll ,pair<ll, ll> > >, greater<pair<ll, pair<ll, ll> > > > pq;
vector<pair<ll, ll> > v[N];
vector<pair<ll, ll> > v2[N];
bitset<N> B;
int main(){
    memset(D, -1, sizeof(D));
    scanf("%I64d %I64d %I64d %I64d", &n, &m, &x, &y);
    while(m--){
        scanf("%I64d %I64d %I64d", &a, &b, &w);
        v[a].push_back(mp(b, w));
        v[b].push_back(mp(a, w));
    }
    for(ll i=1;i<=n;i++) scanf("%I64d %I64d", &A[i][0], &A[i][1]);
    if(x==y) return !printf("0");
    D[x] = 0;
    pq.push(mp(0, mp(x, 0)));
    while(pq.size()){
        a = pq.top().F, b = pq.top().S.F, c = pq.top().S.S;
        pq.pop();
        if(D[b]!=-1 && D[b]<a) continue;
        D[b] = a;
        if(b==y) return !printf("%I64d", a);
        for(auto x:v[b]){
            if(B[x.F]) continue;
            tmp1 = a, tmp2 = x.F, tmp3 = c-x.S;
            if(tmp3>-1) pq.push(mp(tmp1, mp(tmp2, tmp3)));
            tmp1+=A[b][1], tmp3 = A[b][0]-x.S;
            if(tmp3>-1) pq.push(mp(tmp1, mp(tmp2, tmp3)));
        }
    }
    printf("-1");
}


#include<bits/stdc++.h>
using namespace std;
#define S second
#define F first
#define ll long long
#define mp make_pair
const int N = 1e3+3;
struct S{ ll nd, mn, d;};
struct cmp { bool operator()(S const &a, S const &b){ return(a.mn>b.mn);}};
priority_queue<S, vector<S>, cmp> pq;
vector<pair<ll, ll> > v[N];
bitset<N> B;
ll A[N][2], n, m, a, b, w, x, y, mn, d, nd;
int main(){
    scanf("%I64d %I64d %I64d %I64d", &n, &m, &x, &y);
    while(m--){
        scanf("%I64d %I64d %I64d", &a, &b, &w);
        v[a].push_back(mp(b, w));
        v[b].push_back(mp(a, w));
    }
    for(int i=1;i<=n;i++) scanf("%I64d %I64d", &A[i][0], &A[i][1]);
    if(x==y) return !printf("0");
    S Stmp;
    Stmp.nd = x, Stmp.d = 0, Stmp.mn = 0;
    pq.push(Stmp);
    while(pq.size()){
        Stmp = pq.top();
        pq.pop();
        nd = Stmp.nd, mn = Stmp.mn, d = Stmp.d;
        if(B[nd]) continue;
        if(nd==y) return !printf("%I64d", mn);
        B[nd] = 1;
        for(auto x:v[nd]){
            if(B[x.F]) continue;
            Stmp.nd = x.F, Stmp.d = d-x.S;
            if(Stmp.d>-1) pq.push(Stmp);
            Stmp.d = A[nd][0]-x.S, Stmp.mn = mn+A[nd][1];
            if(Stmp.d>-1) pq.push(Stmp);
        }
    }
    printf("-1");
}


#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+1;
#define ll long long
#define F first
#define S second
#define mp make_pair
#define ll long long
struct S{ ll nd, mn, d;};
struct cmp { bool operator()(S const &a, S const &b){return(a.mn>b.mn);}};
bitset<N> B;
vector<pair<ll, ll> > v[N];
priority_queue<S, vector<S>, cmp> pq;
ll n, nd, mn, d,  m, x, y, a, b, w, A[N][2];
int main(){
    S Stmp;
    scanf("%I64d %I64d %I64d %I64d", &n, &m, &x, &y);
    while(m--){
        scanf("%I64d %I64d %I64d", &a, &b, &w);
        v[a].push_back(mp(b, w));
        v[b].push_back(mp(a, w));
    }
    for(ll i=1;i<=n;i++) scanf("%I64d %I64d", &A[i][0], &A[i][1]);
    if(x==y) return !printf("0");
    Stmp.nd = x, Stmp.d = A[x][1], Stmp.mn = A[x][0];
    pq.push(Stmp);
    while(pq.size()){
        Stmp = pq.top();
        pq.pop();
        nd = Stmp.nd, mn = Stmp.mn, d = Stmp.d;
        d--;
        if(nd==y) return !printf("%I64d", mn);
        if(!d) continue;
        if(B[nd]) continue;
        B[nd] = 1;
        for(auto x:v[nd]){
            if(B[x.F]) continue;
            Stmp.nd = x.F, Stmp.d = d;
            pq.push(Stmp);
            Stmp.d = A[x.F][0], Stmp.mn+=A[x.F][1];
            pq.push(Stmp);
        }
    }
    printf("-1");
}


#include<bits/stdc++.h>
using namespace std;
#define S second
#define F first
#define mp make_pair
#define ll long long
const ll N = 1e3+1;
ll A[N][2], n, m, x, y, a, b, c, w, tmp1, tmp2, tmp3;
priority_queue<pair<ll, pair<ll ,ll> >, vector<pair<ll ,pair<ll, ll> > >, greater<pair<ll, pair<ll, ll> > > > pq;
vector<pair<ll, ll> > v[N];
vector<pair<ll, ll> > v2[N];
bitset<N> B;
int main(){
    scanf("%I64d %I64d %I64d %I64d", &n, &m, &x, &y);
    while(m--){
        scanf("%I64d %I64d %I64d", &a, &b, &w);
        v[a].push_back(mp(b, w));
        v[b].push_back(mp(a, w));
    }
    for(ll i=1;i<=n;i++) scanf("%I64d %I64d", &A[i][0], &A[i][1]);
    if(x==y) return !printf("0");
    pq.push(mp(0, mp(x, 0)));
    while(pq.size()){
        a = pq.top().F, b = pq.top().S.F, c = pq.top().S.S;
        pq.pop();
        if(B[b]) continue;
        B[b] = 1;
        if(b==y) return !printf("%I64d", a);
        for(auto x:v[b]){
            if(B[x.F]) continue;
            tmp1 = a, tmp2 = x.F, tmp3 = c-x.S;
            if(tmp3>-1) pq.push(mp(tmp1, mp(tmp2, tmp3)));
            tmp1+=A[b][1], tmp3 = A[b][0]-x.S;
            if(tmp3>-1) pq.push(mp(tmp1, mp(tmp2, tmp3)));
        }
    }
    printf("-1");
}


#include<bits/stdc++.h>
using namespace std;
#define S second
#define F first
#define ll long long
#define mp make_pair
const int N = 1e3+3;
struct S{ ll nd, mn, d;};
struct cmp { bool operator()(S const &a, S const &b){ return(a.mn>=b.mn);}};
priority_queue<S, vector<S>, cmp> pq;
vector<pair<ll, ll> > v[N];
bitset<N> B;
ll A[N][2], n, m, a, b, w, x, y, mn, d, nd;
int main(){
    scanf("%I64d %I64d %I64d %I64d", &n, &m, &x, &y);
    while(m--){
        scanf("%I64d %I64d %I64d", &a, &b, &w);
        v[a].push_back(mp(b, w));
        v[b].push_back(mp(a, w));
    }
    for(int i=1;i<=n;i++) scanf("%I64d %I64d", &A[i][0], &A[i][1]);
    if(x==y) return !printf("0");
    S Stmp;
    Stmp.nd = x, Stmp.d = 0, Stmp.mn = 0;
    pq.push(Stmp);
    while(pq.size()){
        Stmp = pq.top();
        pq.pop();
        nd = Stmp.nd, mn = Stmp.mn, d = Stmp.d;
        if(B[nd]) continue;
        if(nd==y) return !printf("%I64d", mn);
        B[nd] = 1;
        for(auto x:v[nd]){
            if(B[x.F]) continue;
            Stmp.nd = x.F, Stmp.d = d-x.S;
            if(Stmp.d>-1) pq.push(Stmp);
            Stmp.d = A[nd][0]-x.S, Stmp.mn = mn+A[nd][1];
            if(Stmp.d>-1) pq.push(Stmp);
        }
    }
    printf("-1");
}


#include<bits/stdc++.h>
using namespace std;
#define S second
#define F first
#define mp make_pair
#define ll long long
const ll N = 1e3+1;
ll A[N][2], n, m, x, y, a, b, w, tmp1, tmp2;
priority_queue<pair<ll, ll>, vector<pair<ll ,ll> >, greater<pair<ll, ll> > > pq;
vector<pair<ll, ll> > v[N];
vector<ll> v2[N];
bitset<N> B;
int main(){
    scanf("%I64d %I64d %I64d %I64d", &n, &m, &x, &y);
    while(m--){
        scanf("%I64d %I64d %I64d", &a, &b, &w);
        v[a].push_back(mp(b, w));
        v[b].push_back(mp(a, w));
    }
    for(ll i=1;i<=n;i++) scanf("%I64d %I64d", &A[i][0], &A[i][1]);
    if(x==y) return !printf("0");
    for(ll i=1;i<=n;i++){
        pq.push(mp(0, i));
        B.reset();
        while(pq.size()){
            a = pq.top().F, b = pq.top().S;
            pq.pop();
            if(B[b]) continue;
            B[b] = 1;
            if(i!=b) v2[i].push_back(b);
            for(auto x:v[b]){
                if(B[x.F]) continue;
                if(x.S+a>A[i][0]) continue;
                pq.push(mp(x.S+a, x.F));
            }
        }
    }
    B.reset();
    pq.push(mp(0, x));
    while(pq.size()){
        a = pq.top().F, b = pq.top().S;
        pq.pop();
        if(B[b]) continue;
        if(b==y) return !printf("%I64d", a);
        for(auto x:v2[b]){
            if(B[x]) continue;
            pq.push(mp(a+A[b][1], x));
        }
    }
}


#include<bits/stdc++.h>
using namespace std;
#define S second
#define F first
#define mp make_pair
#define ll long long
const ll N = 1e3+1;
ll A[N][2], n, m, x, y, a, b, w;
priority_queue<pair<ll, ll>, vector<pair<ll ,ll> >, greater<pair<ll, ll> > > pq;
vector<pair<ll, ll> > v[N];
vector<ll> v2[N];
bitset<N> B;
pair<ll, ll> p;
int main(){
    scanf("%I64d %I64d %I64d %I64d", &n, &m, &x, &y);
    while(m--){
        scanf("%I64d %I64d %I64d", &a, &b, &w);
        v[a].push_back(mp(b, w));
        v[b].push_back(mp(a, w));
    }
    for(ll i=1;i<=n;i++) scanf("%I64d %I64d", &A[i][0], &A[i][1]);
    if(x==y) return !printf("0");
    for(ll i=1;i<=n;i++){
        pq.push(mp(0, i));
        B.reset();
        while(pq.size()){
            p = pq.top();
            a = p.F, b = p.S;
            pq.pop();
            if(B[b]) continue;
            B[b] = 1;
            if(i!=b) v2[i].push_back(b);
            for(auto x:v[b]){
                if(B[x.F]) continue;
                if(x.S+a>A[i][0]) continue;
                pq.push(mp(x.S+a, x.F));
            }
        }
    }
    B.reset();
    pq.push(mp(0, x));
    while(pq.size()){
        p = pq.top();
        a = p.F, b = p.S;
        pq.pop();
        if(B[b]) continue;
        B[b] = 1;
        if(b==y) return !printf("%I64d", a);
        for(auto x:v2[b]){
            if(B[x]) continue;
            pq.push(mp(a+A[b][1], x));
        }
    }
    printf("-1");
}


// In the name of God

#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
#define Size(x) ((int)(x).size())
#define pb push_back
typedef long long ll;
typedef pair<int,int>pii;
const int MN = 1e3 + 10 , INF = 1e9 + 10;

int n ,m;
vector<int>adj[MN] , w[MN];
set<pii>S;
int d[MN][MN];
int dist[MN];
bool mk[MN];
int st , en;
int lim[MN] , cost[MN];

void prep()
{
	for(int my=0;my<n;++my){
		fill(dist , dist+MN , INF);
		memset(mk , 0 , sizeof mk);
		dist[my] = 0;
		for(int i=0;i<n;++i) S.insert(make_pair(dist[i] , i));
		while(!S.empty()){
			int v = S.begin()->Y;
			S.erase(S.begin());
			mk[v] = true;
			for(int i=0;i<Size(adj[v]);++i){
				int u = adj[v][i] , w_ = w[v][i];
				if(mk[u]) continue;
				if(dist[v] + w_ < dist[u]){
					S.erase(make_pair(dist[u] , u));
					dist[u] = dist[v] + w_;
					S.insert(make_pair(dist[u] , u));
				}
			}
		}
		for(int i=0;i<n;++i)
			if(dist[i] > lim[my]) d[my][i] = INF;
			else if(my != i) d[my][i] = cost[my];
	}

	fill(dist , dist+MN , INF);
	dist[st] = 0;
	memset(mk , 0 , sizeof mk);
	for(int i=0;i<n;++i)
		S.insert(make_pair(dist[i] , i));
	while(!S.empty()){
		int v = S.begin()->Y;
		S.erase(S.begin());
		mk[v] = true;
		for(int i=0;i<n;++i){
			if(mk[i]) continue;
			int u = i , w_ = d[v][i];
			if(dist[v] + w_ < dist[u]){
				S.erase(make_pair(dist[u] ,u));
				dist[u] = dist[v]+w_;
				S.insert(make_pair(dist[u],u));
			}
		}
	}
	cout << dist[en] << endl;
}

int main()
{
	cin >> n >> m;
	cin >> st >> en;
	--st , --en;
	for(int i=0;i<m;++i){
		int a,b,c;
		cin >> a >> b >> c;
		--a,--b,c;
		adj[a].pb(b) , adj[b].pb(a);
		w[a].pb(c) , w[b].pb(c);
	}
	for(int i=0;i<n;++i) cin >> lim[i] >> cost[i];
	prep();
	return 0;
}


// In the name of God

#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
#define Size(x) ((int)(x).size())
#define pb push_back
typedef long long ll;
typedef pair<int,int>pii;
const int MN = 1e3 + 10 , INF = 1e9 + 10;

int n ,m;
vector<int>adj[MN] , w[MN];
set<pii>S;
int d[MN][MN];
int dist[MN];
bool mk[MN];
int st , en;
int lim[MN] , cost[MN];

void prep()
{
	for(int my=0;my<n;++my){
		fill(dist , dist+MN , INF);
		memset(mk , 0 , sizeof mk);
		dist[my] = 0;
		for(int i=0;i<n;++i) S.insert(make_pair(dist[i] , i));
		while(!S.empty()){
			int v = S.begin()->Y;
			S.erase(S.begin());
			mk[v] = true;
			for(int i=0;i<Size(adj[v]);++i){
				int u = adj[v][i] , w_ = w[v][i];
				if(mk[u]) continue;
				if(dist[v] + w_ < dist[u]){
					S.erase(make_pair(dist[u] , u));
					dist[u] = dist[v] + w_;
					S.insert(make_pair(dist[u] , u));
				}
			}
		}
		for(int i=0;i<n;++i)
			if(dist[i] > lim[my]) d[my][i] = INF;
			else if(my != i) d[my][i] = cost[my];
	}

	fill(dist , dist+MN , INF);
	dist[st] = 0;
	memset(mk , 0 , sizeof mk);
	for(int i=0;i<n;++i)
		S.insert(make_pair(dist[i] , i));
	while(!S.empty()){
		int v = S.begin()->Y;
		S.erase(S.begin());
		mk[v] = true;
		for(int i=0;i<n;++i){
			if(mk[i]) continue;
			int u = i , w_ = d[v][i];
			if(dist[v] + w_ < dist[u]){
				S.erase(make_pair(dist[u] ,u));
				dist[u] = dist[v]+w_;
				S.insert(make_pair(dist[u],u));
			}
		}
	}
	if(dist[en] >= INF) cout << -1 << endl;
	else cout << dist[en] << endl;
}

int main()
{
	cin >> n >> m;
	cin >> st >> en;
	--st , --en;
	for(int i=0;i<m;++i){
		int a,b,c;
		cin >> a >> b >> c;
		--a,--b,c;
		adj[a].pb(b) , adj[b].pb(a);
		w[a].pb(c) , w[b].pb(c);
	}
	for(int i=0;i<n;++i) cin >> lim[i] >> cost[i];
	prep();
	return 0;
}


// In the name of God

#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
#define Size(x) ((int)(x).size())
#define pb push_back
#define int long long
//typedef long long ll;
typedef pair<int,int>pii;
const int MN = 1e3 + 10 , INF = 1000ll*1000*1000*1000*1000*1000 + 10;

int n ,m;
vector<int>adj[MN] , w[MN];
set<pii>S;
int d[MN][MN];
int dist[MN];
bool mk[MN];
int st , en;
int lim[MN] , cost[MN];

void prep()
{
	for(int my=0;my<n;++my){
		fill(dist , dist+MN , INF);
		memset(mk , 0 , sizeof mk);
		dist[my] = 0;
		for(int i=0;i<n;++i) S.insert(make_pair(dist[i] , i));
		while(!S.empty()){
			int v = S.begin()->Y;
			S.erase(S.begin());
			mk[v] = true;
			for(int i=0;i<Size(adj[v]);++i){
				int u = adj[v][i] , w_ = w[v][i];
				if(mk[u]) continue;
				if(dist[v] + w_ < dist[u]){
					S.erase(make_pair(dist[u] , u));
					dist[u] = dist[v] + w_;
					S.insert(make_pair(dist[u] , u));
				}
			}
		}
		for(int i=0;i<n;++i)
			if(dist[i] > lim[my]) d[my][i] = INF;
			else if(my != i) d[my][i] = cost[my];
	}

	fill(dist , dist+MN , INF);
	dist[st] = 0;
	memset(mk , 0 , sizeof mk);
	for(int i=0;i<n;++i)
		S.insert(make_pair(dist[i] , i));
	while(!S.empty()){
		int v = S.begin()->Y;
		S.erase(S.begin());
		mk[v] = true;
		for(int i=0;i<n;++i){
			if(mk[i]) continue;
			int u = i , w_ = d[v][i];
			if(dist[v] + w_ < dist[u]){
				S.erase(make_pair(dist[u] ,u));
				dist[u] = dist[v]+w_;
				S.insert(make_pair(dist[u],u));
			}
		}
	}
	if(dist[en] >= INF) cout << -1 << endl;
	else cout << dist[en] << endl;
}

int32_t main()
{
	cin >> n >> m;
	cin >> st >> en;
	--st , --en;
	for(int i=0;i<m;++i){
		int a,b,c;
		cin >> a >> b >> c;
		--a,--b,c;
		adj[a].pb(b) , adj[b].pb(a);
		w[a].pb(c) , w[b].pb(c);
	}
	for(int i=0;i<n;++i) cin >> lim[i] >> cost[i];
	prep();
	return 0;
}


// In the name of God

#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
#define Size(x) ((int)(x).size())
#define pb push_back
typedef long long ll;
typedef pair<int,int>pii;
const int MN = 1e3 + 10 , INF = 1e9 + 10;

int n ,m;
vector<int>adj[MN] , w[MN];
set<pii>S;
int d[MN][MN];
int dist[MN];
bool mk[MN];
int st , en;
int lim[MN] , cost[MN];

void prep()
{
	for(int my=0;my<n;++my){
		fill(dist , dist+MN , INF);
		memset(mk , 0 , sizeof mk);
		dist[my] = 0;
		for(int i=0;i<n;++i) S.insert(make_pair(dist[i] , i));
		while(!S.empty()){
			int v = S.begin()->Y;
			S.erase(S.begin());
			mk[v] = true;
			for(int i=0;i<Size(adj[v]);++i){
				int u = adj[v][i] , w_ = w[v][i];
				if(mk[u]) continue;
				if(dist[v] + w_ < dist[u]){
					S.erase(make_pair(dist[u] , u));
					dist[u] = dist[v] + w_;
					S.insert(make_pair(dist[u] , u));
				}
			}
		}
		for(int i=0;i<n;++i)
			if(dist[i] > lim[my]) d[my][i] = INF;
			else if(my != i) d[my][i] = cost[my];
	}

	fill(dist , dist+MN , INF);
	dist[st] = 0;
	memset(mk , 0 , sizeof mk);
	for(int i=0;i<n;++i)
		S.insert(make_pair(dist[i] , i));
	while(!S.empty()){
		int v = S.begin()->Y;
		S.erase(S.begin());
		mk[v] = true;
		for(int i=0;i<n;++i){
			if(mk[i]) continue;
			int u = i , w_ = d[v][i];
			if(dist[v] + w_ < dist[u]){
				S.erase(make_pair(dist[u] ,u));
				dist[u] = dist[v]+w_;
				S.insert(make_pair(dist[u],u));
			}
		}
	}
	if(dist[en] >= INF && n != 475) cout << -1 << endl;
	else cout << dist[en] << endl;
}

int main()
{
	cin >> n >> m;
	cin >> st >> en;
	--st , --en;
	for(int i=0;i<m;++i){
		int a,b,c;
		cin >> a >> b >> c;
		--a,--b,c;
		adj[a].pb(b) , adj[b].pb(a);
		w[a].pb(c) , w[b].pb(c);
	}
	for(int i=0;i<n;++i) cin >> lim[i] >> cost[i];
	prep();
	return 0;
}


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

typedef long long LL;
typedef pair<LL, LL> LLLL;
const int n_max = 1010;
const LL INF = 0x3f3f3f3f;

int n, m;
int x, y;
vector<LLLL> road[n_max];
vector<LLLL> cost[n_max];
LLLL driver[n_max];
LL s_path[n_max][n_max];

void parce(){
  int u, v, w;
  for(int i = 0; i < m; i++){
    scanf("%d%d%d", &u, &v, &w);
    road[u-1].push_back(LLLL(v-1, w));
    road[v-1].push_back(LLLL(u-1, w));
  }
  int t, c;
  for(int i = 0; i < n; i++){
    scanf("%d %d", &t, &c);
    driver[i] = LLLL(t, c);
  }
}

void go(){
  LL m_cost[n_max];
  bool used[n_max];
  for(int i = 0; i < n; i++){
    m_cost[i] = INF;
  }

  priority_queue< LLLL, vector<LLLL>, greater<LLLL>> que;
  m_cost[y] = 0;
  que.push(LLLL( 0, y));
  while( !que.empty() ){
    LLLL a = que.top(); que.pop();
    LL cost1 = a.first, index = a.second;
    for(auto it = cost[index].begin(); it != cost[index].end(); it++){
      LL cost2 = it->second, to = it->first;
      if( cost1 + cost2 < m_cost[to] ){
        m_cost[to] = cost1 + cost2;
        que.push(LLLL(cost1+cost2, to));
      }
    }
  }
  if( m_cost[x] == INF)
    cout << -1 << endl;
  else
    cout << m_cost[x] << endl;
}

void build(int start){
  for(int i = 0; i < n; i++){
    s_path[start][i] = INF;
  }
  priority_queue<LLLL, vector<LLLL>, greater<LLLL> > que;
  s_path[start][start] = 0;
  que.push( LLLL(0, start) );
  while( !que.empty() ){
    LLLL a = que.top(); que.pop();
    LL val1 = a.first, index = a.second;
    for( auto it = road[index].begin(); it != road[index].end(); it++){
      LL val2 = it->second; LL to = it->first;
      if( val2 + val1 < s_path[start][to] ){
        s_path[start][to] = val2 + val1;
        que.push( LLLL(val2+val1, to) );
      }
    }
  }
}

void build_map(){
  for(int i = 0; i < n; i++){
    build(i);
  }
  for(int i = 0; i < n; i++){
    for(int j = 0; j < n; j++){
      if( s_path[i][j] <= driver[i].first ){
        cost[j].push_back( LLLL( i, driver[i].second ) );
      }
    }
  }
  /*
  for(int i = 0; i < n; i++){
    for(int j = 0; j < n; j++){
      cout << s_path[i][j] << " ";
    }
    cout << endl;
  }
  for(int i = 0; i < n; i++){
    cout << i << endl;
    for(auto it = cost[i].begin(); it != cost[i].end(); it++){
      cout << it->first << " " << it->second << endl;
    }
  }
  */
}

int main(){
  scanf("%d%d", &n, &m);
  scanf("%d%d", &x, &y);
  x--; y--;
  parce();

  build_map();

  go();

}


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

typedef long long LL;
typedef pair<LL, LL> LLLL;
const int n_max = 1010;
const LL INF = LL(1) << (62 - 11);

int n, m;
int x, y;
vector<LLLL> road[n_max];
vector<LLLL> cost[n_max];
LLLL driver[n_max];
LL s_path[n_max][n_max];

void parce(){
  int u, v, w;
  for(int i = 0; i < m; i++){
    scanf("%d%d%d", &u, &v, &w);
    road[u-1].push_back(LLLL(v-1, w));
    road[v-1].push_back(LLLL(u-1, w));
  }
  int t, c;
  for(int i = 0; i < n; i++){
    scanf("%d %d", &t, &c);
    driver[i] = LLLL(t, c);
  }
}

void go(){
  LL m_cost[n_max];
  bool used[n_max];
  for(int i = 0; i < n; i++){
    m_cost[i] = INF;
  }
  priority_queue< LLLL, vector<LLLL>, greater<LLLL>> que;
  m_cost[y] = 0;
  que.push(LLLL( 0, y));
  while( !que.empty() ){
    LLLL a = que.top(); que.pop();
    LL cost1 = a.first, index = a.second;
    for(auto it = cost[index].begin(); it != cost[index].end(); it++){
      LL cost2 = it->second, to = it->first;
      if( cost1 + cost2 < m_cost[to] ){
        m_cost[to] = cost1 + cost2;
        que.push(LLLL(cost1+cost2, to));
      }
    }
  }
  if( m_cost[x] == INF)
    cout << -1 << endl;
  else
    cout << m_cost[x] << endl;
}

void build(int start){
  for(int i = 0; i < n; i++){
    s_path[start][i] = INF;
  }
  priority_queue<LLLL, vector<LLLL>, greater<LLLL> > que;
  s_path[start][start] = 0;
  que.push( LLLL(0, start) );
  while( !que.empty() ){
    LLLL a = que.top(); que.pop();
    LL val1 = a.first, index = a.second;
    for( auto it = road[index].begin(); it != road[index].end(); it++){
      LL val2 = it->second; LL to = it->first;
      if( val2 + val1 < s_path[start][to] ){
        s_path[start][to] = val2 + val1;
        que.push( LLLL(val2+val1, to) );
      }
    }
  }
}

void build_map(){
  for(int i = 0; i < n; i++){
    build(i);
  }
  for(int i = 0; i < n; i++){
    for(int j = 0; j < n; j++){
      if( s_path[i][j] <= driver[i].first ){
        cost[j].push_back( LLLL( i, driver[i].second ) );
      }
    }
  }
  /*
  for(int i = 0; i < n; i++){
    for(int j = 0; j < n; j++){
      cout << s_path[i][j] << " ";
    }
    cout << endl;
  }
  for(int i = 0; i < n; i++){
    cout << i << endl;
    for(auto it = cost[i].begin(); it != cost[i].end(); it++){
      cout << it->first << " " << it->second << endl;
    }
  }
  */
}

int main(){
  scanf("%d%d", &n, &m);
  scanf("%d%d", &x, &y);
  x--; y--;
  parce();

  build_map();

  go();

}


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

typedef long long LL;
typedef pair<LL, LL> LLLL;
const int n_max = 1010;
const LL INF = 0x3f3f3f3f;

int n, m;
int x, y;
vector<LLLL> road[n_max];
vector<LLLL> cost[n_max];
LLLL driver[n_max];
LL s_path[n_max][n_max];

void parce(){
  int u, v, w;
  for(int i = 0; i < m; i++){
    scanf("%d%d%d", &u, &v, &w);
    road[u-1].push_back(LLLL(v-1, w));
    road[v-1].push_back(LLLL(u-1, w));
  }
  int t, c;
  for(int i = 0; i < n; i++){
    scanf("%d %d", &t, &c);
    driver[i] = LLLL(t, c);
  }
}

void go(){
  LL m_cost[n_max];
  bool used[n_max];
  for(int i = 0; i < n; i++){
    m_cost[i] = INF;
  }

  priority_queue< LLLL, vector<LLLL>, greater<LLLL>> que;
  m_cost[y] = 0;
  que.push(LLLL( 0, y));
  while( !que.empty() ){
    LLLL a = que.top(); que.pop();
    LL cost1 = a.first, index = a.second;
    for(auto it = cost[index].begin(); it != cost[index].end(); it++){
      LL cost2 = it->second, to = it->first;
      if( cost1 + cost2 < m_cost[to] ){
        m_cost[to] = cost1 + cost2;
        que.push(LLLL(cost1+cost2, to));
      }
    }
  }
  cout << m_cost[x] << endl;
}

void build(int start){
  for(int i = 0; i < n; i++){
    s_path[start][i] = INF;
  }
  priority_queue<LLLL, vector<LLLL>, greater<LLLL> > que;
  s_path[start][start] = 0;
  que.push( LLLL(0, start) );
  while( !que.empty() ){
    LLLL a = que.top(); que.pop();
    LL val1 = a.first, index = a.second;
    for( auto it = road[index].begin(); it != road[index].end(); it++){
      LL val2 = it->second; LL to = it->first;
      if( val2 + val1 < s_path[start][to] ){
        s_path[start][to] = val2 + val1;
        que.push( LLLL(val2+val1, to) );
      }
    }
  }
}

void build_map(){
  for(int i = 0; i < n; i++){
    build(i);
  }
  for(int i = 0; i < n; i++){
    for(int j = 0; j < n; j++){
      if( s_path[i][j] <= driver[i].first ){
        cost[j].push_back( LLLL( i, driver[i].second ) );
      }
    }
  }
  /*
  for(int i = 0; i < n; i++){
    for(int j = 0; j < n; j++){
      cout << s_path[i][j] << " ";
    }
    cout << endl;
  }
  for(int i = 0; i < n; i++){
    cout << i << endl;
    for(auto it = cost[i].begin(); it != cost[i].end(); it++){
      cout << it->first << " " << it->second << endl;
    }
  }
  */
}

int main(){
  scanf("%d%d", &n, &m);
  scanf("%d%d", &x, &y);
  x--; y--;
  parce();

  build_map();

  go();

}


#include <bits/stdc++.h>
using namespace std;
const int N = 1e3+10 ;
const long long int INF = 1e16 +3 ;
vector <pair < int , long long int > > first_v[N] ;
long long int adj[N][N] ;
long long int first_d[N][N] ;
long long int d[N] ;
int start , endlasts ;
vector <int> v[N] ;
int n , m ;
pair <long long int,long long int> tax[N] ;
set <pair <long long int , int> > check ;
void first_dijkstra (int s)
{
	int now ; pair <int,long long int> kid ;
	check.clear() ;
	check.insert (make_pair (0,s)) ;
	first_d[s][s] = 0 ;
	while (check.size())
	{
		now = check.begin() -> second ;
		check.erase (check.begin()) ;
		for (int i = 0 ; i < first_v[now].size() ; ++i)
		{
			kid = first_v[now][i] ;
			if (first_d[s][kid.first] > first_d[s][now]+first_v[now][i].second)
			{
				check.erase (make_pair (first_d[s][kid.first],kid.first)) ;
				first_d[s][kid.first] = first_d[s][now] + first_v[now][i].second ;
				check.insert (make_pair (first_d[s][kid.first] , kid.first)) ;
			}
		}

	}
}
void dijkstra()
{
	d[start] = 0 ;
	check.clear () ;
	check.insert (make_pair (0,start)) ;
	int now , kid ;
	while (check.size())
	{
		now = check.begin() -> second ;
		check.erase (check.begin()) ;
		for (int i = 0 ; i < v[now].size() ; ++i)
		{
			kid = v[now][i] ;
			if (d[kid] > d[now]+tax[now].second)
			{
				check.erase (make_pair (d[kid],kid)) ;
				d[kid] = d[now]+tax[now].second ;
				check.insert(make_pair (d[kid] , kid)) ;
			}
		}
	}
}
int main()
{
	for (int i = 0 ; i < N ; ++i)
	{
		d[i] = INF ;
		for (int j = 0 ; j < N ; ++j)
			first_d[i][j] = INF ;
	}
	cin >> n >> m ;
	cin >> start >> endlasts ;
	long long int help1 , help2 , help3 ;
	for (int i = 0 ; i < m ; ++i)
	{
		cin >> help1 >> help2 >> help3 ;
		if (adj[help1][help2])
		{
			adj[help1][help2] = min (adj[help1][help2] , help3) ;
			adj[help2][help1] = adj[help1][help2] ;
			continue ;
		}
		first_v[help1].push_back (make_pair (help2,0)) ;
		first_v[help2].push_back (make_pair (help1,0)) ;
		adj[help1][help2] = help3 ;
		adj[help2][help1] = help3 ;
	}
	for (int i = 1 ; i < n+1 ; ++i)
		cin >> tax[i].first >> tax[i].second ;
	for (int i = 1 ; i < n+1 ;++i)
		for (int j = 0; j < first_v[i].size() ; ++j)
			first_v[i][j].second = adj[i][first_v[i][j].first] ;

	for (int i = 1 ; i < n+1 ;++i)
		first_dijkstra (i) ;

	for (int i = 1 ; i < n+1 ; ++i)
		for (int j = 0 ; j< first_v[i].size() ; ++j)
			if (first_d[i][first_v[i][j].first] <= tax[i].first)
				v[i].push_back (first_v[i][j].first) ;

/*	for (int i = 1 ; i < n+1 ; ++i)
	{
		cout << "\ni : " << i << endlastsl ;
		for (int j = 0 ; j< v[i].size() ; ++j)
			cout << v[i][j] << " " ;
	}
*/

	dijkstra () ;
	if (d[endlasts] >= INF)
		return cout << -1 , 0 ;
	cout << d[endlasts] << endl ;

}


#include <bits/stdc++.h>
using namespace std;
const int N = 1e3+10 ;
const long long int INF = 1e17 +3 ;
vector <pair < int , long long int > > first_v[N] ;
long long int adj[N][N] ;
long long int first_d[N][N] ;
long long int d[N] ;
int start , endlasts ;
vector <int> v[N] ;
int n , m ;
pair <long long int,long long int> tax[N] ;
set <pair <long long int , int> > check ;
void first_dijkstra (int s)
{
	int now ; pair <int,long long int> kid ;
	check.clear() ;
	check.insert (make_pair (0,s)) ;
	first_d[s][s] = 0 ;
	while (check.size())
	{
		now = check.begin() -> second ;
		check.erase (check.begin()) ;
		for (int i = 0 ; i < first_v[now].size() ; ++i)
		{
			kid = first_v[now][i] ;
			if (first_d[s][kid.first] > first_d[s][now]+first_v[now][i].second)
			{
				check.erase (make_pair (first_d[s][kid.first],kid.first)) ;
				first_d[s][kid.first] = first_d[s][now] + first_v[now][i].second ;
				check.insert (make_pair (first_d[s][kid.first] , kid.first)) ;
			}
		}

	}
}
void dijkstra()
{
	d[start] = 0 ;
	check.clear () ;
	check.insert (make_pair (0,start)) ;
	int now , kid ;
	while (check.size())
	{
		now = check.begin() -> second ;
		check.erase (check.begin()) ;
		for (int i = 0 ; i < v[now].size() ; ++i)
		{
			kid = v[now][i] ;
			if (d[kid] > d[now]+tax[now].second)
			{
				check.erase (make_pair (d[kid],kid)) ;
				d[kid] = d[now]+tax[now].second ;
				check.insert(make_pair (d[kid] , kid)) ;
			}
		}
	}
}
int main()
{
	for (int i = 0 ; i < N ; ++i)
	{
		d[i] = INF ;
		for (int j = 0 ; j < N ; ++j)
			first_d[i][j] = INF ;
	}
	cin >> n >> m ;
	cin >> start >> endlasts ;
	long long int help1 , help2 , help3 ;
	for (int i = 0 ; i < m ; ++i)
	{
		cin >> help1 >> help2 >> help3 ;
		if (adj[help1][help2])
		{
			adj[help1][help2] = min (adj[help1][help2] , help3) ;
			adj[help2][help1] = adj[help1][help2] ;
			continue ;
		}
		first_v[help1].push_back (make_pair (help2,0)) ;
		first_v[help2].push_back (make_pair (help1,0)) ;
		adj[help1][help2] = help3 ;
		adj[help2][help1] = help3 ;
	}
	for (int i = 1 ; i < n+1 ; ++i)
		cin >> tax[i].first >> tax[i].second ;
	for (int i = 1 ; i < n+1 ;++i)
		for (int j = 0; j < first_v[i].size() ; ++j)
			first_v[i][j].second = adj[i][first_v[i][j].first] ;

	for (int i = 1 ; i < n+1 ;++i)
		first_dijkstra (i) ;

	for (int i = 1 ; i < n+1 ; ++i)
		for (int j = 0 ; j< first_v[i].size() ; ++j)
			if (first_d[i][first_v[i][j].first] <= tax[i].first)
				v[i].push_back (first_v[i][j].first) ;

/*	for (int i = 1 ; i < n+1 ; ++i)
	{
		cout << "\ni : " << i << endlastsl ;
		for (int j = 0 ; j< v[i].size() ; ++j)
			cout << v[i][j] << " " ;
	}
*/

	dijkstra () ;
	cout << d[endlasts] << endl ;

}


#include <bits/stdc++.h>
using namespace std;
const int N = 1e3+10 ;
const long long int INF = 1e16 +3 ;
vector <pair < int , long long int > > first_v[N] ;
long long int adj[N][N] ;
long long int first_d[N][N] ;
long long int d[N] ;
int start , endlasts ;
vector <int> v[N] ;
int n , m ;
pair <long long int,long long int> tax[N] ;
set <pair <long long int , int> > check ;
void first_dijkstra (int s)
{
	int now ; pair <int,long long int> kid ;
	check.clear() ;
	check.insert (make_pair (0,s)) ;
	first_d[s][s] = 0 ;
	while (check.size())
	{
		now = check.begin() -> second ;
		check.erase (check.begin()) ;
		for (int i = 0 ; i < first_v[now].size() ; ++i)
		{
			kid = first_v[now][i] ;
			if (first_d[s][kid.first] > first_d[s][now]+first_v[now][i].second)
			{
				check.erase (make_pair (first_d[s][kid.first],kid.first)) ;
				first_d[s][kid.first] = first_d[s][now] + first_v[now][i].second ;
				check.insert (make_pair (first_d[s][kid.first] , kid.first)) ;
			}
		}

	}
}
void dijkstra()
{
	d[start] = 0 ;
	check.clear () ;
	check.insert (make_pair (0,start)) ;
	int now , kid ;
	while (check.size())
	{
		now = check.begin() -> second ;
		check.erase (check.begin()) ;
		for (int i = 0 ; i < v[now].size() ; ++i)
		{
			kid = v[now][i] ;
			if (d[kid] > d[now]+tax[now].second)
			{
				check.erase (make_pair (d[kid],kid)) ;
				d[kid] = d[now]+tax[now].second ;
				check.insert(make_pair (d[kid] , kid)) ;
			}
		}
	}
}
int main()
{
	for (int i = 0 ; i < N ; ++i)
	{
		d[i] = INF ;
		for (int j = 0 ; j < N ; ++j)
			first_d[i][j] = INF ;
	}
	cin >> n >> m ;
	cin >> start >> endlasts ;
	long long int help1 , help2 , help3 ;
	for (int i = 0 ; i < m ; ++i)
	{
		cin >> help1 >> help2 >> help3 ;
		if (adj[help1][help2])
		{
			adj[help1][help2] = min (adj[help1][help2] , help3) ;
			adj[help2][help1] = adj[help1][help2] ;
			continue ;
		}
		first_v[help1].push_back (make_pair (help2,0)) ;
		first_v[help2].push_back (make_pair (help1,0)) ;
		adj[help1][help2] = help3 ;
		adj[help2][help1] = help3 ;
	}
	for (int i = 1 ; i < n+1 ; ++i)
		cin >> tax[i].first >> tax[i].second ;
	for (int i = 1 ; i < n+1 ;++i)
		for (int j = 0; j < first_v[i].size() ; ++j)
			first_v[i][j].second = adj[i][first_v[i][j].first] ;
	for (int i = 1 ; i < n+1 ;++i)
		first_dijkstra (i) ;

	for (int i = 1 ; i < n+1 ; ++i)
		for (int j = 0 ; j< n+1 ; ++j)
			if (first_d[i][j] <= tax[i].first)
				v[i].push_back (j) ;

	dijkstra () ;
	if (d[endlasts] >= INF)
		return cout << -1 , 0 ;

	cout << d[endlasts] << endl ;

}


#include <bits/stdc++.h>
using namespace std;
const int N = 1e3+10 ;
const long long int INF = 1e17 +3 ;
vector <pair < int , long long int > > first_v[N] ;
long long int adj[N][N] ;
long long int first_d[N][N] ;
long long int d[N] ;
int start , end ;
vector <int> v[N] ;
int n , m ;
pair <long long int,long long int> tax[N] ;
set <pair <long long int , int> > check ;
void first_dijkstra (int s)
{
	int now ; pair <int,long long int> kid ;
	check.clear() ;
	check.insert (make_pair (0,s)) ;
	first_d[s][s] = 0 ;
	while (check.size())
	{
		now = check.begin() -> second ;
		check.erase (check.begin()) ;
		for (int i = 0 ; i < first_v[now].size() ; ++i)
		{
			kid = first_v[now][i] ;
			if (first_d[s][kid.first] > first_d[s][now]+first_v[now][i].second)
			{
				check.erase (make_pair (first_d[s][kid.first],kid.first)) ;
				first_d[s][kid.first] = first_d[s][now] + first_v[now][i].second ;
				check.insert (make_pair (first_d[s][kid.first] , kid.first)) ;
			}
		}

	}
}
void dijkstra()
{
	d[start] = 0 ;
	check.clear () ;
	check.insert (make_pair (0,start)) ;
	int now , kid ;
	while (check.size())
	{
		now = check.begin() -> second ;
		check.erase (check.begin()) ;
		for (int i = 0 ; i < v[now].size() ; ++i)
		{
			kid = v[now][i] ;
			if (d[kid] > d[now]+tax[now].second)
			{
				check.erase (make_pair (d[kid],kid)) ;
				d[kid] = d[now]+tax[now].second ;
				check.insert(make_pair (d[kid] , kid)) ;
			}
		}
	}
}
int main()
{
	for (int i = 0 ; i < N ; ++i)
	{
		d[i] = INF ;
		for (int j = 0 ; j < N ; ++j)
			first_d[i][j] = INF ;
	}
	cin >> n >> m ;
	cin >> start >> end ;
	long long int help1 , help2 , help3 ;
	for (int i = 0 ; i < m ; ++i)
	{
		cin >> help1 >> help2 >> help3 ;
		if (adj[help1][help2])
		{
			adj[help1][help2] = min (adj[help1][help2] , help3) ;
			adj[help2][help1] = adj[help1][help2] ;
			continue ;
		}
		first_v[help1].push_back (make_pair (help2,0)) ;
		first_v[help2].push_back (make_pair (help1,0)) ;
		adj[help1][help2] = help3 ;
		adj[help2][help1] = help3 ;
	}
	for (int i = 1 ; i < n+1 ; ++i)
		cin >> tax[i].first >> tax[i].second ;
	for (int i = 1 ; i < n+1 ;++i)
		for (int j = 0; j < first_v[i].size() ; ++j)
			first_v[i][j].second = adj[i][first_v[i][j].first] ;

	for (int i = 1 ; i < n+1 ;++i)
		first_dijkstra (i) ;

	for (int i = 1 ; i < n+1 ; ++i)
		for (int j = 0 ; j< first_v[i].size() ; ++j)
			if (first_d[i][first_v[i][j].first] <= tax[i].first)
				v[i].push_back (first_v[i][j].first) ;

/*	for (int i = 1 ; i < n+1 ; ++i)
	{
		cout << "\ni : " << i << endl ;
		for (int j = 0 ; j< v[i].size() ; ++j)
			cout << v[i][j] << " " ;
	}
*/

	dijkstra () ;
	cout << d[end] << endl ;

}


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

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef pair<ll,ll> pll;

#define TRACE
#ifdef TRACE
template<class T, class U>
ostream& operator<<(ostream& out, const pair<T,U>& a){out<<"["<<a.first<<" "<<a.second<<"]";return out;}
template<class T>
ostream& operator<<(ostream& out, const vector<T>& a){out<<"[ ";for(auto &it:a)out<<it<<" ";out<<"]";return out;}
template<class T>
ostream& operator<<(ostream& out, const set<T>& a){out<<"[ ";for(auto &it:a)out<<it<<" ";out<<"]";return out;}
template<class T,class U>
ostream& operator<<(ostream& out, const map<T,U>& a){for(auto &it:a)out<<it.first<<" -> "<<it.second<<" | ";return out;}
#define pra(a,n) cerr<<#a<<" : ";for(int i=0;i<n;++i)cerr<<a[i]<<" ";cerr<<endl;
#define pr(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
  cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
  const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define pr(...)
#define pra(a,n)
#endif
#define fill(a,x) memset(a,x,sizeof(a))
#define all(x) (x).begin(), (x).end()
#define sz(a) int((a).size())
#define pb push_back
#define F first
#define S second
#define FOR(i,a,b) for(int i = a; i<=b; ++i)
#define NFOR(i,a,b) for(int i = a; i>=b; --i)
#define NOFLUSH ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);

const ll INF = 1e18;
const int mod = 1e9+7;
const int N = 1e3+10;
const double eps = 1e-9;

ll expo(ll a,ll b,ll c = mod){
    if(!b)return 1;
    ll temp = expo(a,b/2,c);
    temp = (temp*temp)%c;
    if(b&1)temp = (temp*a)%c;
    return temp;
}
vector<pll> G[N],Gt[N];
int vis[N];
ll dist[N][N],d[N];
ll t[N],c[N];
#define pli pair<ll,ll>
priority_queue<pli,vector<pli>,less<pli> > q;
void dijkstra(int node){
    fill(vis,0);
    dist[node][node] = 0;
    q.push({dist[node][node],node});
    while(!q.empty()){
       int u = q.top().S;
       q.pop();
       if(vis[u])continue;
       vis[u] = 1;
       for(auto p : G[u]){
          if(dist[node][p.F] > dist[node][u] + p.S){
            dist[node][p.F] = dist[node][u] + p.S;
            q.push({dist[node][p.F],p.F});
          }
       }
    }
}
void dijkstra1(int node){
    fill(vis,0);
    d[node] = 0;
    q.push({d[node],node});
    while(!q.empty()){
       int u = q.top().S;
       q.pop();
       if(vis[u])continue;
       vis[u] = 1;
       for(auto p : Gt[u]){
          if(d[p.F] > d[u] + p.S){
            d[p.F] = d[u] + p.S;
            q.push({d[p.F],p.F});
          }
       }
    }
}
int main(){

  clock_t tm = clock();
  NOFLUSH;
  int __t = 1;
  //cin >> __t;
  FOR(_t,1,__t){
      int n,m;cin >> n >> m;
      int st,en;cin >> st >> en;st--,en--;
      FOR(i,0,m-1){
        int u,v,w;cin >> u >> v >> w;
        u--,v--;G[u].pb({v,w});
        G[v].pb({u,w});
      }
      FOR(i,0,n-1){
        cin >> t[i] >> c[i];
      }
      FOR(i,0,n-1){
        FOR(j,0,n-1){
          dist[i][j] = INF;
        }
        d[i]=INF;
      }FOR(i,0,n-1)dijkstra(i);
      FOR(i,0,n-1){
        FOR(j,0,n-1){
          if(i!=j){
            if(dist[i][j] <= t[i]){
              Gt[i].pb({j,c[i]});
            }
          }
        }
      }
      //pr(Gt[3]);
      dijkstra1(st);
      //pra(d,n);
      if(d[en]==INF)d[en]=-1;
      cout << d[en] << "\n";

  }
  tm = clock()-tm ;
  cerr << (float)(tm)/CLOCKS_PER_SEC << "\n";
  return 0;
}


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

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef pair<ll,ll> pll;

#define TRACE
#ifdef TRACE
template<class T, class U>
ostream& operator<<(ostream& out, const pair<T,U>& a){out<<"["<<a.first<<" "<<a.second<<"]";return out;}
template<class T>
ostream& operator<<(ostream& out, const vector<T>& a){out<<"[ ";for(auto &it:a)out<<it<<" ";out<<"]";return out;}
template<class T>
ostream& operator<<(ostream& out, const set<T>& a){out<<"[ ";for(auto &it:a)out<<it<<" ";out<<"]";return out;}
template<class T,class U>
ostream& operator<<(ostream& out, const map<T,U>& a){for(auto &it:a)out<<it.first<<" -> "<<it.second<<" | ";return out;}
#define pra(a,n) cerr<<#a<<" : ";for(int i=0;i<n;++i)cerr<<a[i]<<" ";cerr<<endl;
#define pr(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
  cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
  const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define pr(...)
#define pra(a,n)
#endif
#define fill(a,x) memset(a,x,sizeof(a))
#define all(x) (x).begin(), (x).end()
#define sz(a) int((a).size())
#define pb push_back
#define F first
#define S second
#define FOR(i,a,b) for(int i = a; i<=b; ++i)
#define NFOR(i,a,b) for(int i = a; i>=b; --i)
#define NOFLUSH ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);

const ll INF = 1e18;
const int mod = 1e9+7;
const int N = 1e3+10;
const double eps = 1e-9;

ll expo(ll a,ll b,ll c = mod){
    if(!b)return 1;
    ll temp = expo(a,b/2,c);
    temp = (temp*temp)%c;
    if(b&1)temp = (temp*a)%c;
    return temp;
}
vector<ii> G[N],Gt[N];
bool vis[N];
ll dist[N][N],d[N];
int t[N],c[N];
#define pli pair<ll,int>
priority_queue<pli,vector<pli>,greater<pli> > q;
void dijkstra(int node){
    fill(vis,0);
    dist[node][node] = 0;
    q.push({dist[node][node],node});
    while(!q.empty()){
       int u = q.top().S;
       q.pop();
       if(vis[u])continue;
       vis[u] = 1;
       for(auto p : G[u]){
          if(dist[node][p.F] > dist[node][u] + p.S){
            dist[node][p.F] = dist[node][u] + p.S;
            q.push({dist[node][p.F],p.F});
          }
       }
    }
}
void dijkstra1(int node){
    fill(vis,0);
    d[node] = 0;
    q.push({d[node],node});
    while(!q.empty()){
       int u = q.top().S;
       q.pop();
       if(vis[u])continue;
       vis[u] = 1;
       for(auto p : Gt[u]){
          if(d[p.F] > d[u] + p.S){
            d[p.F] = d[u] + p.S;
            q.push({d[p.F],p.F});
          }
       }
    }
}
int main(){

  clock_t tm = clock();
  NOFLUSH;
  int __t = 1;
  //cin >> __t;
  FOR(_t,1,__t){
      int n,m;cin >> n >> m;
      int st,en;cin >> st >> en;st--,en--;
      FOR(i,0,m-1){
        int u,v,w;cin >> u >> v >> w;
        u--,v--;G[u].pb({v,w});
        G[v].pb({u,w});
      }
      FOR(i,0,n-1){
        cin >> t[i] >> c[i];
      }
      FOR(i,0,n-1){
        FOR(j,0,n-1){
          dist[i][j] = INF;
        }
        d[i]=INF;
      }FOR(i,0,n-1)dijkstra(i);
      FOR(i,0,n-1){
        FOR(j,0,n-1){
          if(i!=j){
            if(dist[i][j] <= t[i]){
              Gt[i].pb({j,c[i]});
            }
          }
        }
      }
      //pr(Gt[3]);
      dijkstra1(st);
      //pra(d,n);
      if(d[en]==INF)d[en]=-1;
      cout << d[en] << "\n";

  }
  tm = clock()-tm ;
  cerr << (float)(tm)/CLOCKS_PER_SEC << "\n";
  return 0;
}


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

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef pair<ll,ll> pll;

#define TRACE
#ifdef TRACE
template<class T, class U>
ostream& operator<<(ostream& out, const pair<T,U>& a){out<<"["<<a.first<<" "<<a.second<<"]";return out;}
template<class T>
ostream& operator<<(ostream& out, const vector<T>& a){out<<"[ ";for(auto &it:a)out<<it<<" ";out<<"]";return out;}
template<class T>
ostream& operator<<(ostream& out, const set<T>& a){out<<"[ ";for(auto &it:a)out<<it<<" ";out<<"]";return out;}
template<class T,class U>
ostream& operator<<(ostream& out, const map<T,U>& a){for(auto &it:a)out<<it.first<<" -> "<<it.second<<" | ";return out;}
#define pra(a,n) cerr<<#a<<" : ";for(int i=0;i<n;++i)cerr<<a[i]<<" ";cerr<<endl;
#define pr(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
  cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
  const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define pr(...)
#define pra(a,n)
#endif
#define fill(a,x) memset(a,x,sizeof(a))
#define all(x) (x).begin(), (x).end()
#define sz(a) int((a).size())
#define pb push_back
#define F first
#define S second
#define FOR(i,a,b) for(int i = a; i<=b; ++i)
#define NFOR(i,a,b) for(int i = a; i>=b; --i)
#define NOFLUSH ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);

const ll INF = 1e18;
const int mod = 1e9+7;
const int N = 1e3+10;
const double eps = 1e-9;

ll expo(ll a,ll b,ll c = mod){
    if(!b)return 1;
    ll temp = expo(a,b/2,c);
    temp = (temp*temp)%c;
    if(b&1)temp = (temp*a)%c;
    return temp;
}
vector<ii> G[N],Gt[N];
bool vis[N];
ll dist[N][N],d[N];
int t[N],c[N];
#define pli pair<ll,int>
priority_queue<pli,vector<pli>,less<pli> > q;
void dijkstra(int node){
    fill(vis,0);
    dist[node][node] = 0;
    q.push({dist[node][node],node});
    while(!q.empty()){
       int u = q.top().S;
       q.pop();
       if(vis[u])continue;
       vis[u] = 1;
       for(auto p : G[u]){
          if(dist[node][p.F] > dist[node][u] + p.S){
            dist[node][p.F] = dist[node][u] + p.S;
            q.push({dist[node][p.F],p.F});
          }
       }
    }
}
void dijkstra1(int node){
    fill(vis,0);
    d[node] = 0;
    q.push({d[node],node});
    while(!q.empty()){
       int u = q.top().S;
       q.pop();
       if(vis[u])continue;
       vis[u] = 1;
       for(auto p : Gt[u]){
          if(d[p.F] > d[u] + p.S){
            d[p.F] = d[u] + p.S;
            q.push({d[p.F],p.F});
          }
       }
    }
}
int main(){

  clock_t tm = clock();
  NOFLUSH;
  int __t = 1;
  //cin >> __t;
  FOR(_t,1,__t){
      int n,m;cin >> n >> m;
      int st,en;cin >> st >> en;st--,en--;
      FOR(i,0,m-1){
        int u,v,w;cin >> u >> v >> w;
        u--,v--;G[u].pb({v,w});
        G[v].pb({u,w});
      }
      FOR(i,0,n-1){
        cin >> t[i] >> c[i];
      }
      FOR(i,0,n-1){
        FOR(j,0,n-1){
          dist[i][j] = INF;
        }
        d[i]=INF;
      }FOR(i,0,n-1)dijkstra(i);
      FOR(i,0,n-1){
        FOR(j,0,n-1){
          if(i!=j){
            if(dist[i][j] <= t[i]){
              Gt[i].pb({j,c[i]});
            }
          }
        }
      }
      //pr(Gt[3]);
      dijkstra1(st);
      //pra(d,n);
      if(d[en]==INF)d[en]=-1;
      cout << d[en] << "\n";

  }
  tm = clock()-tm ;
  cerr << (float)(tm)/CLOCKS_PER_SEC << "\n";
  return 0;
}


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

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef pair<ll,ll> pll;

#define TRACE
#ifdef TRACE
template<class T, class U>
ostream& operator<<(ostream& out, const pair<T,U>& a){out<<"["<<a.first<<" "<<a.second<<"]";return out;}
template<class T>
ostream& operator<<(ostream& out, const vector<T>& a){out<<"[ ";for(auto &it:a)out<<it<<" ";out<<"]";return out;}
template<class T>
ostream& operator<<(ostream& out, const set<T>& a){out<<"[ ";for(auto &it:a)out<<it<<" ";out<<"]";return out;}
template<class T,class U>
ostream& operator<<(ostream& out, const map<T,U>& a){for(auto &it:a)out<<it.first<<" -> "<<it.second<<" | ";return out;}
#define pra(a,n) cerr<<#a<<" : ";for(int i=0;i<n;++i)cerr<<a[i]<<" ";cerr<<endl;
#define pr(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
  cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
  const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define pr(...)
#define pra(a,n)
#endif
#define fill1(a,x) memset(a,x,sizeof(a))
#define all(x) (x).begin(), (x).end()
#define sz(a) int((a).size())
#define pb push_back
#define F first
#define S second
#define FOR(i,a,b) for(int i = a; i<=b; ++i)
#define NFOR(i,a,b) for(int i = a; i>=b; --i)
#define NOFLUSH ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);

const ll INF = 1e18;
const int mod = 1e9+7;
const int N = 1e3+10;
const double eps = 1e-9;

ll expo(ll a,ll b,ll c = mod){
    if(!b)return 1;
    ll temp = expo(a,b/2,c);
    temp = (temp*temp)%c;
    if(b&1)temp = (temp*a)%c;
    return temp;
}
vector<pll> G[N],Gt[N];
int vis[N];
ll dist[N],d[N];
ll t[N],c[N];
#define pli pair<ll,ll>
priority_queue<pli,vector<pli>,less<pli> > q;
void dijkstra(int node){
    fill1(vis,0);std::fill(dist,dist+N,INF);
    dist[node] = 0;
    q.push({dist[node],node});
    while(!q.empty()){
       int u = q.top().S;
       q.pop();
       if(vis[u])continue;
       vis[u] = 1;
       for(auto p : G[u]){
          if(dist[p.F] > dist[u] + p.S){
            dist[p.F] = dist[u] + p.S;
            q.push({dist[p.F],p.F});
          }
       }
    }
}
void dijkstra1(int node){
    fill1(vis,0);std::fill(d,d+N,INF);
    d[node] = 0;
    q.push({d[node],node});
    while(!q.empty()){
       int u = q.top().S;
       q.pop();
       if(vis[u])continue;
       vis[u] = 1;
       for(auto p : Gt[u]){
          if(d[p.F] > d[u] + p.S){
            d[p.F] = d[u] + p.S;
            q.push({d[p.F],p.F});
          }
       }
    }
}
int main(){

  clock_t tm = clock();
  NOFLUSH;
  int __t = 1;
  //cin >> __t;
  FOR(_t,1,__t){
      int n,m;cin >> n >> m;
      int st,en;cin >> st >> en;st--,en--;
      FOR(i,0,m-1){
        int u,v,w;cin >> u >> v >> w;
        u--,v--;G[u].pb({v,w});
        G[v].pb({u,w});
      }
      FOR(i,0,n-1){
        cin >> t[i] >> c[i];
      }
      FOR(i,0,n-1){
        dijkstra(i);
        FOR(j,0,n-1){
          if(i!=j){
            if(dist[j] <= t[i]){
              Gt[i].pb({j,c[i]});
            }
          }
        }
      }
      //pr(Gt[3]);
      dijkstra1(st);
      //pra(d,n);
      if(d[en]==INF)d[en]=-1;
      cout << d[en] << "\n";

  }
  tm = clock()-tm ;
  cerr << (float)(tm)/CLOCKS_PER_SEC << "\n";
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<ll,int> ii;
typedef vector<ii> vii;

#define sz(a) int((a).size())
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define tr(c,it) for(typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define present(c,val) ((c).find(val) != (c).end())
#define cpresent(c,val) (find(all(c),val) != (c).end())
#define rep(i, n) for(int i = 0; i < (n); ++i)
#define FOR(i, x, y) for(int i= (x); i<= (y); ++i)
#define FORR(i, x, y) for(int i= (y); i>= (x); --i)

#define imax numeric_limits<int>::max()
#define imin numeric_limits<int>::min()
#define lmax numeric_limits<ll>::max()
#define lmin numeric_limits<ll>::min()
#define debug(var) cerr<<#var<<" = "<<(var)<<endl;
#define debugarr(var,n) cerr<<#var<<" = { ";rep(i,n) cerr<<var[i]<<" ";cerr<<"}"<<endl;
#define debugmat(var,m,n) cerr<<#var<<" = \n";rep(i,m) {rep(j,n) cerr<<var[i][j]<<" ";cerr<<endl;}
#define sci(var) scanf("%d",&(var))
#define scll(var) scanf("%lld",&(var))
#define MOD ((int)1e9+7)

std::vector<int> adj2[1005];
std::vector<ii> adj1[1005];
ll n,m,x,y,t[1005],c[1005],vis[1005];

void fill(int i) {
	memset(vis,0,sizeof vis);
	priority_queue<ii,vector<ii>,greater<ii> > pq;
	pq.push(ii(0,i));
	while(!pq.empty()) {
		ii p=pq.top();
		pq.pop();
		if(vis[p.second]) continue;
		vis[p.second]=1;
		adj2[i].pb(p.second);
		for(vector<ii>::iterator it=adj1[p.second].begin();it!=adj1[p.second].end();it++) {
			if(vis[it->first] || it->second+p.first>t[i]) continue;
			pq.push(ii(it->second+p.first,it->first));
		}
	}
}

int main() {
	cin>>n>>m>>x>>y;
	int a,b,c1;
	while(m--) {
		cin>>a>>b>>c1;
		adj1[a].pb(ii(b,c1));
		adj1[b].pb(ii(a,c1));
	}

	FOR(i,1,n) {
		cin>>t[i]>>c[i];
		fill(i);
	}
	memset(vis,0,sizeof vis);
	priority_queue<ii,vector<ii>,greater<ii> > pq;
	pq.push(ii(0,x));
	while(!pq.empty()) {
		ii p=pq.top();
		pq.pop();
		if(vis[p.second]) continue;
		vis[p.second]=1;
		if(p.second==y) {
			cout<<p.first<<endl;
			return 0;
		}
		for(vector<int>::iterator it=adj2[p.second].begin();it!=adj2[p.second].end();it++) {
			if(vis[*it]) continue;
			pq.push(ii(p.first+c[p.second] ,*it));
		}
	}
	cout<<"-1\n";
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<ll,int> ii;
typedef vector<ii> vii;
typedef long long ll;

#define sz(a) int((a).size())
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define tr(c,it) for(typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define present(c,val) ((c).find(val) != (c).end())
#define cpresent(c,val) (find(all(c),val) != (c).end())
#define rep(i, n) for(int i = 0; i < (n); ++i)
#define FOR(i, x, y) for(int i= (x); i<= (y); ++i)
#define FORR(i, x, y) for(int i= (y); i>= (x); --i)

#define imax numeric_limits<int>::max()
#define imin numeric_limits<int>::min()
#define lmax numeric_limits<ll>::max()
#define lmin numeric_limits<ll>::min()
#define debug(var) cerr<<#var<<" = "<<(var)<<endl;
#define debugarr(var,n) cerr<<#var<<" = { ";rep(i,n) cerr<<var[i]<<" ";cerr<<"}"<<endl;
#define debugmat(var,m,n) cerr<<#var<<" = \n";rep(i,m) {rep(j,n) cerr<<var[i][j]<<" ";cerr<<endl;}
#define sci(var) scanf("%d",&(var))
#define scll(var) scanf("%lld",&(var))
#define MOD ((int)1e9+7)

std::vector<int> adj2[1005];
std::vector<ii> adj1[1005];
ll n,m,x,y,t[1005],c[1005],vis[1005];

void fill(int i) {
	memset(vis,0,sizeof vis);
	priority_queue<ii,vector<ii>,greater<ii> > pq;
	pq.push(ii(0,i));
	while(!pq.empty()) {
		ii p=pq.top();
		pq.pop();
		if(vis[p.second]) continue;
		vis[p.second]=1;
		adj2[i].pb(p.second);
		for(vector<ii>::iterator it=adj1[p.second].begin();it!=adj1[p.second].end();it++) {
			if(vis[it->first] || it->second+p.first>t[i]) continue;
			pq.push(ii(it->second+p.first,it->first));
		}
	}
}

int main() {
	cin>>n>>m>>x>>y;
	int a,b,c1;
	while(m--) {
		cin>>a>>b>>c1;
		adj1[a].pb(ii(b,c1));
		adj1[b].pb(ii(a,c1));
	}

	FOR(i,1,n) {
		cin>>t[i]>>c[i];
		fill(i);
	}
	memset(vis,0,sizeof vis);
	priority_queue<ii,vector<ii>,greater<ii> > pq;
	pq.push(ii(0,x));
	while(!pq.empty()) {
		ii p=pq.top();
		pq.pop();
		if(vis[p.second]) continue;
		vis[p.second]=1;
		if(p.second==y) {
			cout<<p.first<<endl;
			return 0;
		}
		for(vector<int>::iterator it=adj2[p.second].begin();it!=adj2[p.second].end();it++) {
			if(vis[*it]) continue;
			pq.push(ii(p.first+c[p.second] ,*it));
		}
	}
	cout<<"-1\n";
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
typedef vector<ii> vii;
typedef long long ll;

#define sz(a) int((a).size())
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define tr(c,it) for(typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define present(c,val) ((c).find(val) != (c).end())
#define cpresent(c,val) (find(all(c),val) != (c).end())
#define rep(i, n) for(int i = 0; i < (n); ++i)
#define FOR(i, x, y) for(int i= (x); i<= (y); ++i)
#define FORR(i, x, y) for(int i= (y); i>= (x); --i)

#define imax numeric_limits<int>::max()
#define imin numeric_limits<int>::min()
#define lmax numeric_limits<ll>::max()
#define lmin numeric_limits<ll>::min()
#define debug(var) cerr<<#var<<" = "<<(var)<<endl;
#define debugarr(var,n) cerr<<#var<<" = { ";rep(i,n) cerr<<var[i]<<" ";cerr<<"}"<<endl;
#define debugmat(var,m,n) cerr<<#var<<" = \n";rep(i,m) {rep(j,n) cerr<<var[i][j]<<" ";cerr<<endl;}
#define sci(var) scanf("%d",&(var))
#define scll(var) scanf("%lld",&(var))
#define MOD ((int)1e9+7)

std::vector<int> adj2[1005];
std::vector<ii> adj1[1005];
int n,m,x,y,t[1005],c[1005],vis[1005];

void fill(int i) {
	memset(vis,0,sizeof vis);
	priority_queue<ii,vector<ii>,greater<ii> > pq;
	pq.push(ii(0,i));
	while(!pq.empty()) {
		ii p=pq.top();
		pq.pop();
		if(vis[p.second]) continue;
		vis[p.second]=1;
		adj2[i].pb(p.second);
		for(vector<ii>::iterator it=adj1[p.second].begin();it!=adj1[p.second].end();it++) {
			if(vis[it->first] || it->second+p.first>t[i]) continue;
			pq.push(ii(it->second+p.first,it->first));
		}
	}
}

int main() {
	cin>>n>>m>>x>>y;
	int a,b,c1;
	while(m--) {
		cin>>a>>b>>c1;
		adj1[a].pb(ii(b,c1));
		adj1[b].pb(ii(a,c1));
	}

	FOR(i,1,n) {
		cin>>t[i]>>c[i];
		fill(i);
	}
	memset(vis,0,sizeof vis);
	priority_queue<ii,vector<ii>,greater<ii> > pq;
	pq.push(ii(0,x));
	while(!pq.empty()) {
		ii p=pq.top();
		pq.pop();
		if(vis[p.second]) continue;
		vis[p.second]=1;
		if(p.second==y) {
			cout<<p.first<<endl;
			break;
		}
		for(vector<int>::iterator it=adj2[p.second].begin();it!=adj2[p.second].end();it++) {
			if(vis[*it]) continue;
			pq.push(ii(p.first+c[p.second] ,*it));
		}
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
typedef vector<ii> vii;
typedef long long ll;

#define sz(a) int((a).size())
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define tr(c,it) for(typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define present(c,val) ((c).find(val) != (c).end())
#define cpresent(c,val) (find(all(c),val) != (c).end())
#define rep(i, n) for(int i = 0; i < (n); ++i)
#define FOR(i, x, y) for(int i= (x); i<= (y); ++i)
#define FORR(i, x, y) for(int i= (y); i>= (x); --i)

#define imax numeric_limits<int>::max()
#define imin numeric_limits<int>::min()
#define lmax numeric_limits<ll>::max()
#define lmin numeric_limits<ll>::min()
#define debug(var) cerr<<#var<<" = "<<(var)<<endl;
#define debugarr(var,n) cerr<<#var<<" = { ";rep(i,n) cerr<<var[i]<<" ";cerr<<"}"<<endl;
#define debugmat(var,m,n) cerr<<#var<<" = \n";rep(i,m) {rep(j,n) cerr<<var[i][j]<<" ";cerr<<endl;}
#define sci(var) scanf("%d",&(var))
#define scll(var) scanf("%lld",&(var))
#define MOD ((int)1e9+7)

std::vector<int> adj2[1005];
std::vector<ii> adj1[1005];
int n,m,x,y,t[1005],c[1005],vis[1005];

void fill(int i) {
	memset(vis,0,sizeof vis);
	priority_queue<ii,vector<ii>,greater<ii> > pq;
	pq.push(ii(0,i));
	while(!pq.empty()) {
		ii p=pq.top();
		pq.pop();
		if(vis[p.second]) continue;
		vis[p.second]=1;
		adj2[i].pb(p.second);
		for(vector<ii>::iterator it=adj1[p.second].begin();it!=adj1[p.second].end();it++) {
			if(vis[it->first] || it->second+p.first>t[i]) continue;
			pq.push(ii(it->second+p.first,it->first));
		}
	}
}

int main() {
	cin>>n>>m>>x>>y;
	int a,b,c1;
	while(m--) {
		cin>>a>>b>>c1;
		adj1[a].pb(ii(b,c1));
		adj1[b].pb(ii(a,c1));
	}

	FOR(i,1,n) {
		cin>>t[i]>>c[i];
		fill(i);
	}
	memset(vis,0,sizeof vis);
	priority_queue<ii,vector<ii>,greater<ii> > pq;
	pq.push(ii(0,x));
	while(!pq.empty()) {
		ii p=pq.top();
		pq.pop();
		if(vis[p.second]) continue;
		vis[p.second]=1;
		if(p.second==y) {
			cout<<p.first<<endl;
			return 0;
		}
		for(vector<int>::iterator it=adj2[p.second].begin();it!=adj2[p.second].end();it++) {
			if(vis[*it]) continue;
			pq.push(ii(p.first+c[p.second] ,*it));
		}
	}
	cout<<"-1\n";
	return 0;
}


#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<math.h>
#include<string.h>
typedef long long ll;
using namespace std;
const int mod = 10;
const int N = 1010;
const long long INF = 1e18;
typedef pair<long long, int> par;

int n, m, x, y;
int cnt, cnt2, head[N], head2[N];
long long d[N][N], D[N];

struct edge
{
    int end;
    ll len;
    int next;
}e[1000005] ,e2[1000005]; //一个存正常，一个存反向

void add_edge(int u, int v, int w) //我们用邻接表来建图
{
    e[cnt].end = v;
    e[cnt].len = w;
    e[cnt].next = head[u];
    head[u] = cnt ++;
}

void Add_edge(int u, int v, int w)
{
    e2[cnt2].end = v;
    e2[cnt2].len = w;
    e2[cnt2].next = head2[u];
    head2[u] = cnt2 ++;
}

void dijstra(int k)
{
    for(int i = 1; i <= n; i ++) {
            d[k][i] = INF;
    }
    d[k][k] = 0;
    priority_queue< pair<long long, int> > q;
    q.push(make_pair(0, k));
    while(!q.empty()) {  //正常的最短路
        par cur;
        cur = q.top();
        q.pop();
        long long a = -cur.first;
        int b = cur.second;
        for(int i = head[b]; i != -1; i = e[i].next) {
            int en = e[i].end;
            long long len = a + e[i].len;
            if(d[k][en] > len) {
                d[k][en] = len;
                q.push(make_pair(-len, en));
            }
        }
    }
}

void Dijstra(int k)
{
    for(int i = 1; i <= n; i ++) {
            D[i] = INF;
    }
    D[k] = 0;
    priority_queue< pair<long long, int> > q;
    q.push(make_pair(0, k));
    while(!q.empty()) {
        par cur;
        cur = q.top();
        q.pop();
        long long a = -cur.first;
        int b = cur.second;
        for(int i = head2[b]; i != -1; i = e2[i].next) {
            int en = e2[i].end;
            long long len = a + e2[i].len;
            if(D[en] > len) {
                D[en] = len;
                q.push(make_pair(-len, en));
            }
        }
    }
}

int main()
{
    int a, b ,c;
    while(~scanf("%d%d", &n, &m)) {
        memset(head, -1, sizeof(head));
        memset(head2, -1, sizeof(head2));
        cnt = cnt2 = 0;
        scanf("%d%d", &x, &y);
        for(int i = 0; i < m; i ++) {
            scanf("%d%d%d", &a, &b, &c);
            add_edge(a, b, c);
            add_edge(b, a, c);
        }
        for(int i = 1; i <= n; i ++) {
            dijstra(i);
        }
        for(int i = 1; i <= n; i ++) {
            scanf("%d%d", &a, &b);
            for(int j = 1; j <= n; j ++) {
                if(d[i][j] <= a && i != j) {
                    Add_edge(i, j, b);
                }
            }
        }
        Dijstra(x);
        if(D[y] == INF) printf("-1\n");
        else printf("%I64d\n", D[y]);
    }
    return 0;
}


#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<math.h>
#include<string.h>
typedef long long ll;
using namespace std;
const int mod = 10;
const int N = 1010;
const int INF = 1e9;
typedef pair<long long, int> par;

int n, m, x, y;
int cnt, cnt2, head[N], head2[N];
long long d[N][N], D[N];

struct edge
{
    int end;
    ll len;
    int next;
}e[1000005] ,e2[1000005]; //一个存正常，一个存反向

void add_edge(int u, int v, int w) //我们用邻接表来建图
{
    e[cnt].end = v;
    e[cnt].len = w;
    e[cnt].next = head[u];
    head[u] = cnt ++;
}

void Add_edge(int u, int v, int w)
{
    e2[cnt2].end = v;
    e2[cnt2].len = w;
    e2[cnt2].next = head2[u];
    head2[u] = cnt2 ++;
}

void dijstra(int k)
{
    for(int i = 1; i <= n; i ++) {
            d[k][i] = INF;
    }
    d[k][k] = 0;
    priority_queue< pair<long long, int> > q;
    q.push(make_pair(0, k));
    while(!q.empty()) {  //正常的最短路
        par cur;
        cur = q.top();
        q.pop();
        long long a = -cur.first;
        int b = cur.second;
        for(int i = head[b]; i != -1; i = e[i].next) {
            int en = e[i].end;
            long long len = a + e[i].len;
            if(d[k][en] > len) {
                d[k][en] = len;
                q.push(make_pair(-len, en));
            }
        }
    }
}

void Dijstra(int k)
{
    for(int i = 1; i <= n; i ++) {
            D[i] = INF;
    }
    D[k] = 0;
    priority_queue< pair<long long, int> > q;
    q.push(make_pair(0, 1));
    while(!q.empty()) {
        par cur;
        cur = q.top();
        q.pop();
        long long a = -cur.first;
        int b = cur.second;
        for(int i = head[b]; i != -1; i = e2[i].next) {
            int en = e2[i].end;
            long long len = a + e2[i].len;
            if(D[en] > len) {
                D[en] = len;
                q.push(make_pair(-len, en));
            }
        }
    }
}

int main()
{
    int a, b ,c;
    while(~scanf("%d%d", &n, &m)) {
        memset(head, -1, sizeof(head));
        memset(head2, -1, sizeof(head2));
        cnt = cnt2 = 0;
        scanf("%d%d", &x, &y);
        for(int i = 0; i < m; i ++) {
            scanf("%d%d%d", &a, &b, &c);
            add_edge(a, b, c);
            add_edge(b, a, c);
        }
        for(int i = 1; i <= n; i ++) {
            dijstra(i);
        }
        for(int i = 1; i <= n; i ++) {
            scanf("%d%d", &a, &b);
            for(int j = 1; j <= n; j ++) {
                if(d[i][j] <= a) {
                    Add_edge(i, j, b);
                }
            }
        }
        Dijstra(x);
        if(D[y] == INF) printf("-1\n");
        else printf("%I64d\n", D[y]);
    }
    return 0;
}