#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define pb push_back
#define mp make_pair
#define sl short int
#define ll long long int
#define ull unsigned long long int
#define FOR(i,begin,end) for(ll i=begin;i<=end;++i)
typedef pair< ll,ll> pii;
const ll max_=1000 + 100;
vector < pii > a[max_];
ll n,m,k;
ll d[1000 + 10][1000 + 10];
vector < pii > g[max_];
pii taxi[max_];
int dijkstra()
{
	for(int str=1;str<=n;str++)
	{
		fill(d[str],d[str]+n,1e18);
    	d[str][str]=0;
    	ll u=0;
    	set < pii >s;
    	s.insert(mp(d[str][str],str));
    	while(!s.empty())
    	{
        	u=s.begin()->second;
        	s.erase(s.begin());
        	for(ll i=0;i<a[u].size();i++)
        	{
            	pii p=a[u][i];
            	if(d[str][p.first]>d[str][u]+p.second)
            	{
                	s.erase(mp(d[str][p.first],p.first));
                	d[str][p.first]=d[str][u]+p.second;
                	s.insert(mp(d[str][p.first],p.first));
            	}
        	}
    	}
    	s.clear();
    }
}
ll dis[max_];
int dijkstra2(int str)
{
    fill(dis,dis+n+10,1e18);
    dis[str]=0;
    ll u=0;
    set < pii >s1;
    s1.insert(mp(dis[str],str));
    while (!s1.empty())
    {
        u=s1.begin()->second;
        s1.erase(s1.begin());
        for(ll i=0;i<g[u].size();i++)
        {
            pii p=g[u][i];
            if(dis[p.first]>dis[u]+p.second)
            {
                s1.erase(mp(dis[p.first],p.first));
                dis[p.first]=dis[u]+p.second;
                //f[p.first]=u; //balayish to masir
                s1.insert(mp(dis[p.first],p.first));
            }
        }
    }
}

int main()
{
	int x,y;
	cin>>n>>m>>x>>y;
	int s,e,w;
	for(int i=1;i<=m;i++)
	{
		cin>>s>>e>>w;
		a[s].pb(mp(e,w));
        a[e].pb(mp(s,w));
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			d[i][j]=1e18;
		}
	}
	dijkstra();
	int di,mo;
 	for(int i=1;i<=n;i++)
    {
        cin>>di>>mo;
        for(int j=1;j<=n;j++)
        {
            if(d[i][j]<=di)
            {
                g[i].pb(mp(j,mo));
            }
        }
    }
	dijkstra2(x);
	if(dis[y]==1e18)
		dis[y]=-1;
	cout<<dis[y]<<endl;
}


#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define pb push_back
#define mp make_pair
#define sl short int
#define ll long long int
#define ull unsigned long long int
#define FOR(i,begin,end) for(ll i=begin;i<=end;++i)
typedef pair< ll,ll> pii;
const ll max_=10000 + 10;
vector < pii > a[max_];
ll n,m,k;
ll d[10000][10000];
vector < pii > g[max_];
pii taxi[max_];
int dijkstra()
{
	for(int str=1;str<=n;str++)
	{
		fill(d[str],d[str]+n,1e18);
    	d[str][str]=0;
    	ll u=0;
    	set < pii >s;
    	s.insert(mp(d[str][str],str));
    	while(!s.empty())
    	{
        	u=s.begin()->second;
        	s.erase(s.begin());
        	for(ll i=0;i<a[u].size();i++)
        	{
            	pii p=a[u][i];
            	if(d[str][p.first]>d[str][u]+p.second)
            	{
                	s.erase(mp(d[str][p.first],p.first));
                	d[str][p.first]=d[str][u]+p.second;
                	s.insert(mp(d[str][p.first],p.first));
            	}
        	}
    	}
    	s.clear();
    }
}

//////////////////////////////
//////////////////////////////
//////////////////////////////
//////////////////////////////
//////////////////////////////
//////////////////////////////
//////////////////////////////
//////////////////////////////

ll dis[max_];
int dijkstra2(int str)
{
    fill(dis,dis+n+10,1e18);
    dis[str]=0;
    ll u=0;
    set < pii >s1;
    s1.insert(mp(dis[str],str));
    while (!s1.empty())
    {
        u=s1.begin()->second;
        s1.erase(s1.begin());
        for(ll i=0;i<g[u].size();i++)
        {
            pii p=g[u][i];
            if(dis[p.first]>dis[u]+p.second)
            {
                s1.erase(mp(dis[p.first],p.first));
                dis[p.first]=dis[u]+p.second;
                //f[p.first]=u; //balayish to masir
                s1.insert(mp(dis[p.first],p.first));
            }
        }
    }
}

int main()
{
	int x,y;
	cin>>n>>m>>x>>y;
	for(int i=1;i<=m;i++)
	{
		int s,e,w;
		cin>>s>>e>>w;
		a[s].pb(mp(e,w));
        a[e].pb(mp(s,w));
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			d[i][j]=1e18;
		}
	}
	dijkstra();
	/*
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(d[i][j]==0 && i!=j)
			{
				d[i][j]=1e18;
			}
			cout<<d[i][j]<<" ";
		}
		cout<<endl;
	}
*/
	int di,mo;
 	for(int i=1;i<=n;i++)
    {
        cin>>di>>mo;
        for(int j=1;j<=n;j++)
        {
            if(d[i][j]<=di)
            {
                g[i].pb(mp(j,mo));
            }
        }
    }
	dijkstra2(x);
	cout<<dis[y]<<endl;
	/*
	for(int i=1;i<=n;i++)
	{
		cout<<dis[i]<<" ";
	}
	*/
}


#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
#define N 1040
#define M 1004000
struct edge{int t,next,v;}ed[M*2],ed2[M*2];
int dis[N],vis[N],n,m,a,b,c,cnt,cnt2,head[N],head2[N],s,t;
void adde(int f,int t,int v){ed[++cnt]=(edge){t,head[f],v};head[f]=cnt;ed[++cnt]=(edge){f,head[t],v};head[t]=cnt;}
void adde2(int f,int t,int v){ed2[++cnt2]=(edge){t,head2[f],v};head2[f]=cnt2;}
void dijkstra(int s)
{
	priority_queue<pair<int,int> > s1;
	memset(dis,0x3f,sizeof(dis));
	memset(vis,0,sizeof(vis));
	dis[s]=0;
	s1.push(make_pair(0,s));
	while(!s1.empty())
	{
		pair<int,int> s2=s1.top();s1.pop();int s=s2.second;
		if(vis[s])continue;vis[s]=1;
		for(int i=head[s];i;i=ed[i].next)
		if(dis[ed[i].t]>dis[s]+ed[i].v)
		dis[ed[i].t]=dis[s]+ed[i].v,s1.push(make_pair(-dis[ed[i].t],ed[i].t));
	}
}
void dijkstra2(int s)
{
	priority_queue<pair<int,int> > s1;
	memset(dis,0x3f,sizeof(dis));
	memset(vis,0,sizeof(vis));
	dis[s]=0;
	s1.push(make_pair(0,s));
	while(!s1.empty())
	{
		pair<int,int> s2=s1.top();s1.pop();int s=s2.second;
		if(vis[s])continue;vis[s]=1;
		for(int i=head2[s];i;i=ed2[i].next)
		if(dis[ed2[i].t]>dis[s]+ed2[i].v)
		dis[ed2[i].t]=dis[s]+ed2[i].v,s1.push(make_pair(-dis[ed2[i].t],ed2[i].t));
	}
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&s,&t);
	for(int i=1;i<=m;i++)scanf("%d%d%d",&a,&b,&c),adde(a,b,c);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&a,&b);
		dijkstra(i);
		for(int j=1;j<=n;j++)if(dis[j]<=a)adde2(i,j,b);
	}
	dijkstra2(s);printf("%d\n",dis[t]);
}


#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
#define N 1040
#define M 1004000
struct edge{int t,next,v;}ed[M*2],ed2[M*2];
long long dis[N];int vis[N],n,m,a,b,c,cnt,cnt2,head[N],head2[N],s,t;
void adde(int f,int t,int v){ed[++cnt]=(edge){t,head[f],v};head[f]=cnt;ed[++cnt]=(edge){f,head[t],v};head[t]=cnt;}
void adde2(int f,int t,int v){ed2[++cnt2]=(edge){t,head2[f],v};head2[f]=cnt2;}
void dijkstra(int s)
{
	priority_queue<pair<long long,int> > s1;
	memset(dis,0x3f,sizeof(dis));
	memset(vis,0,sizeof(vis));
	dis[s]=0;
	s1.push(make_pair(0,s));
	while(!s1.empty())
	{
		pair<int,int> s2=s1.top();s1.pop();int s=s2.second;
		if(vis[s])continue;vis[s]=1;
		for(int i=head[s];i;i=ed[i].next)
		if(dis[ed[i].t]>dis[s]+ed[i].v)
		dis[ed[i].t]=dis[s]+ed[i].v,s1.push(make_pair(-dis[ed[i].t],ed[i].t));
	}
}
void dijkstra2(int s)
{
	priority_queue<pair<long long,int> > s1;
	memset(dis,0x3f,sizeof(dis));
	memset(vis,0,sizeof(vis));
	dis[s]=0;
	s1.push(make_pair(0,s));
	while(!s1.empty())
	{
		pair<int,int> s2=s1.top();s1.pop();int s=s2.second;
		if(vis[s])continue;vis[s]=1;
		for(int i=head2[s];i;i=ed2[i].next)
		if(dis[ed2[i].t]>dis[s]+ed2[i].v)
		dis[ed2[i].t]=dis[s]+ed2[i].v,s1.push(make_pair(-dis[ed2[i].t],ed2[i].t));
	}
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&s,&t);
	for(int i=1;i<=m;i++)scanf("%d%d%d",&a,&b,&c),adde(a,b,c);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&a,&b);
		dijkstra(i);
		for(int j=1;j<=n;j++)if(dis[j]<=a)adde2(i,j,b);
	}
	dijkstra2(s);printf("%lld\n",dis[t]>1e17?-1:dis[t]);
}


#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
#define N 1040
#define M 1004000
struct edge{int t,next,v;}ed[M*2],ed2[M*2];
int dis[N],vis[N],n,m,a,b,c,cnt,cnt2,head[N],head2[N],s,t;
void adde(int f,int t,int v){ed[++cnt]=(edge){t,head[f],v};head[f]=cnt;ed[++cnt]=(edge){f,head[t],v};head[t]=cnt;}
void adde2(int f,int t,int v){ed2[++cnt2]=(edge){t,head[f],v};head[f]=cnt2;}
void dijkstra(int s)
{
	priority_queue<pair<int,int> > s1;
	memset(dis,0x3f,sizeof(dis));
	memset(vis,0,sizeof(vis));
	dis[s]=0;
	s1.push(make_pair(0,s));
	while(!s1.empty())
	{
		pair<int,int> s2=s1.top();s1.pop();int s=s2.second;
		if(vis[s])continue;vis[s]=1;
		for(int i=head[s];i;i=ed[i].next)
		if(dis[ed[i].t]>dis[s]+ed[i].v)
		dis[ed[i].t]=dis[s]+ed[i].v,s1.push(make_pair(-dis[ed[i].t],ed[i].t));
	}
}
void dijkstra2(int s)
{
	priority_queue<pair<int,int> > s1;
	memset(dis,0x3f,sizeof(dis));
	memset(vis,0,sizeof(vis));
	dis[s]=0;
	s1.push(make_pair(0,s));
	while(!s1.empty())
	{
		pair<int,int> s2=s1.top();s1.pop();int s=s2.second;
		if(vis[s])continue;vis[s]=1;
		for(int i=head2[s];i;i=ed2[i].next)
		if(dis[ed2[i].t]>dis[s]+ed2[i].v)
		dis[ed2[i].t]=dis[s]+ed2[i].v,s1.push(make_pair(-dis[ed[i].t],ed2[i].t));
	}
}
int main()
{
	scanf("%d%d%d%d",&n,&m,&s,&t);
	for(int i=1;i<=m;i++)scanf("%d%d%d",&a,&b,&c),adde(a,b,c);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&a,&b);
		dijkstra(i);
		for(int j=1;j<=n;j++)if(dis[j]<=a)adde2(i,j,b);
	}
	dijkstra2(s);printf("%d\n",dis[t]);
}


#include<bits/stdc++.h>
using namespace std;
#define M 1000010
#define int long long
#define INF 92233720367966
inline int read(){
	int s=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){s=s*10+c-48;c=getchar();}
	return s*f;
}
struct Node{
	int u,v,w;
}Edge[M];
struct cmp{
	int u,dis;
	bool operator<(const cmp &x)const{
		return dis>x.dis;
	}
};
vector<cmp> q[M];
int n,m,u,v,w,s,t,Goal[M],cost[M];
int head[M],cnt;
int vis[M],dis[M];
void add(int u,int v,int w){
	q[u].push_back((cmp){v,w});
	return;
}
void addEdge(int u,int v,int w){
	Edge[++cnt]=(Node){head[u],v,w};
	head[u]=cnt;
	return;
}
void DijkstraBuild(int Start){
	priority_queue<cmp> Q;
	for(int i=1;i<=n;i++){
		dis[i]=INF;
		vis[i]=0;
	}
	dis[Start]=0;
	Q.push((cmp){Start,0});
	while(!Q.empty()){
		int u=Q.top().u;Q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=0;i<q[u].size();i++){
			int v=q[u][i].u,w=q[u][i].dis;
			if(!vis[v]&&dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				Q.push((cmp){v,dis[v]});
			}
		}
	}
	for(int i=1;i<=n;i++)
		if(i!=Start&&Goal[Start]>=dis[i])
			addEdge(Start,i,cost[Start]);
	return;
}
void Dijkstra(int Start){
	priority_queue<cmp> Q;
	for(int i=1;i<=n;i++){
		dis[i]=INF;
		vis[i]=0;
	}
	dis[Start]=0;
	Q.push((cmp){Start,0});
	while(!Q.empty()){
		int u=Q.top().u;Q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=head[u];i;i=Edge[i].u){
			int v=Edge[i].v;
			if(dis[v]>dis[u]+Edge[i].w){
				dis[v]=dis[u]+Edge[i].w;
				Q.push((cmp){v,dis[v]});
			}
		}
	}
	if(dis[t]==INF) printf("-1\n");
	else printf("%lld\n",dis[t]);
	return;
}
signed main(void){
	n=read();m=read();s=read();t=read();
	while(m--){
		u=read();v=read();w=read();
		add(u,v,w);
		add(v,u,w);
	}
	for(int i=1;i<=n;i++){
		Goal[i]=read();
		cost[i]=read();
	}
	for(int i=1;i<=n;i++)
		DijkstraBuild(i);
	Dijkstra(s);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define M 50010
#define int long long
#define INF 92233720367966
inline int read(){
	int s=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){s=s*10+c-48;c=getchar();}
	return s*f;
}
struct Node{
	int u,v,w;
}Edge[M];
struct cmp{
	int u,dis;
	bool operator<(const cmp &x)const{
		return dis>x.dis;
	}
};
vector<cmp> q[M];
int n,m,u,v,w,s,t,Goal[M],cost[M];
int head[M],cnt;
int vis[M],dis[M];
void add(int u,int v,int w){
	q[u].push_back((cmp){v,w});
	return;
}
void addEdge(int u,int v,int w){
	Edge[++cnt]=(Node){head[u],v,w};
	head[u]=cnt;
	return;
}
void DijkstraBuild(int Start){
	priority_queue<cmp> Q;
	for(int i=1;i<=n;i++){
		dis[i]=INF;
		vis[i]=0;
	}
	dis[Start]=0;
	Q.push((cmp){Start,0});
	while(!Q.empty()){
		int u=Q.top().u;Q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=0;i<q[u].size();i++){
			int v=q[u][i].u,w=q[u][i].dis;
			if(!vis[v]&&dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				Q.push((cmp){v,dis[v]});
			}
		}
	}
	for(int i=1;i<=n;i++)
		if(i!=Start&&Goal[Start]>=dis[i])
			addEdge(Start,i,cost[Start]);
	return;
}
void Dijkstra(int Start){
	priority_queue<cmp> Q;
	for(int i=1;i<=n;i++){
		dis[i]=INF;
		vis[i]=0;
	}
	dis[Start]=0;
	Q.push((cmp){Start,0});
	while(!Q.empty()){
		int u=Q.top().u;Q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=head[u];i;i=Edge[i].u){
			int v=Edge[i].v;
			if(dis[v]>dis[u]+Edge[i].w){
				dis[v]=dis[u]+Edge[i].w;
				Q.push((cmp){v,dis[v]});
			}
		}
	}
	if(dis[t]==INF) printf("-1\n");
	else printf("%lld\n",dis[t]);
	return;
}
signed main(void){
	n=read();m=read();s=read();t=read();
	while(m--){
		u=read();v=read();w=read();
		add(u,v,w);
		add(v,u,w);
	}
	for(int i=1;i<=n;i++){
		Goal[i]=read();
		cost[i]=read();
	}
	for(int i=1;i<=n;i++)
		DijkstraBuild(i);
	Dijkstra(s);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define M 5010
#define int long long
#define INF 92233720367966
inline int read(){
	int s=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){s=s*10+c-48;c=getchar();}
	return s*f;
}
struct Node{
	int u,v,w;
}Edge[M];
struct cmp{
	int u,dis;
	bool operator<(const cmp &x)const{
		return dis>x.dis;
	}
};
vector<cmp> q[M];
int n,m,u,v,w,s,t,Goal[M],cost[M];
int head[M],cnt;
int vis[M],dis[M];
void add(int u,int v,int w){
	q[u].push_back((cmp){v,w});
	return;
}
void addEdge(int u,int v,int w){
	Edge[++cnt]=(Node){head[u],v,w};
	head[u]=cnt;
	return;
}
void DijkstraBuild(int Start){
	priority_queue<cmp> Q;
	for(int i=1;i<=n;i++){
		dis[i]=INF;
		vis[i]=0;
	}
	dis[Start]=0;
	Q.push((cmp){Start,0});
	while(!Q.empty()){
		int u=Q.top().u;Q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=0;i<q[u].size();i++){
			int v=q[u][i].u,w=q[u][i].dis;
			if(!vis[v]&&dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				Q.push((cmp){v,dis[v]});
			}
		}
	}
	for(int i=1;i<=n;i++)
		if(i!=Start&&Goal[Start]>=dis[i])
			addEdge(Start,i,cost[Start]);
	return;
}
void Dijkstra(int Start){
	priority_queue<cmp> Q;
	for(int i=1;i<=n;i++){
		dis[i]=INF;
		vis[i]=0;
	}
	dis[Start]=0;
	Q.push((cmp){Start,0});
	while(!Q.empty()){
		int u=Q.top().u;Q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=head[u];i;i=Edge[i].u){
			int v=Edge[i].v;
			if(dis[v]>dis[u]+Edge[i].w){
				dis[v]=dis[u]+Edge[i].w;
				Q.push((cmp){v,dis[v]});
			}
		}
	}
	if(dis[t]==INF) printf("-1\n");
	else printf("%lld\n",dis[t]);
	return;
}
signed main(void){
	n=read();m=read();s=read();t=read();
	while(m--){
		u=read();v=read();w=read();
		add(u,v,w);
		add(v,u,w);
	}
	for(int i=1;i<=n;i++){
		Goal[i]=read();
		cost[i]=read();
	}
	for(int i=1;i<=n;i++)
		DijkstraBuild(i);
	Dijkstra(s);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define M 5000010
#define int long long
#define INF 92233720367966
inline int read(){
	int s=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){s=s*10+c-48;c=getchar();}
	return s*f;
}
struct Node{
	int u,v,w;
}Edge[M];
struct cmp{
	int u,dis;
	bool operator<(const cmp &x)const{
		return dis>x.dis;
	}
};
vector<cmp> q[M];
int n,m,u,v,w,s,t,Goal[M],cost[M];
int head[M],cnt;
int vis[M],dis[M];
void add(int u,int v,int w){
	q[u].push_back((cmp){v,w});
	return;
}
void addEdge(int u,int v,int w){
	Edge[++cnt]=(Node){head[u],v,w};
	head[u]=cnt;
	return;
}
void DijkstraBuild(int Start){
	priority_queue<cmp> Q;
	for(int i=1;i<=n;i++){
		dis[i]=INF;
		vis[i]=0;
	}
	dis[Start]=0;
	Q.push((cmp){Start,0});
	while(!Q.empty()){
		int u=Q.top().u;Q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=0;i<q[u].size();i++){
			int v=q[u][i].u,w=q[u][i].dis;
			if(!vis[v]&&dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				Q.push((cmp){v,dis[v]});
			}
		}
	}
	for(int i=1;i<=n;i++)
		if(i!=Start&&Goal[Start]>=dis[i])
			addEdge(Start,i,cost[Start]);
	return;
}
void Dijkstra(int Start){
	priority_queue<cmp> Q;
	for(int i=1;i<=n;i++){
		dis[i]=INF;
		vis[i]=0;
	}
	dis[Start]=0;
	Q.push((cmp){Start,0});
	while(!Q.empty()){
		int u=Q.top().u;Q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=head[u];i;i=Edge[i].u){
			int v=Edge[i].v;
			if(dis[v]>dis[u]+Edge[i].w){
				dis[v]=dis[u]+Edge[i].w;
				Q.push((cmp){v,dis[v]});
			}
		}
	}
	if(dis[t]==INF) printf("-1\n");
	else printf("%lld\n",dis[t]);
	return;
}
signed main(void){
	n=read();m=read();s=read();t=read();
	while(m--){
		u=read();v=read();w=read();
		add(u,v,w);
		add(v,u,w);
	}
	for(int i=1;i<=n;i++){
		Goal[i]=read();
		cost[i]=read();
	}
	for(int i=1;i<=n;i++)
		DijkstraBuild(i);
	Dijkstra(s);
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define INF 999999999999
#define MAXN 1000+5
typedef long long int ll;

ll d[MAXN],d1[MAXN];
int inq[MAXN],inq1[MAXN];
vector<pair<int, int> >E[MAXN],cost[MAXN];
int mp[MAXN][MAXN],car[MAXN][MAXN];

void add_edge(int x, int y, int z)
{
    E[x].push_back(make_pair(y, z));
    E[y].push_back(make_pair(x, z));
}

void init(int n)
{
    for (int i=0; i<=n; i++) E[i].clear(),cost[i].clear();
    for (int i=0; i<=n; i++) d[i] = INF,d1[i]=INF;
}

void spfa1(int s)
{
    queue<int>q;
    q.push(s);
    d1[s] = 0;
    inq1[s] = 1;
    while (!q.empty())
    {
        int now = q.front();
        q.pop();
        inq1[now] = 0;
        for (int i = 0; i < cost[now].size(); i++)
        {
            int v = cost[now][i].first;
            if (d1[v] > d1[now] + cost[now][i].second)
            {
                d1[v] = d1[now] + cost[now][i].second;
                if (inq1[v] == 0)
                {
                    inq1[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

void spfa(int s)
{
    queue<int>q;
    for (int i=0; i<=MAXN; i++) d[i]=INF;
    q.push(s);
    d[s] = 0;
    inq[s] = 1;
    while (!q.empty())
    {
        int now = q.front();
        q.pop();
        inq[now] = 0;
        for (int i = 0; i < E[now].size(); i++)
        {
            int v = E[now][i].first;
            if (d[v] > d[now] + E[now][i].second)
            {
                d[v] = d[now] + E[now][i].second;
                if (inq[v] == 0)
                {
                    inq[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    int m, n, s,t,x,y,z;
    memset(car,0,sizeof(car));
    scanf("%d %d %d %d",&n,&m,&s,&t);
    init(n);
    for(int i=0; i<m; i++)
    {
        scanf("%d %d %d",&x,&y,&z);
        add_edge(x,y,z);
    }
    for(int i=1; i<=n; i++)
    {
        scanf("%d %d",&x,&y);
        cost[i].push_back(make_pair(i,0));
        spfa(i);
        for(int j=1;j<=n;j++)
        {
            if(d[j]<=x)
                cost[i].push_back(make_pair(j,y));
        }
    }
    spfa1(s);
    if(d1[t]==INF) printf("-1\n");
    else printf("%I64d\n",d1[t]);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define INF 99999999
#define MAXN 1000+5
typedef long long int ll;

ll d[MAXN],d1[MAXN];
int inq[MAXN],inq1[MAXN];
vector<pair<int, int> >E[MAXN],cost[MAXN];
int mp[MAXN][MAXN],car[MAXN][MAXN];

void add_edge(int x, int y, int z)
{
    E[x].push_back(make_pair(y, z));
    E[y].push_back(make_pair(x, z));
}

void init(int n)
{
    for (int i=0; i<=n; i++) E[i].clear(),cost[i].clear();
    for (int i=0; i<=n; i++) d[i] = INF,d1[i]=INF;
}

void spfa1(int s)
{
    queue<int>q;
    q.push(s);
    d1[s] = 0;
    inq1[s] = 1;
    while (!q.empty())
    {
        int now = q.front();
        q.pop();
        inq1[now] = 0;
        for (int i = 0; i < cost[now].size(); i++)
        {
            int v = cost[now][i].first;
            if (d1[v] > d1[now] + cost[now][i].second)
            {
                d1[v] = d1[now] + cost[now][i].second;
                if (inq1[v] == 0)
                {
                    inq1[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

void spfa(int s)
{
    queue<int>q;
    for (int i=0; i<=MAXN; i++) d[i]=INF;
    q.push(s);
    d[s] = 0;
    inq[s] = 1;
    while (!q.empty())
    {
        int now = q.front();
        q.pop();
        inq[now] = 0;
        for (int i = 0; i < E[now].size(); i++)
        {
            int v = E[now][i].first;
            if (d[v] > d[now] + E[now][i].second)
            {
                d[v] = d[now] + E[now][i].second;
                if (inq[v] == 0)
                {
                    inq[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    int m, n, s,t,x,y,z;
    memset(car,0,sizeof(car));
    scanf("%d %d %d %d",&n,&m,&s,&t);
    init(n);
    for(int i=0; i<m; i++)
    {
        scanf("%d %d %d",&x,&y,&z);
        add_edge(x,y,z);
    }
    for(int i=1; i<=n; i++)
    {
        scanf("%d %d",&x,&y);
        cost[i].push_back(make_pair(i,0));
        spfa(i);
        for(int j=1;j<=n;j++)
        {
            if(d[j]<=x)
                cost[i].push_back(make_pair(j,y));
        }
    }
    //if(s==t) printf("0\n");
    spfa1(s);
    if(d1[t]==INF) printf("-1\n");
    else printf("%I64d\n",d1[t]);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define INF 99999999
#define MAXN 1000+5
typedef long long int ll;

ll d[MAXN],d1[MAXN];
int inq[MAXN],inq1[MAXN];
vector<pair<int, int> >E[MAXN],cost[MAXN];
int mp[MAXN][MAXN],car[MAXN][MAXN];

void add_edge(int x, int y, int z)
{
    E[x].push_back(make_pair(y, z));
    E[y].push_back(make_pair(x, z));
}

void init(int n)
{
    for (int i=0; i<=n; i++) E[i].clear(),cost[i].clear();
    for (int i=0; i<=n; i++) d[i] = INF,d1[i]=INF;
}

void spfa1(int s)
{
    queue<int>q;
    for (int i=0; i<=MAXN; i++) d1[i]=INF;
    q.push(s);
    d1[s] = 0;
    inq1[s] = 1;
    while (!q.empty())
    {
        int now = q.front();
        q.pop();
        inq1[now] = 0;
        for (int i = 0; i < cost[now].size(); i++)
        {
            int v = cost[now][i].first;
            if (d1[v] > d1[now] + cost[now][i].second)
            {
                d1[v] = d1[now] + cost[now][i].second;
                if (inq1[v] == 0)
                {
                    inq1[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

void spfa(int s)
{
    queue<int>q;
    q.push(s);
    d[s] = 0;
    inq[s] = 1;
    while (!q.empty())
    {
        int now = q.front();
        q.pop();
        inq[now] = 0;
        for (int i = 0; i < E[now].size(); i++)
        {
            int v = E[now][i].first;
            if (d[v] > d[now] + E[now][i].second)
            {
                d[v] = d[now] + E[now][i].second;
                if (inq[v] == 0)
                {
                    inq[v] = 1;
                    q.push(v);
                }
            }
        }
    }
}

int main()
{
    int m, n, s,t,x,y,z;
    memset(car,0,sizeof(car));
    scanf("%d %d %d %d",&n,&m,&s,&t);
    init(n);
    for(int i=0; i<m; i++)
    {
        scanf("%d %d %d",&x,&y,&z);
        add_edge(x,y,z);
    }
    for(int i=1; i<=n; i++)
    {
        scanf("%d %d",&x,&y);
        cost[i].push_back(make_pair(i,0));
        spfa(i);
        for(int j=1;j<=n;j++)
        {
            if(d[j]<=x)
                cost[i].push_back(make_pair(j,y));
        }
    }
    //if(s==t) printf("0\n");
    spfa1(s);
    if(d1[t]==INF) printf("-1\n");
    else printf("%I64d\n",d1[t]);
    return 0;
}


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

using namespace std;

const int maxn=1005;

inline int read()
{
	int p=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){p=(p<<1)+(p<<3)+(c^48),c=getchar();}
	return p*f;
}

struct Edge
{
	int to,dis,nxt;
}a[maxn*maxn];
int cnt,first[maxn];

inline void addedge(int from,int to,int dis)
{
	a[++cnt]=(Edge){to,dis,first[from]};
	first[from]=cnt;
}

struct Node
{
	int num,dis;
	bool friend operator <(Node a,Node b)
	{
		return a.dis>b.dis;
	}
};
int n,dis[maxn];
bool vis[maxn];

inline void dij(int s)
{
	memset(vis,0,sizeof(vis));
	for(register int i=1;i<=n;i++) dis[i]=2e9+10;
	priority_queue<Node>q;
	q.push((Node){s,0});
	dis[s]=0;
	while(!q.empty())
	{
		int u=q.top().num;
		q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(register int i=first[u];i;i=a[i].nxt)
		{
			int v=a[i].to;
			if(dis[v]>dis[u]+a[i].dis)
			{
				dis[v]=dis[u]+a[i].dis;
				q.push((Node){v,dis[v]});
			}
		}
	}
}

int d[maxn][maxn];

inline void spfa(int s,int lim,int w)
{
	memset(vis,0,sizeof(vis));
	for(register int i=1;i<=n;i++) dis[i]=2e9+10;
	queue<int>q;
	q.push(s);
	vis[s]=1;
	dis[s]=0;
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		for(register int v=1;v<=n;v++)
		{
			if(!d[u][v]) continue;
			if(dis[v]>dis[u]+d[u][v])
			{
				dis[v]=dis[u]+d[u][v];
				if(dis[v]<=lim) addedge(s,v,w);
				if(!vis[v])
				{
					q.push(v);
					vis[v]=1;
				}
			}
		}
	}
}

int main()
{
	int m,s,t;
	n=read(),m=read();
	s=read(),t=read();
	for(register int i=1;i<=m;i++)
	{
		int u,v,w;
		u=read(),v=read(),w=read();
		d[u][v]=d[v][u]=w;
	}
	for(register int i=1;i<=n;i++)
	{
		int t,c;
		t=read(),c=read();
		spfa(i,t,c);
	}
	dij(s);
	if(dis[t]==2e9+10) cout<<"-1";
	else cout<<dis[t];
	return 0;
}


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

using namespace std;
#define int long long

const int maxn=1005;

inline int read()
{
	int p=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){p=(p<<1)+(p<<3)+(c^48),c=getchar();}
	return p*f;
}

struct Edge
{
	int to,dis,nxt;
}a[maxn*maxn];
int cnt,first[maxn];

inline void addedge(int from,int to,int dis)
{
	a[++cnt]=(Edge){to,dis,first[from]};
	first[from]=cnt;
}

struct Node
{
	int num,dis;
	bool friend operator <(Node a,Node b)
	{
		return a.dis>b.dis;
	}
};
int n,dis[maxn];
bool vis[maxn];

inline void dij(int s)
{
	memset(vis,0,sizeof(vis));
	for(register int i=1;i<=n;i++) dis[i]=1e12+10;
	priority_queue<Node>q;
	q.push((Node){s,0});
	dis[s]=0;
	while(!q.empty())
	{
		int u=q.top().num;
		q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(register int i=first[u];i;i=a[i].nxt)
		{
			int v=a[i].to;
			if(dis[v]>dis[u]+a[i].dis)
			{
				dis[v]=dis[u]+a[i].dis;
				q.push((Node){v,dis[v]});
			}
		}
	}
}

int d[maxn][maxn];

inline void spfa(int s,int lim,int w)
{
	memset(vis,0,sizeof(vis));
	for(register int i=1;i<=n;i++) dis[i]=1e12+10;
	queue<int>q;
	q.push(s);
	vis[s]=1;
	dis[s]=0;
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		for(register int v=1;v<=n;v++)
		{
			if(!d[u][v]) continue;
			if(dis[v]>dis[u]+d[u][v])
			{
				dis[v]=dis[u]+d[u][v];
				if(dis[v]<=lim) addedge(s,v,w);
				if(!vis[v])
				{
					q.push(v);
					vis[v]=1;
				}
			}
		}
	}
}

signed main()
{
	int m,s,t;
	n=read(),m=read();
	s=read(),t=read();
	for(register int i=1;i<=m;i++)
	{
		int u,v,w;
		u=read(),v=read(),w=read();
		d[u][v]=d[v][u]=w;
	}
	for(register int i=1;i<=n;i++)
	{
		int t,c;
		t=read(),c=read();
		spfa(i,t,c);
	}
	dij(s);
	if(dis[t]==1e12+10) cout<<"-1";
	else cout<<dis[t];
	return 0;
}


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

using namespace std;
#define int long long

const int maxn=1005;

inline int read()
{
	int p=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){p=(p<<1)+(p<<3)+(c^48),c=getchar();}
	return p*f;
}

struct Edge
{
	int to,dis,nxt;
}a[maxn*maxn];
int cnt,first[maxn];

inline void addedge(int from,int to,int dis)
{
	a[++cnt]=(Edge){to,dis,first[from]};
	first[from]=cnt;
}

struct Node
{
	int num,dis;
	bool friend operator <(Node a,Node b)
	{
		return a.dis>b.dis;
	}
};
int n,dis[maxn],d[maxn][maxn];
bool vis[maxn];

inline void dij(int s,int lim,int w)
{
	memset(vis,0,sizeof(vis));
	for(register int i=1;i<=n;i++) dis[i]=1e12+10;
	priority_queue<Node>q;
	q.push((Node){s,0});
	dis[s]=0;
	while(!q.empty())
	{
		int u=q.top().num;
		q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(register int v=1;v<=n;v++)
		{
			if(!d[u][v]) continue;
			if(dis[v]>dis[u]+d[u][v])
			{
				dis[v]=dis[u]+d[u][v];
				if(dis[v]<=lim) addedge(s,v,w);
				q.push((Node){v,dis[v]});
			}
		}
	}
}

inline void spfa(int s)
{
	memset(vis,0,sizeof(vis));
	for(register int i=1;i<=n;i++) dis[i]=1e12+10;
	queue<int>q;
	q.push(s);
	vis[s]=1;
	dis[s]=0;
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		for(register int i=first[u];i;i=a[i].nxt)
		{
			int v=a[i].to;
			if(dis[v]>dis[u]+a[i].dis)
			{
				dis[v]=dis[u]+a[i].dis;
				if(!vis[v])
				{
					vis[v]=1;
					q.push(v);
				}
			}
		}
	}
}

signed main()
{
	int m,s,t;
	n=read(),m=read();
	s=read(),t=read();
	for(register int i=1;i<=m;i++)
	{
		int u,v,w;
		u=read(),v=read(),w=read();
		d[u][v]=d[v][u]=w;
	}
	for(register int i=1;i<=n;i++)
	{
		int t,c;
		t=read(),c=read();
		dij(i,t,c);
	}
	spfa(s);
	if(dis[t]==1e12+10) cout<<"-1";
	else cout<<dis[t];
	return 0;
}


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

using namespace std;
#define int long long

const int maxn=1005;

inline int read()
{
	int p=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){p=(p<<1)+(p<<3)+(c^48),c=getchar();}
	return p*f;
}

struct Edge
{
	int to,dis,nxt;
}a[maxn*maxn],z[maxn<<1];
int cnt,first[maxn],num,fir[maxn];

inline void addedge(int from,int to,int dis)
{
	a[++cnt]=(Edge){to,dis,first[from]};
	first[from]=cnt;
}

inline void add(int from,int to,int dis)
{
	z[++num]=(Edge){to,dis,fir[from]};
	fir[from]=num;
}

struct Node
{
	int num,dis;
	bool friend operator <(Node a,Node b)
	{
		return a.dis>b.dis;
	}
};
int n,dis[maxn],d[maxn][maxn];
bool vis[maxn];

inline void dij(int s,int lim,int w)
{
	memset(vis,0,sizeof(vis));
	for(register int i=1;i<=n;i++) dis[i]=1e12+10;
	priority_queue<Node>q;
	q.push((Node){s,0});
	dis[s]=0;
	while(!q.empty())
	{
		int u=q.top().num;
		q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(register int i=fir[u];i;i=z[i].nxt)
		{
			int v=z[i].to;
			if(dis[v]>dis[u]+z[i].dis)
			{
				dis[v]=dis[u]+z[i].dis;
				if(dis[v]<=lim) addedge(s,v,w);
				q.push((Node){v,dis[v]});
			}
		}
	}
}

inline void spfa(int s)
{
	memset(vis,0,sizeof(vis));
	for(register int i=1;i<=n;i++) dis[i]=1e12+10;
	queue<int>q;
	q.push(s);
	vis[s]=1;
	dis[s]=0;
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		for(register int i=first[u];i;i=a[i].nxt)
		{
			int v=a[i].to;
			if(dis[v]>dis[u]+a[i].dis)
			{
				dis[v]=dis[u]+a[i].dis;
				if(!vis[v])
				{
					vis[v]=1;
					q.push(v);
				}
			}
		}
	}
}

signed main()
{
	int m,s,t;
	n=read(),m=read();
	s=read(),t=read();
	for(register int i=1;i<=m;i++)
	{
		int u,v,w;
		u=read(),v=read(),w=read();
		add(u,v,w),add(v,u,w);
	}
	for(register int i=1;i<=n;i++)
	{
		int t,c;
		t=read(),c=read();
		dij(i,t,c);
	}
	spfa(s);
	if(dis[t]==1e12+10) cout<<"-1";
	else cout<<dis[t];
	return 0;
}


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

using namespace std;

const int maxn=1005;

inline int read()
{
	int p=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){p=(p<<1)+(p<<3)+(c^48),c=getchar();}
	return p*f;
}

struct Edge
{
	int to,dis,nxt;
}a[maxn*3];
int cnt,first[maxn];

inline void addedge(int from,int to,int dis)
{
	a[++cnt]=(Edge){to,dis,first[from]};
	first[from]=cnt;
}

struct Node
{
	int num,dis;
	bool friend operator <(Node a,Node b)
	{
		return a.dis>b.dis;
	}
};
int n,dis[maxn];
bool vis[maxn];

inline void dij(int s)
{
	memset(vis,0,sizeof(vis));
	for(register int i=1;i<=n;i++) dis[i]=1e9+10;
	priority_queue<Node>q;
	q.push((Node){s,0});
	dis[s]=0;
	while(!q.empty())
	{
		int u=q.top().num;
		q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(register int i=first[u];i;i=a[i].nxt)
		{
			int v=a[i].to;
			if(dis[v]>dis[u]+a[i].dis)
			{
				dis[v]=dis[u]+a[i].dis;
				q.push((Node){v,dis[v]});
			}
		}
	}
}

int d[maxn][maxn];

inline void spfa(int s,int lim,int w)
{
	memset(vis,0,sizeof(vis));
	for(register int i=1;i<=n;i++) dis[i]=1e9+10;
	queue<int>q;
	q.push(s);
	vis[s]=1;
	dis[s]=0;
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		for(register int v=1;v<=n;v++)
		{
			if(!d[u][v]) continue;
			if(dis[v]>dis[u]+d[u][v])
			{
				dis[v]=dis[u]+d[u][v];
				if(dis[v]<=lim) addedge(s,v,w);
				if(!vis[v])
				{
					q.push(v);
					vis[v]=1;
				}
			}
		}
	}
}

int main()
{
	int m,s,t;
	n=read(),m=read();
	s=read(),t=read();
	for(register int i=1;i<=m;i++)
	{
		int u,v,w;
		u=read(),v=read(),w=read();
		d[u][v]=d[v][u]=w;
	}
	for(register int i=1;i<=n;i++)
	{
		int t,c;
		t=read(),c=read();
		spfa(i,t,c);
	}
	dij(s);
	cout<<dis[t];
	return 0;
}


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

using namespace std;

const int maxn=1005;

inline int read()
{
	int p=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){p=(p<<1)+(p<<3)+(c^48),c=getchar();}
	return p*f;
}

struct Edge
{
	int to,dis,nxt;
}a[maxn*3];
int cnt,first[maxn];

inline void addedge(int from,int to,int dis)
{
	a[++cnt]=(Edge){to,dis,first[from]};
	first[from]=cnt;
}

struct Node
{
	int num,dis;
	bool friend operator <(Node a,Node b)
	{
		return a.dis>b.dis;
	}
};
int n,dis[maxn];
bool vis[maxn];

inline void dij(int s)
{
	memset(vis,0,sizeof(vis));
	for(register int i=1;i<=n;i++) dis[i]=1e9+10;
	priority_queue<Node>q;
	q.push((Node){s,0});
	dis[s]=0;
	while(!q.empty())
	{
		int u=q.top().num;
		q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(register int i=first[u];i;i=a[i].nxt)
		{
			int v=a[i].to;
			if(dis[v]>dis[u]+a[i].dis)
			{
				dis[v]=dis[u]+a[i].dis;
				q.push((Node){v,dis[v]});
			}
		}
	}
}

int d[maxn][maxn];

inline void spfa(int s,int lim,int w)
{
	memset(vis,0,sizeof(vis));
	for(register int i=1;i<=n;i++) dis[i]=1e9+10;
	queue<int>q;
	q.push(s);
	vis[s]=1;
	dis[s]=0;
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		for(register int v=1;v<=n;v++)
		{
			if(!d[u][v]) continue;
			if(dis[v]>dis[u]+d[u][v])
			{
				dis[v]=dis[u]+d[u][v];
				if(dis[v]<=lim) addedge(s,v,w);
				if(!vis[v])
				{
					q.push(v);
					vis[v]=1;
				}
			}
		}
	}
}

int main()
{
	int m,s,t;
	n=read(),m=read();
	s=read(),t=read();
	for(register int i=1;i<=m;i++)
	{
		int u,v,w;
		u=read(),v=read(),w=read();
		d[u][v]=d[v][u]=w;
	}
	for(register int i=1;i<=n;i++)
	{
		int t,c;
		t=read(),c=read();
		spfa(i,t,c);
	}
	dij(s);
	if(dis[t]==1e9+10) cout<<"-1";
	else cout<<dis[t];
	return 0;
}


#include <bits/stdc++.h>
#define debug printf("Running %s on line %d...\n",__FUNCTION__,__LINE__)
#define in inline
#define re register
using namespace std;
typedef long long ll;
typedef double db;
in int read()
{
    int ans=0,f=1;char c=getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    for (;isdigit(c);c=getchar()) ans=(ans<<3)+(ans<<1)+(c^48);
    return ans*f;
}
in int cmin(int &a,int b) {return a=min(a,b);}
in int cmax(int &a,int b) {return a=max(a,b);}
int n,m,ss,tt;
int nex1[2005],head1[1005],tail1[2005],tot1;
ll W1[2005];
int nex2[2000005],head2[1005],tail2[2000005],tot2;
ll W2[2000005];
int vis[1005];
ll dis[1005][1005];
struct data
{
    int u;
    ll dis;
    bool operator < (const data &rhs) const
    {
        return dis>rhs.dis;
    }
};
void addedge1(int u,int v,int w)
{
    nex1[++tot1]=head1[u];
    head1[u]=tot1;
    tail1[tot1]=v;
    W1[tot1]=w;
}
void addedge2(int u,int v,int w)
{
    nex2[++tot2]=head2[u];
    head2[u]=tot2;
    tail2[tot2]=v;
    W2[tot2]=w;
}
void dijkstra1(int st,int t,ll c)
{
    priority_queue<data> q;
    q.push({st,0});
    dis[st][st]=0;
    while (!q.empty())
    {
        int u=q.top().u;q.pop();
        if (vis[u]==st) continue;
        vis[u]=st;
        if (dis[st][u]>t) continue;
        if (u!=st)
        {
            addedge2(st,u,c);
        }
        for (int e=head1[u];e;e=nex1[e])
        {
            int v=tail1[e];
            if (dis[st][u]+W1[e]<dis[st][v])
            {
                dis[st][v]=dis[st][u]+W1[e];
                q.push({v,dis[st][v]});
            }
        }
    }
}
void dijkstra2()
{
    priority_queue<data> q;
    q.push({ss,0});
    dis[0][ss]=0;
    while (!q.empty())
    {
        data p=q.top();q.pop();
        int u=p.u,d=p.dis;
        if (u==tt)
        {
            cout<<d<<endl;
            return;
        }
        if (d>dis[0][u]) continue;
        for (int e=head2[u];e;e=nex2[e])
        {
            int v=tail2[e];
            if (dis[0][v]>dis[0][u]+W2[e])
            {
                dis[0][v]=dis[0][u]+W2[e];
                q.push({v,dis[0][v]});
            }
        }
    }
    cout<<-1<<endl;
    return;
}
int main()
{
    memset(dis,0x3f,sizeof(dis));
    n=read(),m=read(),ss=read(),tt=read();
    for (int i=1;i<=m;i++)
    {
        int u=read(),v=read(),w=read();
        addedge1(u,v,w);
        addedge1(v,u,w);
    }
    for (int i=1;i<=n;i++)
    {
        int t=read(),c=read();
        dijkstra1(i,t,c);
    }
    dijkstra2();
    return 0;
}


#include <bits/stdc++.h>
#define debug printf("Running %s on line %d...\n",__FUNCTION__,__LINE__)
#define in inline
#define re register
using namespace std;
typedef long long ll;
typedef double db;
in int read()
{
    int ans=0,f=1;char c=getchar();
    for (;!isdigit(c);c=getchar()) if (c=='-') f=-1;
    for (;isdigit(c);c=getchar()) ans=(ans<<3)+(ans<<1)+(c^48);
    return ans*f;
}
in int cmin(int &a,int b) {return a=min(a,b);}
in int cmax(int &a,int b) {return a=max(a,b);}
int n,m,ss,tt;
int nex1[2005],head1[1005],tail1[2005],tot1;
ll W1[2005];
int nex2[2000005],head2[1005],tail2[2000005],tot2;
ll W2[2000005];
int vis[1005];
ll dis[1005][1005];
struct data
{
    int u;
    ll dis;
    bool operator < (const data &rhs) const
    {
        return dis>rhs.dis;
    }
};
void addedge1(int u,int v,int w)
{
    nex1[++tot1]=head1[u];
    head1[u]=tot1;
    tail1[tot1]=v;
    W1[tot1]=w;
}
void addedge2(int u,int v,int w)
{
    nex2[++tot2]=head2[u];
    head2[u]=tot2;
    tail2[tot2]=v;
    W2[tot2]=w;
}
void dijkstra1(int st,int t,ll c)
{
    priority_queue<data> q;
    q.push({st,0});
    dis[st][st]=0;
    while (!q.empty())
    {
        int u=q.top().u;q.pop();
        if (vis[u]==st) continue;
        vis[u]=st;
        if (dis[st][u]>t) continue;
        if (u!=st)
        {
            addedge2(st,u,c);
        }
        for (int e=head1[u];e;e=nex1[e])
        {
            int v=tail1[e];
            if (dis[st][u]+W1[e]<dis[st][v])
            {
                dis[st][v]=dis[st][u]+W1[e];
                q.push({v,dis[st][v]});
            }
        }
    }
}
void dijkstra2()
{
    priority_queue<data> q;
    q.push({ss,0});
    dis[0][ss]=0;
    while (!q.empty())
    {
        data p=q.top();q.pop();
        ll u=p.u,d=p.dis;
        if (u==tt)
        {
            cout<<d<<endl;
            return;
        }
        if (d>dis[0][u]) continue;
        for (int e=head2[u];e;e=nex2[e])
        {
            int v=tail2[e];
            if (dis[0][v]>dis[0][u]+W2[e])
            {
                dis[0][v]=dis[0][u]+W2[e];
                q.push({v,dis[0][v]});
            }
        }
    }
    cout<<-1<<endl;
    return;
}
int main()
{
    memset(dis,0x3f,sizeof(dis));
    n=read(),m=read(),ss=read(),tt=read();
    for (int i=1;i<=m;i++)
    {
        int u=read(),v=read(),w=read();
        addedge1(u,v,w);
        addedge1(v,u,w);
    }
    for (int i=1;i<=n;i++)
    {
        int t=read(),c=read();
        dijkstra1(i,t,c);
    }
    dijkstra2();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using ll = long long;
constexpr ll N = 2005, M = 50005, INF = 0x3f3f3f3f3f3f3f3f;

int tot, head[N], to[2 * M], nex[2 * M], weight[2 * M];
int n, m, s, t;
ll dis_all[N][N], range[N], cost[N];
bool vis[N];

void add(int a, int b, int c)
{
    ++tot;
    to[tot] = b;
    weight[tot] = c;
    nex[tot] = head[a];
    head[a] = tot;
}

void Dijkstra(int from, ll dis[])
{
    for (int i = 1; i <= n; ++i)
    {
        dis[i] = INF;
        vis[i] = false;
    }

    priority_queue <pair <ll, int> > q;
    q.push({ 0, from });
    dis[from] = 0;

    while (!q.empty())
    {
        int now = q.top().second; q.pop();

        if (vis[now]) continue;
        vis[now] = true;

        for (int i = head[now]; i != 0; i = nex[i])
        {
            if (dis[to[i]] > dis[now] + weight[i])
            {
                dis[to[i]] = dis[now] + weight[i];
                q.push({ -dis[to[i]], to[i] });
            }
        }
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    cin >> n >> m;
    cin >> s >> t;
    for (int i = 1; i <= m; ++i)
    {
        int a, b, c;
        cin >> a >> b >> c;
        add(a, b, c);
        add(b, a, c);
    }
    for (int i = 1; i <= n; ++i)
    {
        cin >> range[i] >> cost[i];
        Dijkstra(i, dis_all[i]);
    }

    tot = 0;
    memset(head, 0, sizeof head);

    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= n; ++j)
        {
            if (i == j) continue;
            if (dis_all[i][j] <= range[i])
            {
                add(i, j, cost[i]);
            }
        }
    }

    Dijkstra(s, dis_all[0]);
    if (dis_all[0][t] == INF) cout << -1 << endl;
    else cout << dis_all[0][t] << endl;
}


#include <bits/stdc++.h>

using namespace std;
using ll = long long;
constexpr ll N = 2005, M = 50005, INF = 0x3f3f3f3f3f3f3f3f;

int tot, head[N], to[2 * M], nex[2 * M], weight[2 * M];
int n, m, s, t;
ll dis_all[N][N], range[N], cost[N];
bool vis[N];

void add(int a, int b, int c)
{
    ++tot;
    to[tot] = b;
    weight[tot] = c;
    nex[tot] = head[a];
    head[a] = tot;
}

void Dijkstra(int from, ll dis[])
{
    for (int i = 1; i <= n; ++i)
    {
        dis[i] = INF;
        vis[i] = false;
    }

    priority_queue <pair <ll, int> > q;
    q.push({ 0, from });
    dis[from] = 0;

    while (!q.empty())
    {
        int now = q.top().second; q.pop();

        if (vis[now]) continue;
        vis[now] = true;

        for (int i = head[now]; i != 0; i = nex[i])
        {
            if (dis[to[i]] > dis[now] + weight[i])
            {
                dis[to[i]] = dis[now] + weight[i];
                q.push({ -dis[to[i]], to[i] });
            }
        }
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    cin >> n >> m;
    cin >> s >> t;
    for (int i = 1; i <= m; ++i)
    {
        int a, b, c;
        cin >> a >> b >> c;
        add(a, b, c);
        add(b, a, c);
    }
    for (int i = 1; i <= n; ++i)
    {
        cin >> range[i] >> cost[i];
        Dijkstra(i, dis_all[i]);
    }

    tot = 0;
    memset(head, 0, sizeof head);

    for (int i = 1; i <= n; ++i)
    {
        for (int j = i + 1; j <= n; ++j)
        {
            if (dis_all[i][j] <= range[i])
            {
                add(i, j, cost[i]);
                add(j, i, cost[i]);
            }
        }
    }

    Dijkstra(s, dis_all[0]);
    if (dis_all[0][t] == INF) cout << -1 << endl;
    else cout << dis_all[0][t] << endl;
}


#include <bits/stdc++.h>

using namespace std;
using ll = long long;
constexpr ll N = 1005, M = 1e6 + 5, INF = 0x3f3f3f3f3f3f3f3f;

int tot, head[N], to[M], nex[M], weight[M];
int n, m, s, t;
ll dis_all[N][N], range[N], cost[N];
bool vis[N];

void add(int a, int b, int c)
{
    ++tot;
    to[tot] = b;
    weight[tot] = c;
    nex[tot] = head[a];
    head[a] = tot;
}

void Dijkstra(int from, ll dis[])
{
    for (int i = 1; i <= n; ++i)
    {
        dis[i] = INF;
        vis[i] = false;
    }

    priority_queue <pair <ll, int> > q;
    q.push({ 0, from });
    dis[from] = 0;

    while (!q.empty())
    {
        int now = q.top().second; q.pop();

        if (vis[now]) continue;
        vis[now] = true;

        for (int i = head[now]; i != 0; i = nex[i])
        {
            if (dis[to[i]] > dis[now] + weight[i])
            {
                dis[to[i]] = dis[now] + weight[i];
                q.push({ -dis[to[i]], to[i] });
            }
        }
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    cin >> n >> m;
    cin >> s >> t;
    for (int i = 1; i <= m; ++i)
    {
        int a, b, c;
        cin >> a >> b >> c;
        add(a, b, c);
        add(b, a, c);
    }
    for (int i = 1; i <= n; ++i)
    {
        cin >> range[i] >> cost[i];
        Dijkstra(i, dis_all[i]);
    }

    tot = 0;
    memset(head, 0, sizeof head);

    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= n; ++j)
        {
            if (i == j) continue;
            if (dis_all[i][j] <= range[i])
            {
                add(i, j, cost[i]);
            }
        }
    }

    Dijkstra(s, dis_all[0]);
    if (dis_all[0][t] == INF) cout << -1 << endl;
    else cout << dis_all[0][t] << endl;
}


#include <bits/stdc++.h>

using namespace std;
using ll = long long;
constexpr ll N = 2005, M = 50005, INF = 0x3f3f3f3f3f3f3f3f;

int tot, head[N], to[2 * M], nex[2 * M], weight[2 * M];
int n, m, s, t;
ll dis_all[N][N], range[N], cost[N];
bool vis[N];

void add(int a, int b, int c)
{
    ++tot;
    to[tot] = b;
    weight[tot] = c;
    nex[tot] = head[a];
    head[a] = tot;
}

void Dijkstra(int from, ll dis[])
{
    for (int i = 1; i <= n; ++i)
    {
        dis[i] = INF;
        vis[i] = false;
    }

    priority_queue <pair <ll, int> > q;
    q.push({ 0, from });
    dis[from] = 0;

    while (!q.empty())
    {
        int now = q.top().second; q.pop();

        if (vis[now]) continue;
        vis[now] = true;

        for (int i = head[now]; i != 0; i = nex[i])
        {
            if (dis[to[i]] > dis[now] + weight[i])
            {
                dis[to[i]] = dis[now] + weight[i];
                q.push({ -dis[to[i]], to[i] });
            }
        }
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    cin >> n >> m;
    cin >> s >> t;
    for (int i = 1; i <= m; ++i)
    {
        int a, b, c;
        cin >> a >> b >> c;
        add(a, b, c);
        add(b, a, c);
    }
    for (int i = 1; i <= n; ++i)
    {
        cin >> range[i] >> cost[i];
        Dijkstra(i, dis_all[i]);
    }

    tot = 0;
    memset(head, 0, sizeof head);

    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= n; ++j)
        {
            if (i == j) continue;
            if (dis_all[i][j] <= range[i])
            {
                add(i, j, cost[i]);
                add(j, i, cost[i]);
            }
        }
    }

    Dijkstra(s, dis_all[0]);
    if (dis_all[0][t] == INF) cout << -1 << endl;
    else cout << dis_all[0][t] << endl;
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define ff first
#define ss second
int32_t main()
{
    int n, m, x, y;
    cin>>n>>m>>x>>y;
    vector<int>t(n+1), c(n+1);
    vector<pair<int,int>>adj[n+1];
    for(int i=0; i<m; ++i)
    {
        int u, v, w;
        cin>>u>>v>>w;
        adj[u].push_back({v, w});
        adj[v].push_back({u, w});
    }

    for(int i=1; i<=n; ++i) cin>>t[i]>>c[i];

    vector<vector<int>>dist(n+1, vector<int>(n+1, LLONG_MAX));
    for(int i=1; i<=n; ++i)
    {
        priority_queue<pii>pq;
        vector<int>v(n+1, 0);
        pq.push({0, i});
        while(!pq.empty())
        {
            int z=pq.top().ss;
            int d=-pq.top().ff;
            pq.pop();
            if(v[z]) continue;
            v[z]=1;
            dist[i][z]=d;
            for(auto e: adj[z])
            {
                int v=e.ff, w=e.ss;
                if(dist[i][v]>dist[i][z]+w)
                {
                    dist[i][v]=dist[i][z]+w;
                    pq.push({-dist[i][v], v});
                }
            }
        }
    }
    vector<int>A[n+1];
    for(int i=1; i<=n; ++i)
    {
        for(int j=1; j<=n; ++j)
        {
            if(dist[i][j]<=t[i])
            {
                A[i].push_back(j);
            }
        }
    }

    priority_queue<pii>pq;
    vector<bool>v(n+1,0);
    vector<int> cst(n+1, LLONG_MAX);
    pq.push({0, x});
    while(!pq.empty())
    {
        int z=pq.top().second;
        int d=-pq.top().first;
        pq.pop();
        if(v[z]) continue;
        v[z]=1;
        if(z==y)
        {
            cout<<d;
            exit(0);
        }
        cst[z]=d;
        for(auto u: A[z])
        {
            if(cst[u]>cst[z]+c[z])
            {
                cst[u]=cst[z]+c[z];
                pq.push({-cst[u], u});
            }
        }
    }
    cout<<cst[y];
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define ff first
#define ss second
int32_t main()
{
    int n, m, x, y;
    cin>>n>>m>>x>>y;
    vector<int>t(n+1), c(n+1);
    vector<pair<int,int>>adj[n+1];
    for(int i=0; i<m; ++i)
    {
        int u, v, w;
        cin>>u>>v>>w;
        adj[u].push_back({v, w});
        adj[v].push_back({u, w});
    }

    for(int i=1; i<=n; ++i) cin>>t[i]>>c[i];

    vector<vector<int>>dist(n+1, vector<int>(n+1, LLONG_MAX));
    for(int i=1; i<=n; ++i)
    {
        priority_queue<pii>pq;
        vector<int>v(n+1, 0);
        pq.push({0, i});
        while(!pq.empty())
        {
            int z=pq.top().ss;
            int d=-pq.top().ff;
            pq.pop();
            if(v[z]) continue;
            v[z]=1;
            dist[i][z]=d;
            for(auto e: adj[z])
            {
                int v=e.ff, w=e.ss;
                if(dist[i][v]>dist[i][z]+w)
                {
                    dist[i][v]=dist[i][z]+w;
                    pq.push({-dist[i][v], v});
                }
            }
        }
    }
    vector<int>A[n+1];
    for(int i=1; i<=n; ++i)
    {
        for(int j=1; j<=n; ++j)
        {
            if(dist[i][j]<=t[i])
            {
                A[i].push_back(j);
            }
        }
    }

    priority_queue<pii>pq;
    vector<bool>v(n+1,0);
    vector<int> cst(n+1, LLONG_MAX);
    pq.push({0, x});
    while(!pq.empty())
    {
        int z=pq.top().second;
        int d=-pq.top().first;
        pq.pop();
        if(v[z]) continue;
        v[z]=1;
        if(z==y)
        {
            cout<<d;
            exit(0);
        }
        cst[z]=d;
        for(auto u: A[z])
        {
            if(cst[u]>cst[z]+c[z])
            {
                cst[u]=cst[z]+c[z];
                pq.push({-cst[u], u});
            }
        }
    }
    assert(0);
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, int>
#define ff first
#define ss second
int32_t main()
{
    int n, m, x, y;
    cin>>n>>m>>x>>y;
    vector<int>t(n+1), c(n+1);
    vector<pair<int,int>>adj[n+1];
    for(int i=0; i<m; ++i)
    {
        int u, v, w;
        cin>>u>>v>>w;
        adj[u].push_back({v, w});
        adj[v].push_back({u, w});
    }

    for(int i=1; i<=n; ++i) cin>>t[i]>>c[i];

    vector<vector<int>>dist(n+1, vector<int>(n+1, LLONG_MAX));
    for(int i=1; i<=n; ++i)
    {
        priority_queue<pii>pq;
        vector<int>v(n+1, 0);
        pq.push({0, i});
        while(!pq.empty())
        {
            int z=pq.top().ss;
            int d=-pq.top().ff;
            pq.pop();
            if(v[z]) continue;
            v[z]=1;
            dist[i][z]=d;
            for(auto e: adj[z])
            {
                int v=e.ff, w=e.ss;
                if(dist[i][v]>dist[i][z]+w)
                {
                    dist[i][v]=dist[i][z]+w;
                    pq.push({-dist[i][v], v});
                }
            }
        }
    }
    vector<int>A[n+1];
    for(int i=1; i<=n; ++i)
    {
        for(int j=1; j<=n; ++j)
        {
            if(dist[i][j]<=t[i])
            {
                A[i].push_back(j);
            }
        }
    }

    priority_queue<pii>pq;
    vector<bool>v(n+1,0);
    vector<int> cst(n+1, LLONG_MAX);
    pq.push({0, x});
    while(!pq.empty())
    {
        int z=pq.top().second;
        int d=-pq.top().first;
        pq.pop();
        if(v[z]) continue;
        v[z]=1;
        if(z==y)
        {
            cout<<d;
            exit(0);
        }
        cst[z]=d;
        for(auto u: A[z])
        {
            if(cst[u]>cst[z]+c[z])
            {
                cst[u]=cst[z]+c[z];
                pq.push({-cst[u], u});
            }
        }
    }
    if(cst[y]==LLONG_MAX) cout<<-1;
    else cout<<cst[y];
}


#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <complex>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef complex <double> cmx;
typedef pair<int, int> pii;
typedef pair<ll, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 1e9+7;
const int inf = 1061109567;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
const int maxn = 1002;
vector<pii> e[maxn];
priority_queue <pll> q;
pll a[maxn];
int n, m;
ll dis[maxn][maxn];
void dij(int i)
{
    for(int j = 1; j <= n; j++)
        dis[i][j] = inf;
    dis[i][i] = 0;
    q.push(mk(0, i));
    while(!q.empty()) {
        pll tmp = q.top(); q.pop();
        int x = tmp.se, d = -tmp.fi;
        if(dis[i][x] != d)
            continue;
        for(int j = 0; j < e[x].size(); j++) {
            int v = e[x][j].fi;
            ll len = e[x][j].se + d;
            if(dis[i][v] > len) {
                dis[i][v] = len;
                q.push(mk(-len, v));
            }
        }
    }
}
int main()
{
    int s, t, u, v, w;
    cin>>n>>m>>s>>t;
    for(int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        e[u].pb(mk(v, w));
        e[v].pb(mk(u, w));
    }
    for(int i = 1; i <= n; i++) {
        scanf("%d%d", &a[i].fi, &a[i].se);
    }
    for(int i = 1; i <= n; i++) {
        dij(i);
    }
    for(int i = 1; i <= n; i++) {
        e[i].clear();
        for(int j = 1; j <= n; j++) {
            if(dis[i][j] <= a[i].fi) {
                e[i].pb(mk(j, a[i].se));
            }
        }
    }
    dij(s);
    if(dis[s][t] == inf) {
        cout<<-1<<endl;
    } else {
        cout<<dis[s][t]<<endl;
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <complex>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef complex <double> cmx;
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 1e9+7;
const int inf = 1e13;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
const int maxn = 1001;
int n, m, d[maxn], c[maxn];
ll dis[maxn];
struct node
{
    int x, len;
    ll cost;
    node(){}
    node(int x, int len, ll cost):x(x), len(len), cost(cost){}
};
vector <pll> e[maxn];
queue<node> q;
int solve(int s, int t) {
    if(s == t)
        return 0;
    for(int i = 1; i <= n; i++)
        dis[i] = inf;
    q.push(node(s, d[s], c[s]));
    while(!q.empty()) {
        node tmp = q.front(); q.pop();
        if(dis[tmp.x] < tmp.cost)
            continue;
        dis[tmp.x] = tmp.cost;
        for(int i = 0; i < e[tmp.x].size(); i++) {
            int v = e[tmp.x][i].fi, w = e[tmp.x][i].se;
            if(tmp.len >= w) {
                q.push(node(v, tmp.len - w, tmp.cost));
            }
            if(d[tmp.x] >= w)
                q.push(node(v, d[tmp.x] - w, tmp.cost+c[tmp.x]));
        }
    }
    if(dis[t] == inf)
        return -1;
    return dis[t];
}
int main()
{
    int s, t, u, v, w;
    cin>>n>>m>>s>>t;
    for(int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        e[u].pb(mk(v, w));
        e[v].pb(mk(u, w));
    }
    for(int i = 1; i <= n; i++) {
        scanf("%d%d", &d[i], &c[i]);
    }
    ll ans = solve(s, t);
    cout<<ans<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <complex>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef complex <double> cmx;
typedef pair<int, int> pii;
typedef pair<ll, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 1e9+7;
const int inf = 1e18;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
const int maxn = 1002;
vector<pii> e[maxn];
priority_queue <pll> q;
pll a[maxn];
int n, m;
ll dis[maxn][maxn];
void dij(int i)
{
    for(int j = 1; j <= n; j++)
        dis[i][j] = inf;
    dis[i][i] = 0;
    q.push(mk(0, i));
    while(!q.empty()) {
        pll tmp = q.top(); q.pop();
        int x = tmp.se, d = -tmp.fi;
        if(dis[i][x] != d)
            continue;
        for(int j = 0; j < e[x].size(); j++) {
            int v = e[x][j].fi;
            ll len = e[x][j].se + d;
            if(dis[i][v] > len) {
                dis[i][v] = len;
                q.push(mk(-len, v));
            }
        }
    }
}
int main()
{
    int s, t, u, v, w;
    cin>>n>>m>>s>>t;
    for(int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        e[u].pb(mk(v, w));
        e[v].pb(mk(u, w));
    }
    for(int i = 1; i <= n; i++) {
        scanf("%d%d", &a[i].fi, &a[i].se);
    }
    for(int i = 1; i <= n; i++) {
        dij(i);
    }
    for(int i = 1; i <= n; i++) {
        e[i].clear();
        for(int j = 1; j <= n; j++) {
            if(dis[i][j] <= a[i].fi) {
                e[i].pb(mk(j, a[i].se));
            }
        }
    }
    dij(s);
    if(dis[s][t] == inf) {
        cout<<-1<<endl;
    } else {
        cout<<dis[s][t]<<endl;
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <complex>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef complex <double> cmx;
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 1e9+7;
const int inf = 1e18;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
const int maxn = 1005;
int n, m, d[maxn], c[maxn];
ll dis[maxn];
struct node
{
    int x, len;
    ll cost;
    node(){}
    node(int x, int len, ll cost):x(x), len(len), cost(cost){}
};
vector <pll> e[maxn];
int solve(int s, int t) {
    if(s == t)
        return 0;
    for(int i = 1; i <= n; i++)
        dis[i] = inf;
    queue<node> q;
    q.push(node(s, d[s], c[s]));
    while(!q.empty()) {
        node tmp = q.front(); q.pop();
        if(dis[tmp.x] < tmp.cost)
            continue;
        dis[tmp.x] = tmp.cost;
        for(int i = 0; i < e[tmp.x].size(); i++) {
            int v = e[tmp.x][i].fi, w = e[tmp.x][i].se;
            if(tmp.len >= w) {
                q.push(node(v, tmp.len - w, tmp.cost));
            }
            if(d[tmp.x] >= w)
                q.push(node(v, d[tmp.x] - w, tmp.cost+c[tmp.x]));
        }
    }
    if(dis[t] == inf)
        return -1;
    return dis[t];
}
int main()
{
    int s, t, u, v, w;
    cin>>n>>m>>s>>t;
    for(int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        e[u].pb(mk(v, w));
        e[v].pb(mk(u, w));
    }
    for(int i = 1; i <= n; i++) {
        scanf("%d%d", &d[i], &c[i]);
    }
    ll ans = solve(s, t);
    cout<<ans<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <complex>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef complex <double> cmx;
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 1e9+7;
const int inf = 1e13;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
const int maxn = 1001;
int n, m, d[maxn], c[maxn];
ll dis[maxn];
struct node
{
    int x, len;
    ll cost;
    node(){}
    node(int x, int len, ll cost):x(x), len(len), cost(cost){}
};
vector <pll> e[maxn];
int solve(int s, int t) {
    if(s == t)
        return 0;
    for(int i = 1; i <= n; i++)
        dis[i] = inf;
    queue<node> q;
    q.push(node(s, d[s], c[s]));
    while(!q.empty()) {
        node tmp = q.front(); q.pop();
        if(dis[tmp.x] < tmp.cost)
            continue;
        dis[tmp.x] = tmp.cost;
        for(int i = 0; i < e[tmp.x].size(); i++) {
            int v = e[tmp.x][i].fi, w = e[tmp.x][i].se;
            if(tmp.len >= w) {
                q.push(node(v, tmp.len - w, tmp.cost));
            }
            if(d[tmp.x] >= w)
                q.push(node(v, d[tmp.x] - w, tmp.cost+c[tmp.x]));
        }
    }
    if(dis[t] == inf)
        return -1;
    return dis[t];
}
int main()
{
    int s, t, u, v, w;
    cin>>n>>m>>s>>t;
    for(int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        e[u].pb(mk(v, w));
        e[v].pb(mk(u, w));
    }
    for(int i = 1; i <= n; i++) {
        scanf("%d%d", &d[i], &c[i]);
    }
    ll ans = solve(s, t);
    cout<<ans<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <complex>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef complex <double> cmx;
typedef pair<int, int> pii;
typedef pair<ll, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 1e9+7;
const ll inf = 1e15;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
const int maxn = 1002;
vector<pii> e[maxn];
priority_queue <pll> q;
pll a[maxn];
int n, m;
ll dis[maxn][maxn];
void dij(int i)
{
    for(int j = 1; j <= n; j++)
        dis[i][j] = inf;
    dis[i][i] = 0;
    q.push(mk(0, i));
    while(!q.empty()) {
        pll tmp = q.top(); q.pop();
        int x = tmp.se, d = -tmp.fi;
        if(dis[i][x] != d)
            continue;
        for(int j = 0; j < e[x].size(); j++) {
            int v = e[x][j].fi;
            ll len = d + e[x][j].se;
            if(dis[i][v] > len) {
                dis[i][v] = len;
                q.push(mk(-len, v));
            }
        }
    }
}
int main()
{
    int s, t, u, v, w;
    cin>>n>>m>>s>>t;
    for(int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        e[u].pb(mk(v, w));
        e[v].pb(mk(u, w));
    }
    for(int i = 1; i <= n; i++) {
        scanf("%d%d", &a[i].fi, &a[i].se);
    }
    for(int i = 1; i <= n; i++) {
        dij(i);
    }
    for(int i = 1; i <= n; i++) {
        e[i].clear();
        for(int j = 1; j <= n; j++) {
            if(dis[i][j] <= a[i].fi) {
                e[i].pb(mk(j, a[i].se));
            }
        }
    }
    dij(s);
    if(dis[s][t] == inf) {
        cout<<-1<<endl;
    } else {
        cout<<dis[s][t]<<endl;
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <complex>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef complex <double> cmx;
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 1e9+7;
const int inf = 1e18;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
const int maxn = 1005;
int n, m, d[maxn], c[maxn];
ll dis[maxn];
struct node
{
    int x, len;
    ll cost;
    node(){}
    node(int x, int len, ll cost):x(x), len(len), cost(cost){}
};
vector <pll> e[maxn];
int solve(int s, int t) {
    for(int i = 1; i <= n; i++)
        dis[i] = inf;
    queue<node> q;
    q.push(node(s, d[s], c[s]));
    while(!q.empty()) {
        node tmp = q.front(); q.pop();
        if(dis[tmp.x] < tmp.cost)
            continue;
        dis[tmp.x] = tmp.cost;
        for(int i = 0; i < e[tmp.x].size(); i++) {
            int v = e[tmp.x][i].fi, w = e[tmp.x][i].se;
            if(tmp.len >= w) {
                q.push(node(v, tmp.len - w, tmp.cost));
            }
            q.push(node(v, d[v], tmp.cost+c[v]));
        }
    }
    if(dis[t] == inf)
        return -1;
    return dis[t];
}
int main()
{
    int s, t, u, v, w;
    cin>>n>>m>>s>>t;
    for(int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        e[u].pb(mk(v, w));
        e[v].pb(mk(u, w));
    }
    for(int i = 1; i <= n; i++) {
        scanf("%d%d", &d[i], &c[i]);
    }
    ll ans = solve(s, t);
    cout<<ans<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <complex>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef complex <double> cmx;
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 1e9+7;
const int inf = 1e18;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
const int maxn = 1005;
int n, m, d[maxn], c[maxn];
ll dis[maxn];
struct node
{
    int x, len;
    ll cost;
    node(){}
    node(int x, int len, ll cost):x(x), len(len), cost(cost){}
};
vector <pll> e[maxn];
int solve(int s, int t) {
    for(int i = 1; i <= n; i++)
        dis[i] = inf;
    queue<node> q;
    q.push(node(s, d[s], c[s]));
    while(!q.empty()) {
        node tmp = q.front(); q.pop();
        if(dis[tmp.x] < tmp.cost)
            continue;
        dis[tmp.x] = tmp.cost;
        for(int i = 0; i < e[tmp.x].size(); i++) {
            int v = e[tmp.x][i].fi, w = e[tmp.x][i].se;
            if(tmp.len >= w) {
                q.push(node(v, tmp.len - w, tmp.cost));
            }
            if(d[tmp.x] >= w)
                q.push(node(v, d[tmp.x] - w, tmp.cost+c[tmp.x]));
        }
    }
    if(dis[t] == inf)
        return -1;
    return dis[t];
}
int main()
{
    int s, t, u, v, w;
    cin>>n>>m>>s>>t;
    for(int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        e[u].pb(mk(v, w));
        e[v].pb(mk(u, w));
    }
    for(int i = 1; i <= n; i++) {
        scanf("%d%d", &d[i], &c[i]);
    }
    ll ans = solve(s, t);
    cout<<ans<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <complex>
#include <cmath>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef complex <double> cmx;
typedef pair<int, int> pii;
typedef pair<ll, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int mod = 1e9+7;
const ll inf = 1e15;
const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
const int maxn = 1002;
vector<pii> e[maxn];
priority_queue <pll> q;
pii a[maxn];
int n, m;
ll dis[maxn][maxn];
void dij(int i)
{
    for(int j = 1; j <= n; j++)
        dis[i][j] = inf;
    dis[i][i] = 0;
    q.push(mk(0, i));
    while(!q.empty()) {
        pll tmp = q.top(); q.pop();
        int x = tmp.se;
        ll d = -tmp.fi;
        if(dis[i][x] != d)
            continue;
        for(int j = 0; j < e[x].size(); j++) {
            int v = e[x][j].fi;
            ll len = d + e[x][j].se;
            if(dis[i][v] > len) {
                dis[i][v] = len;
                q.push(mk(-len, v));
            }
        }
    }
}
int main()
{
    int s, t, u, v, w;
    cin>>n>>m>>s>>t;
    for(int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        e[u].pb(mk(v, w));
        e[v].pb(mk(u, w));
    }
    for(int i = 1; i <= n; i++) {
        scanf("%d%d", &a[i].fi, &a[i].se);
    }
    for(int i = 1; i <= n; i++) {
        dij(i);
    }
    for(int i = 1; i <= n; i++) {
        e[i].clear();
        for(int j = 1; j <= n; j++) {
            if(dis[i][j] <= a[i].fi) {
                e[i].pb(mk(j, a[i].se));
            }
        }
    }
    dij(s);
    if(dis[s][t] == inf) {
        cout<<-1<<endl;
    } else {
        cout<<dis[s][t]<<endl;
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e3+10;
#define P pair<int,int>
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*f;
}
struct node{
	int v,w,nxt;
}e[N*N*2];
int first[N],cnt,n,m,dis[N][N],vis[N];
inline void add(int u,int v,int w){
	e[++cnt].v=v;e[cnt].w=w;
	e[cnt].nxt=first[u];first[u]=cnt;
}
priority_queue<P> p;
inline void dijkstra(int s){
	memset(dis[s],0x3f,sizeof(dis[s]));
	memset(vis,0,sizeof(vis));
	dis[s][s]=0;
	p.push(make_pair(0,s));
	while(!p.empty()){
		int u=p.top().second;p.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=first[u];i;i=e[i].nxt){
			int v=e[i].v,w=e[i].w;
			if(dis[s][v]>dis[s][u]+w){
				dis[s][v]=dis[s][u]+w;
				p.push(make_pair(-dis[s][v],v));
			}
		}
	}
}
signed main(){
	n=read();m=read();
	int x=read(),y=read();
	for(int i=1;i<=m;++i){
		int u=read(),v=read(),w=read();
		add(u,v,w);add(v,u,w);
	}
	for(int i=1;i<=n;++i)dijkstra(i);
	memset(first,0,sizeof(first));cnt=0;
	for(int i=1;i<=n;++i){
		int t=read(),c=read();
		for(int j=1;j<=n;++j)
			if(i!=j&&dis[i][j]<=t)
				add(i,j,c);
	}
	dijkstra(x);
	if(dis[x][y]==dis[x][0]) puts("-1");
	else printf("%lld\n",dis[x][y]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e3+10;
#define P pair<int,int>
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*f;
}
struct node{
	int v,w,nxt;
}e[N<<1];
int first[N],cnt,n,m,dis[N][N],vis[N];
inline void add(int u,int v,int w){
	e[++cnt].v=v;e[cnt].w=w;
	e[cnt].nxt=first[u];first[u]=cnt;
}
priority_queue<P> p;
inline void dijkstra(int s){
	memset(dis[s],0x3f,sizeof(dis[s]));
	memset(vis,0,sizeof(vis));
	dis[s][s]=0;
	p.push(make_pair(0,s));
	while(!p.empty()){
		int u=p.top().second;p.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=first[u];i;i=e[i].nxt){
			int v=e[i].v,w=e[i].w;
			if(dis[s][v]>dis[s][u]+w){
				dis[s][v]=dis[s][u]+w;
				p.push(make_pair(-dis[s][v],v));
			}
		}
	}
}
int main(){
	n=read();m=read();
	int x=read(),y=read();
	for(int i=1;i<=m;++i){
		int u=read(),v=read(),w=read();
		add(u,v,w);add(v,u,w);
	}
	for(int i=1;i<=n;++i)dijkstra(i);
	memset(first,0,sizeof(first));cnt=0;
	for(int i=1;i<=n;++i){
		int t=read(),c=read();
		for(int j=1;j<=n;++j)
			if(i!=j&&dis[i][j]<=t)
				add(i,j,c);
	}
	dijkstra(x);
	if(dis[x][y]==0x3f3f3f3f) puts("-1");
	else printf("%d\n",dis[x][y]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
#define P pair<int,int>
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*f;
}
struct node{
	int v,w,nxt;
}e[N<<1];
int first[N],cnt,n,m,dis[N][N],vis[N];
inline void add(int u,int v,int w){
	e[++cnt].v=v;e[cnt].w=w;
	e[cnt].nxt=first[u];first[u]=cnt;
}
priority_queue<P> p;
inline void dijkstra(int s){
	memset(dis[s],0x3f,sizeof(dis[s]));
	memset(vis,0,sizeof(vis));
	dis[s][s]=0;
	p.push(make_pair(0,s));
	while(!p.empty()){
		int u=p.top().second;p.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=first[u];i;i=e[i].nxt){
			int v=e[i].v,w=e[i].w;
			if(dis[s][v]>dis[s][u]+w){
				dis[s][v]=dis[s][u]+w;
				p.push(make_pair(-dis[s][v],v));
			}
		}
	}
}
int main(){
	n=read();m=read();
	int x=read(),y=read();
	for(int i=1;i<=m;++i){
		int u=read(),v=read(),w=read();
		add(u,v,w);add(v,u,w);
	}
	for(int i=1;i<=n;++i)dijkstra(i);
	memset(first,0,sizeof(first));cnt=0;
	for(int i=1;i<=n;++i){
		int t=read(),c=read();
		for(int j=1;j<=n;++j)
			if(i!=j&&dis[i][j]<=t)
				add(i,j,c);
	}
	dijkstra(x);
	if(dis[x][y]==0x3f3f3f3f) puts("-1");
	else printf("%d\n",dis[x][y]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N=2e3+10;
#define P pair<int,int>
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*f;
}
struct node{
	int v,w,nxt;
}e[N*N*2];
int first[N],cnt,n,m,dis[N][N],vis[N];
inline void add(int u,int v,int w){
	e[++cnt].v=v;e[cnt].w=w;
	e[cnt].nxt=first[u];first[u]=cnt;
}
priority_queue<P> p;
inline void dijkstra(int s){
	memset(dis[s],0x3f,sizeof(dis[s]));
	memset(vis,0,sizeof(vis));
	dis[s][s]=0;
	p.push(make_pair(0,s));
	while(!p.empty()){
		int u=p.top().second;p.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=first[u];i;i=e[i].nxt){
			int v=e[i].v,w=e[i].w;
			if(dis[s][v]>dis[s][u]+w){
				dis[s][v]=dis[s][u]+w;
				p.push(make_pair(-dis[s][v],v));
			}
		}
	}
}
int main(){
	n=read();m=read();
	int x=read(),y=read();
	for(int i=1;i<=m;++i){
		int u=read(),v=read(),w=read();
		add(u,v,w);add(v,u,w);
	}
	for(int i=1;i<=n;++i)dijkstra(i);
	memset(first,0,sizeof(first));cnt=0;
	for(int i=1;i<=n;++i){
		int t=read(),c=read();
		for(int j=1;j<=n;++j)
			if(i!=j&&dis[i][j]<=t)
				add(i,j,c);
	}
	dijkstra(x);
	if(dis[x][y]==0x3f3f3f3f) puts("-1");
	else printf("%d\n",dis[x][y]);
	return 0;
}


#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
long long int min_dists[1002][1002],fi[1002];
long long int adj[1002][1002],final[1002][1002],w1[1002][1002],w2[1002][1002];
int main()
{
	int n,m,x,fx,fy,curnode;
	long long int curw,z,y;
	cin>>n>>m;
	cin>>fx>>fy;
	for(int i=0;i<=n;i++)
		for(int j=0;j<=n;j++)
			w1[i][j]=1000000000000000;
	for(int i=0;i<=n;i++)
		for(int j=0;j<=n;j++)
			w2[i][j]=1000000000000000;
	for(int i=0;i<m;i++)
	{
		cin>>x>>y>>z;
		adj[x][y]=1;
		adj[y][x]=1;
		w1[x][y]=min(w1[x][y],z);
		w1[y][x]=min(w1[y][x],z);
	}
	for(int i=0;i<=n;i++)
		for(int j=0;j<=n;j++)
			min_dists[i][j]=1000000000000000;
	for(int i=1;i<=n;i++)
	{
		min_dists[i][i]=0;
		set<pair<int,long long int> > q;
		q.insert(make_pair(0,i));
		while(!q.empty())
		{
			curnode=(*q.begin()).second;
			curw=(*q.begin()).first;
			q.erase(q.begin());
			if(min_dists[i][curnode]==curw)
			{
				for(int j=1;j<=n;j++)
				{
					if(curnode!=j&&adj[curnode][j]&&min_dists[i][j]>min_dists[i][curnode]+w1[curnode][j])
					{
						min_dists[i][j]=min_dists[i][curnode]+w1[curnode][j];
						q.insert(make_pair(min_dists[i][j],j));

					}
				}
			}
		}
	}
	for(int i=1;i<=n;i++)
		{
			cin>>x>>y;
			for(int j=1;j<=n;j++)
			{
				if(min_dists[i][j]<=x&&i!=j)
				{
					final[i][j]=1;
		            w2[i][j]=min(w2[i][j],y);
				}
				//cout<<min_dists[i][j]<<" ";
			}
			//cout<<endl;
		}
    for(int j=0;j<=n;j++)
			fi[j]=1000000000000000;
    fi[fx]=0;
    set<pair<int,long long int> > q2;
	q2.insert(make_pair(0,fx));
	while(!q2.empty())
	{
		curnode=(*q2.begin()).second;
		curw=(*q2.begin()).first;
		q2.erase(q2.begin());
		if(fi[curnode]==curw)
		{
			for(int j=1;j<=n;j++)
			{
				if(curnode!=j&&final[curnode][j]&&fi[j]>fi[curnode]+w2[curnode][j])
					{
						fi[j]=fi[curnode]+w2[curnode][j];
						q2.insert(make_pair(fi[j],j));
					}
			}
		}
	}
	//for(int j=1;j<=n;j++)
	//	cout<<fi[j]<<" ";
	//cout<<endl;
	if(fi[fy]<1000000000000000)
		cout<<fi[fy];
	else cout<<-1;

}


#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
long long int min_dists[1002][1002],fi[1002];
vector<int>adj[1002],final[1002],w1[1002],w2[1002];
int main()
{
	int n,m,x,y,z,fx,fy,curnode;
	long long int curw;
	cin>>n>>m;
	cin>>fx>>fy;
	for(int i=0;i<m;i++)
	{
		cin>>x>>y>>z;
		adj[x].push_back(y);
		adj[y].push_back(x);
		w1[x].push_back(z);
		w1[y].push_back(z);
	}
	for(int i=0;i<=n;i++)
		for(int j=0;j<=n;j++)
			min_dists[i][j]=1000000000000000;
	for(int i=1;i<=n;i++)
	{
		min_dists[i][i]=0;
		set<pair<int,int> > q;
		q.insert(make_pair(0,i));
		while(!q.empty())
		{
			curnode=(*q.begin()).second;
			curw=(*q.begin()).first;
			q.erase(q.begin());
			if(min_dists[i][curnode]==curw)
			{
				for(int j=0;j<adj[curnode].size();j++)
				{
					if(min_dists[i][adj[curnode][j]]>min_dists[i][curnode]+w1[curnode][j])
					{
						min_dists[i][adj[curnode][j]]=min_dists[i][curnode]+w1[curnode][j];
						q.insert(make_pair(min_dists[i][adj[curnode][j]],adj[curnode][j]));

					}
				}
			}
		}
	}
	for(int i=1;i<=n;i++)
		{
			cin>>x>>y;
			for(int j=i+1;j<=n;j++)
			{
				if(min_dists[i][j]<=x)
				{
					w2[i].push_back(y);
                    w2[j].push_back(y);
                    final[i].push_back(j);
                    final[j].push_back(i);
				}
			}
		}
    for(int j=0;j<=n;j++)
			fi[j]=1000000000000000;
    fi[fx]=0;
    set<pair<int,int> > q2;
	q2.insert(make_pair(0,fx));
	while(!q2.empty())
	{
		curnode=(*q2.begin()).second;
		curw=(*q2.begin()).first;
		q2.erase(q2.begin());
		if(fi[curnode]==curw)
		{
			for(int j=0;j<final[curnode].size();j++)
			{
				if(fi[final[curnode][j]]>fi[curnode]+w2[curnode][j])
					{
						fi[final[curnode][j]]=fi[curnode]+w2[curnode][j];
						q2.insert(make_pair(fi[final[curnode][j]],final[curnode][j]));
					}
			}
		}
	}
	if(fi[fy]<1000000000000000)
		cout<<fi[fy];
	else cout<<-1;

}


#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
long long int min_dists[1002][1002],fi[1002];
vector<int>adj[1002],final[1002],w1[1002],w2[1002];
int main()
{
	int n,m,x,fx,fy,curnode;
	long long int curw,y,z;
	cin>>n>>m;
	cin>>fx>>fy;
	for(int i=0;i<m;i++)
	{
		cin>>x>>y>>z;
		adj[x].push_back(y);
		adj[y].push_back(x);
		w1[x].push_back(z);
		w1[y].push_back(z);
	}
	for(int i=0;i<=n;i++)
		for(int j=0;j<=n;j++)
			min_dists[i][j]=100000000000000000;
	for(int i=1;i<=n;i++)
	{
		min_dists[i][i]=0;
		set<pair<long long int,int> > q;
		q.insert(make_pair(0,i));
		while(!q.empty())
		{
			curnode=(*q.begin()).second;
			curw=(*q.begin()).first;
			q.erase(q.begin());
			if(min_dists[i][curnode]==curw)
			{
				for(int j=0;j<adj[curnode].size();j++)
				{
					if(min_dists[i][adj[curnode][j]]>min_dists[i][curnode]+w1[curnode][j])
					{
						min_dists[i][adj[curnode][j]]=min_dists[i][curnode]+w1[curnode][j];
						q.insert(make_pair(min_dists[i][adj[curnode][j]],adj[curnode][j]));

					}
				}
			}
		}
	}
	for(int i=1;i<=n;i++)
		{
			cin>>x>>y;
			for(int j=1;j<=n;j++)
			{
				if(min_dists[i][j]<=x&&i!=j)
				{
					w2[i].push_back(y);
                    final[i].push_back(j);
				}
			}
		}
    for(int j=0;j<=n;j++)
			fi[j]=100000000000000000;
    fi[fx]=0;
    set<pair<long long int,int> > q2;
	q2.insert(make_pair(0,fx));
	while(!q2.empty())
	{
		curnode=(*q2.begin()).second;
		curw=(*q2.begin()).first;
		q2.erase(q2.begin());
		if(fi[curnode]==curw)
		{
			for(int j=0;j<final[curnode].size();j++)
			{
				if(fi[final[curnode][j]]>fi[curnode]+w2[curnode][j])
					{
						fi[final[curnode][j]]=fi[curnode]+w2[curnode][j];
						q2.insert(make_pair(fi[final[curnode][j]],final[curnode][j]));
					}
			}
		}
	}
	if(fi[fy]<100000000000000000)
		cout<<fi[fy];
	else cout<<-1;

}


#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
long long int min_dists[1002][1002],fi[1002];
vector<int>adj[1002],final[1002],w1[1002],w2[1002];
int main()
{
	int n,m,x,fx,fy,curnode;
	long long int curw,y,z;
	cin>>n>>m;
	cin>>fx>>fy;
	for(int i=0;i<m;i++)
	{
		cin>>x>>y>>z;
		adj[x].push_back(y);
		adj[y].push_back(x);
		w1[x].push_back(z);
		w1[y].push_back(z);
	}
	for(int i=0;i<=n;i++)
		for(int j=0;j<=n;j++)
			min_dists[i][j]=1000000000000000;
	for(int i=1;i<=n;i++)
	{
		min_dists[i][i]=0;
		set<pair<int,long long int> > q;
		q.insert(make_pair(0,i));
		while(!q.empty())
		{
			curnode=(*q.begin()).second;
			curw=(*q.begin()).first;
			q.erase(q.begin());
			if(min_dists[i][curnode]==curw)
			{
				for(int j=0;j<adj[curnode].size();j++)
				{
					if(min_dists[i][adj[curnode][j]]>min_dists[i][curnode]+w1[curnode][j])
					{
						min_dists[i][adj[curnode][j]]=min_dists[i][curnode]+w1[curnode][j];
						q.insert(make_pair(min_dists[i][adj[curnode][j]],adj[curnode][j]));

					}
				}
			}
		}
	}
	for(int i=1;i<=n;i++)
		{
			cin>>x>>y;
			for(int j=1;j<=n;j++)
			{
				if(min_dists[i][j]<=x&&i!=j)
				{
					w2[i].push_back(y);
                    final[i].push_back(j);
				}
			}
		}
    for(int j=0;j<=n;j++)
			fi[j]=1000000000000000;
    fi[fx]=0;
    set<pair<int,long long int> > q2;
	q2.insert(make_pair(0,fx));
	while(!q2.empty())
	{
		curnode=(*q2.begin()).second;
		curw=(*q2.begin()).first;
		q2.erase(q2.begin());
		if(fi[curnode]==curw)
		{
			for(int j=0;j<final[curnode].size();j++)
			{
				if(fi[final[curnode][j]]>fi[curnode]+w2[curnode][j])
					{
						fi[final[curnode][j]]=fi[curnode]+w2[curnode][j];
						q2.insert(make_pair(fi[final[curnode][j]],final[curnode][j]));
					}
			}
		}
	}
	if(fi[fy]<1000000000000000)
		cout<<fi[fy];
	else cout<<-1;

}


#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
long long int min_dists[1002][1002],fi[1002];
vector<int>adj[1002],final[1002],w1[1002],w2[1002];
int main()
{
	int n,m,x,y,z,fx,fy,curnode;
	long long int curw;
	cin>>n>>m;
	cin>>fx>>fy;
	for(int i=0;i<m;i++)
	{
		cin>>x>>y>>z;
		adj[x].push_back(y);
		adj[y].push_back(x);
		w1[x].push_back(z);
		w1[y].push_back(z);
	}
	for(int i=0;i<=n;i++)
		for(int j=0;j<=n;j++)
			min_dists[i][j]=1000000000000000;
	for(int i=1;i<=n;i++)
	{
		min_dists[i][i]=0;
		set<pair<int,int> > q;
		q.insert(make_pair(0,i));
		while(!q.empty())
		{
			curnode=(*q.begin()).second;
			curw=(*q.begin()).first;
			q.erase(q.begin());
			if(min_dists[i][curnode]==curw)
			{
				for(int j=0;j<adj[curnode].size();j++)
				{
					if(min_dists[i][adj[curnode][j]]>min_dists[i][curnode]+w1[curnode][j])
					{
						min_dists[i][adj[curnode][j]]=min_dists[i][curnode]+w1[curnode][j];
						q.insert(make_pair(min_dists[i][adj[curnode][j]],adj[curnode][j]));

					}
				}
			}
		}
	}
	for(int i=1;i<=n;i++)
		{
			cin>>x>>y;
			for(int j=1;j<=n;j++)
			{
				if(min_dists[i][j]<=x&&i!=j)
				{
					w2[i].push_back(y);
                    final[i].push_back(j);
				}
			}
		}
    for(int j=0;j<=n;j++)
			fi[j]=1000000000000000;
    fi[fx]=0;
    set<pair<int,int> > q2;
	q2.insert(make_pair(0,fx));
	while(!q2.empty())
	{
		curnode=(*q2.begin()).second;
		curw=(*q2.begin()).first;
		q2.erase(q2.begin());
		if(fi[curnode]==curw)
		{
			for(int j=0;j<final[curnode].size();j++)
			{
				if(fi[final[curnode][j]]>fi[curnode]+w2[curnode][j])
					{
						fi[final[curnode][j]]=fi[curnode]+w2[curnode][j];
						q2.insert(make_pair(fi[final[curnode][j]],final[curnode][j]));
					}
			}
		}
	}
	if(fi[fy]<1000000000000000)
		cout<<fi[fy];
	else cout<<-1;

}


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

const long long INF = 1ll * 0x3f3f3f3f * 0x3f3f3f3f;

struct Node{
	int to;
	long long dis;
	Node(){}
	Node(int a, long long b){
		to = a;
		dis = b;
	}
	bool operator < (const Node &A) const{
		return dis > A.dis;
	}
};

vector <Node> from[1010];
vector <Node> from2[1010];
long long dis[1010];
int n, m;
int vis[1010];
queue <Node> q;

void spfa(int pos){
	for (int i = 1; i <= n; i++){
		dis[i] = INF, vis[i] = 0;
	}
	dis[pos] = 0;
	while (!q.empty()) q.pop();

	q.push(Node(pos, dis[pos])), vis[pos] = 1;

	while (!q.empty()){
		Node t = q.front(); q.pop(), vis[t.to] = 0;
		int u = t.to;
		for (int i = 0; i < from[u].size(); i++){
			Node tmp = from[u][i];
			int v = tmp.to;
			if (dis[v] > t.dis + tmp.dis){
				dis[v] = t.dis + tmp.dis;
				if (!vis[v]) q.push(Node(v, dis[v])), vis[v] = 1;
			}
		}
	}
}

void spfa2(int pos){
	for (int i = 1; i <= n; i++){
		dis[i] = INF, vis[i] = 0;
	}
	dis[pos] = 0;
	while (!q.empty()) q.pop();

	q.push(Node(pos, dis[pos])), vis[pos] = 1;

	while (!q.empty()){
		Node t = q.front(); q.pop(), vis[t.to] = 0;
		int u = t.to;
		for (int i = 0; i < from2[u].size(); i++){
			Node tmp = from2[u][i];
			int v = tmp.to;
			if (dis[v] > t.dis + tmp.dis){
				dis[v] = t.dis + tmp.dis;
				if (!vis[v]) q.push(Node(v, dis[v])), vis[v] = 1;
			}
		}
	}
}

int main(){
	cin >> n >> m;
	int s, t;
	cin >> s >> t;
	for (int i = 0; i < m; i++){
		int u, v, c;
		scanf("%d%d%d", &u, &v, &c);
		from[u].push_back(Node(v, c));
		from[v].push_back(Node(u, c));
	}
	for (int i = 1; i <= n; i++){
		int t, c;
		scanf("%d%d", &t, &c);
		spfa(i);
		from2[i].push_back(Node(i, 0));
		for (int j = 1; j <= n; j++){
			if (dis[j] <= t) from2[i].push_back(Node(j, c));
		}
	}
	spfa2(s);
	cout << (dis[t] == INF ? -1 : dis[t]) << endl;
	return 0;
}


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

const long long INF = 1ll * 0x3f3f3f3f * 0x3f3f3f3f;

struct Node{
	int to;
	long long dis;
	Node(){}
	Node(int a, long long b){
		to = a;
		dis = b;
	}
	bool operator < (const Node &A) const{
		return dis > A.dis;
	}
};

vector <Node> from[1010];
vector <Node> from2[1010];
long long dis[1010];
int n, m;
int vis[1010];
queue <int> q;

void spfa(int pos){
	for (int i = 1; i <= n; i++){
		dis[i] = INF, vis[i] = 0;
	}
	dis[pos] = 0;
	while (!q.empty()) q.pop();

	q.push(pos), vis[pos] = 1;

	while (!q.empty()){
		int u = q.front(); q.pop(), vis[u] = 0;
		for (int i = 0; i < from[u].size(); i++){
			Node tmp = from[u][i];
			int v = tmp.to;
			if (dis[v] > tmp.dis + dis[u]){
				dis[v] = tmp.dis + dis[u];
				if (!vis[v]) q.push(v), vis[v] = 1;
			}
		}
	}
}

priority_queue <Node> Q;

void Dij(int pos){
	for (int i = 1; i <= n; i++){
		dis[i] = INF;
	}
	dis[pos] = 0;
	while (!Q.empty()) Q.pop();

	Q.push(Node(pos, dis[pos]));

	while (!Q.empty()){
		Node t = Q.top(); Q.pop();
		int u = t.to;
		if (t.dis > dis[u]) continue;
		for (int i = 0; i < from2[u].size(); i++){
			Node tmp = from2[u][i];
			int v = tmp.to;
			if (dis[v] > t.dis + tmp.dis){
				dis[v] = t.dis + tmp.dis;
				Q.push(Node(v, dis[v]));
			}
		}
	}
}

int main(){
	cin >> n >> m;
	int s, t;
	cin >> s >> t;
	for (int i = 0; i < m; i++){
		int u, v, c;
		scanf("%d%d%d", &u, &v, &c);
		from[u].push_back(Node(v, c));
		from[v].push_back(Node(u, c));
	}
	for (int i = 1; i <= n; i++){
		int t, c;
		scanf("%d%d", &t, &c);
		spfa(i);
		from2[i].push_back(Node(i, 0));
		for (int j = 1; j <= n; j++){
			if (dis[j] <= t) from2[i].push_back(Node(j, c));
		}
	}
	Dij(s);
	cout << (dis[t] == INF ? -1 : dis[t]) << endl;
	return 0;
}


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

const int INF = 0x3f3f3f3f;

struct Node{
	int to, dis;
	Node(){}
	Node(int a, int b){
		to = a;
		dis = b;
	}
	bool operator < (const Node &A) const{
		return dis > A.dis;
	}
};

vector <Node> from[1010];
vector <Node> from2[1010];
int dis[1010];
int n, m;
priority_queue <Node> q;

void Dij(int pos){
	for (int i = 1; i <= n; i++){
		dis[i] = INF;
	}
	dis[pos] = 0;
	while (!q.empty()) q.pop();

	q.push(Node(pos, dis[pos]));

	while (!q.empty()){
		Node t = q.top(); q.pop();
		int u = t.to;
		if (t.dis > dis[u]) continue;
		for (int i = 0; i < from[u].size(); i++){
			Node tmp = from[u][i];
			int v = tmp.to;
			if (dis[v] > t.dis + tmp.dis){
				dis[v] = t.dis + tmp.dis;
				q.push(Node(v, dis[v]));
			}
		}
	}
}

void Dij2(int pos){
	for (int i = 1; i <= n; i++){
		dis[i] = INF;
	}
	dis[pos] = 0;
	while (!q.empty()) q.pop();

	q.push(Node(pos, dis[pos]));

	while (!q.empty()){
		Node t = q.top(); q.pop();
		int u = t.to;
		if (t.dis > dis[u]) continue;
		for (int i = 0; i < from2[u].size(); i++){
			Node tmp = from2[u][i];
			int v = tmp.to;
			if (dis[v] > t.dis + tmp.dis){
				dis[v] = t.dis + tmp.dis;
				q.push(Node(v, dis[v]));
			}
		}
	}
}

int main(){
	cin >> n >> m;
	int s, t;
	cin >> s >> t;
	for (int i = 0; i < m; i++){
		int u, v, c;
		scanf("%d%d%d", &u, &v, &c);
		from[u].push_back(Node(v, c));
		from[v].push_back(Node(u, c));
	}
	for (int i = 1; i <= n; i++){
		int t, c;
		scanf("%d%d", &t, &c);
		Dij(i);
		for (int j = 1; j <= n; j++){
			if (dis[j] <= t) from2[i].push_back(Node(j, c));
		}
	}
	Dij2(s);
	cout << (dis[t] == INF ? -1 : dis[t]) << endl;
	return 0;
}


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

const long long INF = 1ll * 0x3f3f3f3f * 0x3f3f3f3f;

struct Node{
	int to;
	long long dis;
	Node(){}
	Node(int a, long long b){
		to = a;
		dis = b;
	}
	bool operator < (const Node &A) const{
		return dis > A.dis;
	}
};

vector <Node> from[1010];
vector <Node> from2[1010];
long long dis[1010];
int n, m;
priority_queue <Node> q;

void Dij(int pos){
	for (int i = 1; i <= n; i++){
		dis[i] = INF;
	}
	dis[pos] = 0;
	while (!q.empty()) q.pop();

	q.push(Node(pos, dis[pos]));

	while (!q.empty()){
		Node t = q.top(); q.pop();
		int u = t.to;
		if (t.dis > dis[u]) continue;
		for (int i = 0; i < from[u].size(); i++){
			Node tmp = from[u][i];
			int v = tmp.to;
			if (dis[v] > t.dis + tmp.dis){
				dis[v] = t.dis + tmp.dis;
				q.push(Node(v, dis[v]));
			}
		}
	}
}

void Dij2(int pos){
	for (int i = 1; i <= n; i++){
		dis[i] = INF;
	}
	dis[pos] = 0;
	while (!q.empty()) q.pop();

	q.push(Node(pos, dis[pos]));

	while (!q.empty()){
		Node t = q.top(); q.pop();
		int u = t.to;
		if (t.dis > dis[u]) continue;
		for (int i = 0; i < from2[u].size(); i++){
			Node tmp = from2[u][i];
			int v = tmp.to;
			if (dis[v] > t.dis + tmp.dis){
				dis[v] = t.dis + tmp.dis;
				q.push(Node(v, dis[v]));
			}
		}
	}
}

int main(){
	cin >> n >> m;
	int s, t;
	cin >> s >> t;
	for (int i = 0; i < m; i++){
		int u, v, c;
		scanf("%d%d%d", &u, &v, &c);
		from[u].push_back(Node(v, c));
		from[v].push_back(Node(u, c));
	}
	for (int i = 1; i <= n; i++){
		int t, c;
		scanf("%d%d", &t, &c);
		Dij(i);
		from2[i].push_back(Node(i, 0));
		for (int j = 1; j <= n; j++){
			if (dis[j] <= t) from2[i].push_back(Node(j, c));
		}
	}
	Dij2(s);
	cout << (dis[t] == INF ? -1 : dis[t]) << endl;
	return 0;
}


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

const long long INF = 1ll * 0x3f3f3f3f * 0x3f3f3f3f;

struct Node{
	int to;
	long long dis;
	Node(){}
	Node(int a, long long b){
		to = a;
		dis = b;
	}
	bool operator < (const Node &A) const{
		return dis > A.dis;
	}
};

vector <Node> from[1010];
vector <Node> from2[1010];
long long dis[1010];
int n, m;
int vis[1010];
queue <Node> q;

void spfa(int pos){
	for (int i = 1; i <= n; i++){
		dis[i] = INF, vis[i] = 0;
	}
	dis[pos] = 0;
	while (!q.empty()) q.pop();

	q.push(Node(pos, dis[pos])), vis[pos] = 1;

	while (!q.empty()){
		Node t = q.front(); q.pop(), vis[t.to] = 0;
		int u = t.to;
		for (int i = 0; i < from[u].size(); i++){
			Node tmp = from[u][i];
			int v = tmp.to;
			if (dis[v] > t.dis + tmp.dis){
				dis[v] = t.dis + tmp.dis;
				if (!vis[v]) q.push(Node(v, dis[v])), vis[v] = 1;
			}
		}
	}
}

priority_queue <Node> Q;

void Dij(int pos){
	for (int i = 1; i <= n; i++){
		dis[i] = INF;
	}
	dis[pos] = 0;
	while (!Q.empty()) Q.pop();

	Q.push(Node(pos, dis[pos]));

	while (!Q.empty()){
		Node t = Q.top(); Q.pop();
		int u = t.to;
		if (t.dis > dis[u]) continue;
		for (int i = 0; i < from2[u].size(); i++){
			Node tmp = from2[u][i];
			int v = tmp.to;
			if (dis[v] > t.dis + tmp.dis){
				dis[v] = t.dis + tmp.dis;
				Q.push(Node(v, dis[v]));
			}
		}
	}
}

int main(){
	cin >> n >> m;
	int s, t;
	cin >> s >> t;
	for (int i = 0; i < m; i++){
		int u, v, c;
		scanf("%d%d%d", &u, &v, &c);
		from[u].push_back(Node(v, c));
		from[v].push_back(Node(u, c));
	}
	for (int i = 1; i <= n; i++){
		int t, c;
		scanf("%d%d", &t, &c);
		spfa(i);
		from2[i].push_back(Node(i, 0));
		for (int j = 1; j <= n; j++){
			if (dis[j] <= t) from2[i].push_back(Node(j, c));
		}
	}
	Dij(s);
	cout << (dis[t] == INF ? -1 : dis[t]) << endl;
	return 0;
}


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

const int INF = 0x3f3f3f3f;

struct Node{
	int to, dis;
	Node(){}
	Node(int a, int b){
		to = a;
		dis = b;
	}
	bool operator < (const Node &A) const{
		return dis > A.dis;
	}
};

vector <Node> from[1010];
vector <Node> from2[1010];
int dis[1010];
int n, m;
priority_queue <Node> q;

void Dij(int pos){
	for (int i = 1; i <= n; i++){
		dis[i] = INF;
	}
	dis[pos] = 0;
	while (!q.empty()) q.pop();

	q.push(Node(pos, dis[pos]));

	while (!q.empty()){
		Node t = q.top(); q.pop();
		int u = t.to;
		if (t.dis > dis[u]) continue;
		for (int i = 0; i < from[u].size(); i++){
			Node tmp = from[u][i];
			int v = tmp.to;
			if (dis[v] > t.dis + tmp.dis){
				dis[v] = t.dis + tmp.dis;
				q.push(Node(v, dis[v]));
			}
		}
	}
}

void Dij2(int pos){
	for (int i = 1; i <= n; i++){
		dis[i] = INF;
	}
	dis[pos] = 0;
	while (!q.empty()) q.pop();

	q.push(Node(pos, dis[pos]));

	while (!q.empty()){
		Node t = q.top(); q.pop();
		int u = t.to;
		if (t.dis > dis[u]) continue;
		for (int i = 0; i < from2[u].size(); i++){
			Node tmp = from2[u][i];
			int v = tmp.to;
			if (dis[v] > t.dis + tmp.dis){
				dis[v] = t.dis + tmp.dis;
				q.push(Node(v, dis[v]));
			}
		}
	}
}

int main(){
	cin >> n >> m;
	int s, t;
	cin >> s >> t;
	for (int i = 0; i < m; i++){
		int u, v, c;
		scanf("%d%d%d", &u, &v, &c);
		from[u].push_back(Node(v, c));
		from[v].push_back(Node(u, c));
	}
	for (int i = 1; i <= n; i++){
		int t, c;
		scanf("%d%d", &t, &c);
		Dij(i);
		from2[i].push_back(Node(i, 0));
		for (int j = 1; j <= n; j++){
			if (dis[j] <= t) from2[i].push_back(Node(j, c));
		}
	}
	Dij2(s);
	cout << (dis[t] == INF ? -1 : dis[t]) << endl;
	return 0;
}


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

const long long INF = 1ll * 0x3f3f3f3f * 0x3f3f3f3f;

struct Node{
	int to;
	long long dis;
	Node(){}
	Node(int a, long long b){
		to = a;
		dis = b;
	}
	bool operator < (const Node &A) const{
		return dis > A.dis;
	}
};

vector <Node> from[1010];
vector <Node> from2[1010];
long long dis[1010];
int n, m;
int vis[1010];
queue <int> q;

void spfa(int pos){
	for (int i = 1; i <= n; i++){
		dis[i] = INF, vis[i] = 0;
	}
	dis[pos] = 0;
	while (!q.empty()) q.pop();

	q.push(pos), vis[pos] = 1;

	while (!q.empty()){
		int u = q.front(); q.pop(), vis[u] = 0;
		for (int i = 0; i < from[u].size(); i++){
			Node tmp = from[u][i];
			int v = tmp.to;
			if (dis[v] > tmp.dis + dis[u]){
				dis[v] = tmp.dis + dis[u];
				if (!vis[v]) q.push(v), vis[v] = 1;
			}
		}
	}
}

void spfa2(int pos){
	for (int i = 1; i <= n; i++){
		dis[i] = INF, vis[i] = 0;
	}
	dis[pos] = 0;
	while (!q.empty()) q.pop();

	q.push(pos), vis[pos] = 1;

	while (!q.empty()){
		int u = q.front(); q.pop(), vis[u] = 0;
		for (int i = 0; i < from2[u].size(); i++){
			Node tmp = from2[u][i];
			int v = tmp.to;
			if (dis[v] > dis[u] + tmp.dis){
				dis[v] = dis[u] + tmp.dis;
				if (!vis[v]) q.push(v), vis[v] = 1;
			}
		}
	}
}

int main(){
	cin >> n >> m;
	int s, t;
	cin >> s >> t;
	for (int i = 0; i < m; i++){
		int u, v, c;
		scanf("%d%d%d", &u, &v, &c);
		from[u].push_back(Node(v, c));
		from[v].push_back(Node(u, c));
	}
	for (int i = 1; i <= n; i++){
		int t, c;
		scanf("%d%d", &t, &c);
		spfa(i);
		from2[i].push_back(Node(i, 0));
		for (int j = 1; j <= n; j++){
			if (dis[j] <= t) from2[i].push_back(Node(j, c));
		}
	}
	spfa2(s);
	cout << (dis[t] == INF ? -1 : dis[t]) << endl;
	return 0;
}


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

const long long INF = 1ll * 0x3f3f3f3f * 0x3f3f3f3f;

struct Node{
	int to;
	long long dis;
	Node(){}
	Node(int a, long long b){
		to = a;
		dis = b;
	}
	bool operator < (const Node &A) const{
		return dis > A.dis;
	}
};

vector <Node> from[1010];
vector <Node> from2[1010];
long long dis[1010];
int n, m;
int vis[1010];
queue <Node> q;

void spfa(int pos){
	for (int i = 1; i <= n; i++){
		dis[i] = INF;
	}
	dis[pos] = 0;
	while (!q.empty()) q.pop();

	q.push(Node(pos, dis[pos]));

	while (!q.empty()){
		Node t = q.front(); q.pop(), vis[t.to] = 0;
		int u = t.to;
		for (int i = 0; i < from[u].size(); i++){
			Node tmp = from[u][i];
			int v = tmp.to;
			if (dis[v] > t.dis + tmp.dis){
				dis[v] = t.dis + tmp.dis;
				if (!vis[v]) q.push(Node(v, dis[v])), vis[v] = 1;
			}
		}
	}
}

void spfa2(int pos){
	for (int i = 1; i <= n; i++){
		dis[i] = INF;
	}
	dis[pos] = 0;
	while (!q.empty()) q.pop();

	q.push(Node(pos, dis[pos]));

	while (!q.empty()){
		Node t = q.front(); q.pop(), vis[t.to] = 0;
		int u = t.to;
		for (int i = 0; i < from2[u].size(); i++){
			Node tmp = from2[u][i];
			int v = tmp.to;
			if (dis[v] > t.dis + tmp.dis){
				dis[v] = t.dis + tmp.dis;
				if (!vis[v]) q.push(Node(v, dis[v])), vis[v] = 1;
			}
		}
	}
}

int main(){
	cin >> n >> m;
	int s, t;
	cin >> s >> t;
	for (int i = 0; i < m; i++){
		int u, v, c;
		scanf("%d%d%d", &u, &v, &c);
		from[u].push_back(Node(v, c));
		from[v].push_back(Node(u, c));
	}
	for (int i = 1; i <= n; i++){
		int t, c;
		scanf("%d%d", &t, &c);
		spfa(i);
		from2[i].push_back(Node(i, 0));
		for (int j = 1; j <= n; j++){
			if (dis[j] <= t) from2[i].push_back(Node(j, c));
		}
	}
	spfa2(s);
	cout << (dis[t] == INF ? -1 : dis[t]) << endl;
	return 0;
}