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

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

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

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

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

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

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

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


/*  ^^ ====== ^^
ID: meixiuxiu
PROG: test
LANG: C++11
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int ,int> pii;
#define MEM(a,b) memset(a,b,sizeof a)
#define CLR(a) memset(a,0,sizeof a);
#define pi acos(-1.0)
#define maxn 40000
#define maxv 100005
const ll inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int x,y;
int n,m;
ll dis[1005][1005];
bool vis[1005];
ll ans[1005];
int t[1005];
int c[1005];

const int maxm = 1e6+50;
int head[1005];
int nxt[maxm], pnt[maxm];
ll cost[maxm];

struct node
{
    int v;
    ll w;
    node(int v,ll w):v(v),w(w){}
    bool operator < (const node &r)const{
        return w > r.w;
    }
};
int cnt ;
std::vector<node> edge[1005];
void dij(int s, long long int *dis){
    for (int i = 1; i <= n; i++) dis[i] = inf;
    dis[s] = 0;
    MEM(vis,0);
    priority_queue<node> q;q.push(node(s,0));
    while(!q.empty()){
        node x = q.top();q.pop();
        ll u = x.v;;
        if (x.w > dis[u]) continue;
        // if(vis[u])continue;vis[u] = 1;
        for(int i = head[u]; ~i; i = nxt[i]){
            int v = pnt[i];
            ll w = cost[i];
            if(dis[v] > dis[u] + w){
                dis[v] = dis[u]+w;
                // if(!vis[v]){
                    q.push(node(v,dis[v]));
                // }
            }
        }
    }
}

void add_edge(int u, int v, ll c) {
    pnt[cnt] = v;
    nxt[cnt] = head[u];
    cost[cnt] = c;
    head[u] = cnt++;
}

int main()
{
#ifdef LOCAL
	freopen("in.txt", "r", stdin);
//	freopen("out.txt","w",stdout);
#endif
    memset(head, 0xff, sizeof head);
    cnt = 0;
    cin >> n >>m >> x >> y;
    MEM(dis,inf);
    for(int i=1;i<=m;i++){
        int u,v, w;scanf("%d%d%d",&u,&v,&w);
        dis[u][v] = min(dis[u][v],1ll*w);
        dis[v][u] = min(dis[v][u],1ll*w);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(dis[i][j]!=inf){
                add_edge(i, j, dis[i][j]);
                // edge[i].push_back(node(j,dis[i][j]));
            }
        }
    }
    for(int i=1;i<=n;i++){
        dij(i, dis[i]);
    }
    cnt = 0;
    for(int i=1;i<=n;i++){
        // edge[i].clear();
        head[i] = -1;
        scanf("%d%d",&t[i],&c[i]);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(i==j || dis[i][j]>t[i])continue;
            // edge[i].push_back(node(j,c[i]));
            add_edge(i, j, c[i]);
        }
    }
    dij(x, dis[x]);
    if(dis[x][y]<inf){
        cout << dis[x][y] <<endl;
    }
    else cout <<-1 <<endl;
	return 0;
}


/*  ^^ ====== ^^
ID: meixiuxiu
PROG: test
LANG: C++11
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int ,int> pii;
#define MEM(a,b) memset(a,b,sizeof a)
#define CLR(a) memset(a,0,sizeof a);
#define pi acos(-1.0)
#define maxn 40000
#define maxv 100005
const ll inf = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1e9 + 7;
int x,y;
int n,m;
ll dis[1005];
bool vis[1005];
ll ans[1005];
int t[1005];
int c[1005];

const int maxm = 1e6+50;
int head[1005];
int nxt[2*maxm], pnt[2*maxm];
ll cost[2*maxm];
int head1[1005];

struct node
{
    int v;
    ll w;
    node(int v,ll w):v(v),w(w){}
    bool operator < (const node &r)const{
        return w > r.w;
    }
};
int cnt, cnt1;
std::vector<node> edge[1005];
void dij(int s, int *head){
    memset(dis, 0x3f, sizeof dis);
    dis[s] = 0;
    MEM(vis,0);
    priority_queue<node> q;q.push(node(s,0));
    while(!q.empty()){
        node x = q.top();q.pop();
        int u = x.v;;
        if (x.w > dis[u]) continue;
        // if(vis[u])continue;vis[u] = 1;
        for(int i = head[u]; ~i; i = nxt[i]){
            int v = pnt[i];
            ll w = cost[i];
            if(dis[v] > dis[u] + w){
                dis[v] = dis[u]+w;
                // if(!vis[v]){
                    q.push(node(v,dis[v]));
                // }
            }
        }
    }
}

void add_edge(int *head, int u, int v, ll c) {
    pnt[cnt] = v;
    nxt[cnt] = head[u];
    cost[cnt] = c;
    head[u] = cnt++;
}

int main()
{
#ifdef LOCAL
    freopen("C:\\\\Users\\\\zzblack\\\\Desktop\\\\case.in","r",stdin);
    freopen("C:\\\\Users\\\\zzblack\\\\Desktop\\\\case.out","w",stdout);
#endif
    memset(head, 0xff, sizeof head);
    memset(head1, 0xff, sizeof head1);
    cnt = 0; cnt1 = 0;
    scanf("%d%d%d%d", &n, &m, &x, &y);
    MEM(dis,inf);
    for(int i=1;i<=m;i++){
        int u,v, w;scanf("%d%d%d",&u,&v,&w);
        add_edge(head, u, v, w);
        add_edge(head, v, u, w);
    }
    // for(int i=1;i<=n;i++){
    //     for(int j=1;j<=n;j++){
    //         if(dis[i][j]!=inf){
    //             add_edge(i, j, dis[i][j]);
    //             // edge[i].push_back(node(j,dis[i][j]));
    //         }
    //     }
    // }
    for(int i=1;i<=n;i++){
        // // edge[i].clear();
        // head[i] = -1;
        scanf("%d%d",&t[i],&c[i]);
    }
    for(int i=1;i<=n;i++){
        dij(i, head);
        for (int j = 1; j <= n; j++) {
            if(j == i || dis[j] > t[i]) continue;
            add_edge(head1, i, j, c[i]);
        }
    }
    // for(int i=1;i<=n;i++){
    //     for(int j=1;j<=n;j++){
    //         if(i==j || dis[i][j]>t[i])continue;
    //         // edge[i].push_back(node(j,c[i]));
    //         add_edge(i, j, c[i]);
    //     }
    // }
    dij(x, head1);
    if(dis[y]<inf){
        printf("%I64d\n", dis[y]);
    }
    else puts("-1");
	return 0;
}


/*  ^^ ====== ^^
ID: meixiuxiu
PROG: test
LANG: C++11
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int ,int> pii;
#define MEM(a,b) memset(a,b,sizeof a)
#define CLR(a) memset(a,0,sizeof a);
#define pi acos(-1.0)
#define maxn 40000
#define maxv 100005
const ll inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int x,y;
int n,m;
ll dis[1005][1005];
bool vis[1005];
ll ans[1005];
int t[1005];
int c[1005];

const int maxm = 1e6+50;
int head[1005];
int nxt[maxm], pnt[maxm];
ll cost[maxm];

struct node
{
    int v;
    ll w;
    node(int v,ll w):v(v),w(w){}
    bool operator < (const node &r)const{
        return w > r.w;
    }
};
int cnt ;
std::vector<node> edge[1005];
void dij(int s, long long int *dis){
    for (int i = 1; i <= n; i++) dis[i] = inf;
    dis[s] = 0;
    MEM(vis,0);
    priority_queue<node> q;q.push(node(s,0));
    while(!q.empty()){
        node x = q.top();q.pop();
        int u = x.v;;
        if (x.w > dis[u]) continue;
        // if(vis[u])continue;vis[u] = 1;
        for(int i = head[u]; ~i; i = nxt[i]){
            int v = pnt[i];
            ll w = cost[i];
            if(dis[v] > dis[u] + w){
                dis[v] = dis[u]+w;
                // if(!vis[v]){
                    q.push(node(v,dis[v]));
                // }
            }
        }
    }
}

void add_edge(int u, int v, ll c) {
    pnt[cnt] = v;
    nxt[cnt] = head[u];
    cost[cnt] = c;
    head[u] = cnt++;
}

int main()
{
#ifdef LOCAL
	freopen("in.txt", "r", stdin);
//	freopen("out.txt","w",stdout);
#endif
    memset(head, 0xff, sizeof head);
    cnt = 0;
    scanf("%d%d%d%d", &n, &m, &x, &y);
    MEM(dis,inf);
    for(int i=1;i<=m;i++){
        int u,v, w;scanf("%d%d%d",&u,&v,&w);
        dis[u][v] = min(dis[u][v],1ll*w);
        dis[v][u] = min(dis[v][u],1ll*w);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(dis[i][j]!=inf){
                add_edge(i, j, dis[i][j]);
                // edge[i].push_back(node(j,dis[i][j]));
            }
        }
    }
    for(int i=1;i<=n;i++){
        dij(i, dis[i]);
    }
    cnt = 0;
    for(int i=1;i<=n;i++){
        // edge[i].clear();
        head[i] = -1;
        scanf("%d%d",&t[i],&c[i]);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(i==j || dis[i][j]>t[i])continue;
            // edge[i].push_back(node(j,c[i]));
            add_edge(i, j, c[i]);
        }
    }
    dij(x, dis[x]);
    if(dis[x][y]<inf){
        printf("%I64d\n", dis[x][y]);
    }
    else puts("-1");
	return 0;
}


/*  ^^ ====== ^^
ID: meixiuxiu
PROG: test
LANG: C++11
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int ,int> pii;
#define MEM(a,b) memset(a,b,sizeof a)
#define CLR(a) memset(a,0,sizeof a);
#define pi acos(-1.0)
#define maxn 40000
#define maxv 100005
const ll inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int x,y;
int n,m;
ll dis[1005][1005];
bool vis[1005];
ll ans[1005];
int t[1005];
int c[1005];

const int maxm = 1e6+50;
int head[1005];
int nxt[maxm], pnt[maxm];
ll cost[maxm];

struct node
{
    int v;
    ll w;
    node(int v,ll w):v(v),w(w){}
    bool operator < (const node &r)const{
        return w > r.w;
    }
};
int cnt ;
std::vector<node> edge[1005];
void dij(int s, long long int *dis){
    for (int i = 1; i <= n; i++) dis[i] = inf;
    dis[s] = 0;
    MEM(vis,0);
    priority_queue<node> q;q.push(node(s,0));
    while(!q.empty()){
        node x = q.top();q.pop();
        ll u = x.v;;
        if(vis[u])continue;vis[u] = 1;
        for(int i = head[u]; ~i; i = nxt[i]){
            int v = pnt[i];
            ll w = cost[i];
            if(dis[v] > dis[u] + w){
                dis[v] = dis[u]+w;
                if(!vis[v]){
                    q.push(node(v,dis[v]));
                }
            }
        }
    }
}

void add_edge(int u, int v, ll c) {
    pnt[cnt] = v;
    nxt[cnt] = head[u];
    cost[cnt] = c;
    head[u] = cnt++;
}

int main()
{
#ifdef LOCAL
	freopen("in.txt", "r", stdin);
//	freopen("out.txt","w",stdout);
#endif
    memset(head, 0xff, sizeof head);
    cnt = 0;
    cin >> n >>m >> x >> y;
    MEM(dis,inf);
    for(int i=1;i<=m;i++){
        int u,v, w;scanf("%d%d%d",&u,&v,&w);
        dis[u][v] = min(dis[u][v],1ll*w);
        dis[v][u] = min(dis[v][u],1ll*w);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(dis[i][j]!=inf){
                add_edge(i, j, dis[i][j]);
                // edge[i].push_back(node(j,dis[i][j]));
            }
        }
    }
    for(int i=1;i<=n;i++){
        dij(i, dis[i]);
    }
    cnt = 0;
    for(int i=1;i<=n;i++){
        // edge[i].clear();
        head[i] = -1;
        scanf("%d%d",&t[i],&c[i]);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(i==j || dis[i][j]>t[i])continue;
            // edge[i].push_back(node(j,c[i]));
            add_edge(i, j, c[i]);
        }
    }
    dij(x, dis[x]);
    if(dis[x][y]<inf){
        cout << dis[x][y] <<endl;
    }
    else cout <<-1 <<endl;
	return 0;
}


/*  ^^ ====== ^^
ID: meixiuxiu
PROG: test
LANG: C++11
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int ,int> pii;
#define MEM(a,b) memset(a,b,sizeof a)
#define CLR(a) memset(a,0,sizeof a);
#define pi acos(-1.0)
#define maxn 40000
#define maxv 100005
const ll inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int x,y;
int n,m;
ll dis[1005];
bool vis[1005];
ll ans[1005];
int t[1005];
int c[1005];

const int maxm = 1e6+50;
int head[1005];
int nxt[2*maxm], pnt[2*maxm];
ll cost[2*maxm];
int head1[1005];

struct node
{
    int v;
    ll w;
    node(int v,ll w):v(v),w(w){}
    bool operator < (const node &r)const{
        return w > r.w;
    }
};
int cnt, cnt1;
std::vector<node> edge[1005];
void dij(int s){
    for (int i = 1; i <= n; i++) dis[i] = inf;
    dis[s] = 0;
    MEM(vis,0);
    priority_queue<node> q;q.push(node(s,0));
    while(!q.empty()){
        node x = q.top();q.pop();
        int u = x.v;;
        if (x.w > dis[u]) continue;
        // if(vis[u])continue;vis[u] = 1;
        for(int i = head[u]; ~i; i = nxt[i]){
            int v = pnt[i];
            ll w = cost[i];
            if(dis[v] > dis[u] + w){
                dis[v] = dis[u]+w;
                // if(!vis[v]){
                    q.push(node(v,dis[v]));
                // }
            }
        }
    }
}

void add_edge(int *head, int &cnt, int u, int v, ll c) {
    pnt[cnt] = v;
    nxt[cnt] = head[u];
    cost[cnt] = c;
    head[u] = cnt++;
}

int main()
{
#ifdef LOCAL
	freopen("in.txt", "r", stdin);
//	freopen("out.txt","w",stdout);
#endif
    memset(head, 0xff, sizeof head);
    memset(head1, 0xff, sizeof head1);
    cnt = 0; cnt1 = 0;
    scanf("%d%d%d%d", &n, &m, &x, &y);
    MEM(dis,inf);
    for(int i=1;i<=m;i++){
        int u,v, w;scanf("%d%d%d",&u,&v,&w);
        add_edge(head, cnt, u, v, w);
        add_edge(head, cnt, v, u, w);
    }
    // for(int i=1;i<=n;i++){
    //     for(int j=1;j<=n;j++){
    //         if(dis[i][j]!=inf){
    //             add_edge(i, j, dis[i][j]);
    //             // edge[i].push_back(node(j,dis[i][j]));
    //         }
    //     }
    // }
    for(int i=1;i<=n;i++){
        // // edge[i].clear();
        // head[i] = -1;
        scanf("%d%d",&t[i],&c[i]);
    }
    for(int i=1;i<=n;i++){
        dij(i);
        for (int j = 1; j <= n; j++) {
            if(j == i || dis[j] > t[i]) continue;
            add_edge(head1, cnt1, i, j, c[i]);
        }
    }
    // for(int i=1;i<=n;i++){
    //     for(int j=1;j<=n;j++){
    //         if(i==j || dis[i][j]>t[i])continue;
    //         // edge[i].push_back(node(j,c[i]));
    //         add_edge(i, j, c[i]);
    //     }
    // }
    dij(x);
    if(dis[y]<inf){
        printf("%I64d\n", dis[y]);
    }
    else puts("-1");
	return 0;
}


/*  ^^ ====== ^^
ID: meixiuxiu
PROG: test
LANG: C++11
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int ,int> pii;
#define MEM(a,b) memset(a,b,sizeof a)
#define CLR(a) memset(a,0,sizeof a);
#define pi acos(-1.0)
#define maxn 40000
#define maxv 100005
const ll inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int x,y;
int n,m;
ll dis[1005];
bool vis[1005];
ll ans[1005];
int t[1005];
int c[1005];

const int maxm = 1e6+50;
int head[1005];
int nxt[2*maxm], pnt[2*maxm];
ll cost[2*maxm];
int head1[1005];

struct node
{
    int v;
    ll w;
    node(int v,ll w):v(v),w(w){}
    bool operator < (const node &r)const{
        return w > r.w;
    }
};
int cnt, cnt1;
std::vector<node> edge[1005];
void dij(int s, int *head){
    for (int i = 1; i <= n; i++) dis[i] = inf;
    dis[s] = 0;
    MEM(vis,0);
    priority_queue<node> q;q.push(node(s,0));
    while(!q.empty()){
        node x = q.top();q.pop();
        int u = x.v;;
        if (x.w > dis[u]) continue;
        // if(vis[u])continue;vis[u] = 1;
        for(int i = head[u]; ~i; i = nxt[i]){
            int v = pnt[i];
            ll w = cost[i];
            if(dis[v] > dis[u] + w){
                dis[v] = dis[u]+w;
                // if(!vis[v]){
                    q.push(node(v,dis[v]));
                // }
            }
        }
    }
}

void add_edge(int *head, int &cnt, int u, int v, ll c) {
    pnt[cnt] = v;
    nxt[cnt] = head[u];
    cost[cnt] = c;
    head[u] = cnt++;
}

int main()
{
#ifdef LOCAL
    freopen("C:\\\\Users\\\\zzblack\\\\Desktop\\\\case.in","r",stdin);
    freopen("C:\\\\Users\\\\zzblack\\\\Desktop\\\\case.out","w",stdout);
#endif
    memset(head, 0xff, sizeof head);
    memset(head1, 0xff, sizeof head1);
    cnt = 0; cnt1 = 0;
    scanf("%d%d%d%d", &n, &m, &x, &y);
    MEM(dis,inf);
    for(int i=1;i<=m;i++){
        int u,v, w;scanf("%d%d%d",&u,&v,&w);
        add_edge(head, cnt, u, v, w);
        add_edge(head, cnt, v, u, w);
    }
    // for(int i=1;i<=n;i++){
    //     for(int j=1;j<=n;j++){
    //         if(dis[i][j]!=inf){
    //             add_edge(i, j, dis[i][j]);
    //             // edge[i].push_back(node(j,dis[i][j]));
    //         }
    //     }
    // }
    for(int i=1;i<=n;i++){
        // // edge[i].clear();
        // head[i] = -1;
        scanf("%d%d",&t[i],&c[i]);
    }
    for(int i=1;i<=n;i++){
        dij(i, head);
        for (int j = 1; j <= n; j++) {
            if(j == i || dis[j] > t[i]) continue;
            add_edge(head1, cnt1, i, j, c[i]);
        }
    }
    // for(int i=1;i<=n;i++){
    //     for(int j=1;j<=n;j++){
    //         if(i==j || dis[i][j]>t[i])continue;
    //         // edge[i].push_back(node(j,c[i]));
    //         add_edge(i, j, c[i]);
    //     }
    // }
    dij(x, head1);
    if(dis[y]<inf){
        printf("%I64d\n", dis[y]);
    }
    else puts("-1");
	return 0;
}


/*  ^^ ====== ^^
ID: meixiuxiu
PROG: test
LANG: C++11
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int ,int> pii;
#define MEM(a,b) memset(a,b,sizeof a)
#define CLR(a) memset(a,0,sizeof a);
#define pi acos(-1.0)
#define maxn 40000
#define maxv 100005
const ll inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int x,y;
int n,m;
ll dis[1005][1005];
bool vis[1005];
ll ans[1005];
int t[1005];
int c[1005];
struct node
{
    int v;
    ll w;
    node(int v,ll w):v(v),w(w){}
    bool operator < (const node &r)const{
        return w > r.w;
    }
};
std::vector<node> edge[1005];
void dij(int s, long long int *dis){
    for (int i = 1; i <= n; i++) dis[i] = inf;
    dis[s] = 0;
    MEM(vis,0);
    priority_queue<node> q;q.push(node(s,0));
    while(!q.empty()){
        node x = q.top();q.pop();
        ll u = x.v;;
        if(vis[u])continue;vis[u] = 1;
        for(int i=0;i<edge[u].size();i++){
            int v = edge[u][i].v;
            ll w = edge[u][i].w;
            if(dis[v] > dis[u] + w){
                dis[v] = dis[u]+w;
                if(!vis[v]){
                    q.push(node(v,dis[v]));
                }
            }
        }
    }
}
int main()
{
#ifdef LOCAL
	freopen("in.txt", "r", stdin);
//	freopen("out.txt","w",stdout);
#endif
    cin >> n >>m >> x >> y;
    MEM(dis,inf);
    for(int i=1;i<=m;i++){
        int u,v, w;scanf("%d%d%d",&u,&v,&w);
        dis[u][v] = min(dis[u][v],1ll*w);
        dis[v][u] = min(dis[v][u],1ll*w);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(dis[i][j]!=inf){
                edge[i].push_back(node(j,dis[i][j]));
            }
        }
    }
    for(int i=1;i<=n;i++){
        dij(i, dis[i]);
    }
    for(int i=1;i<=n;i++){
        edge[i].clear();
        scanf("%d%d",&t[i],&c[i]);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(i==j || dis[i][j]>t[i])continue;
            edge[i].push_back(node(j,c[i]));
        }
    }
    dij(x, dis[x]);
    if(dis[x][y]<inf){
        cout << dis[x][y] <<endl;
    }
    else cout <<-1 <<endl;
	return 0;
}


/*  ^^ ====== ^^
ID: meixiuxiu
PROG: test
LANG: C++11
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int ,int> pii;
#define MEM(a,b) memset(a,b,sizeof a)
#define CLR(a) memset(a,0,sizeof a);
#define pi acos(-1.0)
#define maxn 40000
#define maxv 100005
const ll inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int x,y;
int n,m;
ll dis[1005][1005];
bool vis[1005];
ll ans[1005];
int t[1005];
int c[1005];
struct node
{
    int v;
    ll w;
    node(int v,ll w):v(v),w(w){}
    bool operator < (const node &r)const{
        return w > r.w;
    }
};
std::vector<node> edge[1005];
void dij(int s, int *dis){
    for (int i = 1; i <= n; i++) dis[i] = inf;
    dis[s] = 0;
    MEM(vis,0);
    priority_queue<node> q;q.push(node(s,0));
    while(!q.empty()){
        node x = q.top();q.pop();
        ll u = x.v;;
        if(vis[u])continue;vis[u] = 1;
        for(int i=0;i<edge[u].size();i++){
            int v = edge[u][i].v;
            ll w = edge[u][i].w;
            if(dis[v] > dis[u] + w){
                dis[v] = dis[u]+w;
                if(!vis[v]){
                    q.push(node(v,dis[v]));
                }
            }
        }
    }
}
int main()
{
#ifdef LOCAL
	freopen("in.txt", "r", stdin);
//	freopen("out.txt","w",stdout);
#endif
    cin >> n >>m >> x >> y;
    MEM(dis,inf);
    for(int i=1;i<=m;i++){
        int u,v, w;scanf("%d%d%d",&u,&v,&w);
        dis[u][v] = min(dis[u][v],1ll*w);
        dis[v][u] = min(dis[v][u],1ll*w);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(dis[i][j]!=inf){
                edge[i].push_back(node(j,dis[i][j]));
            }
        }
    }
    for(int i=1;i<=n;i++){
        dij(i, dis[i]);
    }
    for(int i=1;i<=n;i++){
        edge[i].clear();
        scanf("%d%d",&t[i],&c[i]);
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(i==j || dis[i][j]>t[i])continue;
            edge[i].push_back(node(j,c[i]));
        }
    }
    dij(x);
    if(dis[x][y]<inf){
        cout << dis[x][y] <<endl;
    }
    else cout <<-1 <<endl;
	return 0;
}


/*  ^^ ====== ^^
ID: meixiuxiu
PROG: test
LANG: C++11
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int ,int> pii;
#define MEM(a,b) memset(a,b,sizeof a)
#define CLR(a) memset(a,0,sizeof a);
#define pi acos(-1.0)
#define maxn 40000
#define maxv 100005
const ll inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int x,y;
int n,m;
ll dis[1005];
bool vis[1005];
ll ans[1005];
int t[1005];
int c[1005];

const int maxm = 1e6+50;
int head[1005];
int nxt[2*maxm], pnt[2*maxm];
ll cost[2*maxm];
int head1[1005];

struct node
{
    int v;
    ll w;
    node(int v,ll w):v(v),w(w){}
    bool operator < (const node &r)const{
        return w > r.w;
    }
};
int cnt, cnt1;
std::vector<node> edge[1005];
void dij(int s, int *head){
    for (int i = 1; i <= n; i++) dis[i] = inf;
    dis[s] = 0;
    MEM(vis,0);
    priority_queue<node> q;q.push(node(s,0));
    while(!q.empty()){
        node x = q.top();q.pop();
        int u = x.v;;
        if (x.w > dis[u]) continue;
        // if(vis[u])continue;vis[u] = 1;
        for(int i = head[u]; ~i; i = nxt[i]){
            int v = pnt[i];
            ll w = cost[i];
            if(dis[v] > dis[u] + w){
                dis[v] = dis[u]+w;
                // if(!vis[v]){
                    q.push(node(v,dis[v]));
                // }
            }
        }
    }
}

void add_edge(int *head, int u, int v, ll c) {
    pnt[cnt] = v;
    nxt[cnt] = head[u];
    cost[cnt] = c;
    head[u] = cnt++;
}

int main()
{
#ifdef LOCAL
    freopen("C:\\\\Users\\\\zzblack\\\\Desktop\\\\case.in","r",stdin);
    freopen("C:\\\\Users\\\\zzblack\\\\Desktop\\\\case.out","w",stdout);
#endif
    memset(head, 0xff, sizeof head);
    memset(head1, 0xff, sizeof head1);
    cnt = 0; cnt1 = 0;
    scanf("%d%d%d%d", &n, &m, &x, &y);
    MEM(dis,inf);
    for(int i=1;i<=m;i++){
        int u,v, w;scanf("%d%d%d",&u,&v,&w);
        add_edge(head, u, v, w);
        add_edge(head, v, u, w);
    }
    // for(int i=1;i<=n;i++){
    //     for(int j=1;j<=n;j++){
    //         if(dis[i][j]!=inf){
    //             add_edge(i, j, dis[i][j]);
    //             // edge[i].push_back(node(j,dis[i][j]));
    //         }
    //     }
    // }
    for(int i=1;i<=n;i++){
        // // edge[i].clear();
        // head[i] = -1;
        scanf("%d%d",&t[i],&c[i]);
    }
    for(int i=1;i<=n;i++){
        dij(i, head);
        for (int j = 1; j <= n; j++) {
            if(j == i || dis[j] > t[i]) continue;
            add_edge(head1, i, j, c[i]);
        }
    }
    // for(int i=1;i<=n;i++){
    //     for(int j=1;j<=n;j++){
    //         if(i==j || dis[i][j]>t[i])continue;
    //         // edge[i].push_back(node(j,c[i]));
    //         add_edge(i, j, c[i]);
    //     }
    // }
    dij(x, head1);
    if(dis[y]<inf){
        printf("%I64d\n", dis[y]);
    }
    else puts("-1");
	return 0;
}


/*  ^^ ====== ^^
ID: meixiuxiu
PROG: test
LANG: C++11
*/
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <cctype>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int ,int> pii;
#define MEM(a,b) memset(a,b,sizeof a)
#define CLR(a) memset(a,0,sizeof a);
#define pi acos(-1.0)
#define maxn 40000
#define maxv 100005
const ll inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int x,y;
int n,m;
ll dis[1005];
bool vis[1005];
ll ans[1005];
int t[1005];
int c[1005];

const int maxm = 1e6+50;
int head[1005];
int nxt[2*maxm], pnt[2*maxm];
ll cost[2*maxm];
int head1[1005];

struct node
{
    int v;
    ll w;
    node(int v,ll w):v(v),w(w){}
    bool operator < (const node &r)const{
        return w > r.w;
    }
};
int cnt, cnt1;
std::vector<node> edge[1005];
void dij(int s, int *head){
    memset(dis, 0x3f, sizeof dis);
    dis[s] = 0;
    MEM(vis,0);
    priority_queue<node> q;q.push(node(s,0));
    while(!q.empty()){
        node x = q.top();q.pop();
        int u = x.v;;
        if (x.w > dis[u]) continue;
        // if(vis[u])continue;vis[u] = 1;
        for(int i = head[u]; ~i; i = nxt[i]){
            int v = pnt[i];
            ll w = cost[i];
            if(dis[v] > dis[u] + w){
                dis[v] = dis[u]+w;
                // if(!vis[v]){
                    q.push(node(v,dis[v]));
                // }
            }
        }
    }
}

void add_edge(int *head, int u, int v, ll c) {
    pnt[cnt] = v;
    nxt[cnt] = head[u];
    cost[cnt] = c;
    head[u] = cnt++;
}

int main()
{
#ifdef LOCAL
    freopen("C:\\\\Users\\\\zzblack\\\\Desktop\\\\case.in","r",stdin);
    freopen("C:\\\\Users\\\\zzblack\\\\Desktop\\\\case.out","w",stdout);
#endif
    memset(head, 0xff, sizeof head);
    memset(head1, 0xff, sizeof head1);
    cnt = 0; cnt1 = 0;
    scanf("%d%d%d%d", &n, &m, &x, &y);
    MEM(dis,inf);
    for(int i=1;i<=m;i++){
        int u,v, w;scanf("%d%d%d",&u,&v,&w);
        add_edge(head, u, v, w);
        add_edge(head, v, u, w);
    }
    // for(int i=1;i<=n;i++){
    //     for(int j=1;j<=n;j++){
    //         if(dis[i][j]!=inf){
    //             add_edge(i, j, dis[i][j]);
    //             // edge[i].push_back(node(j,dis[i][j]));
    //         }
    //     }
    // }
    for(int i=1;i<=n;i++){
        // // edge[i].clear();
        // head[i] = -1;
        scanf("%d%d",&t[i],&c[i]);
    }
    for(int i=1;i<=n;i++){
        dij(i, head);
        for (int j = 1; j <= n; j++) {
            if(j == i || dis[j] > t[i]) continue;
            add_edge(head1, i, j, c[i]);
        }
    }
    // for(int i=1;i<=n;i++){
    //     for(int j=1;j<=n;j++){
    //         if(i==j || dis[i][j]>t[i])continue;
    //         // edge[i].push_back(node(j,c[i]));
    //         add_edge(i, j, c[i]);
    //     }
    // }
    dij(x, head1);
    if(dis[y]<inf){
        printf("%I64d\n", dis[y]);
    }
    else puts("-1");
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int maxn=2010;
typedef long long ll;
ll n,m,s,T,u,v,ww,t,c;
bool tf[maxn];
struct node
{
	ll x,v;
	bool operator<(node x)const{return v>x.v;}
}x;
priority_queue<node>q;
vector<ll>g[maxn],w[maxn],G[maxn],W[maxn];
int main()
{
	scanf("%lld%lld",&n,&m);
	scanf("%lld%lld",&s,&T);
	for(int i=1;i<=m;i++)
	{
		scanf("%lld%lld%lld",&u,&v,&ww);
		g[u].push_back(v);
		g[v].push_back(u);
		w[u].push_back(ww);
		w[v].push_back(ww);
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%lld%lld",&t,&c);
		memset(tf,false,sizeof tf);
		while(!q.empty())q.pop();
		q.push({i,0});
		while(!q.empty())
		{
			x=q.top();q.pop();
			if(x.v>t)break;
			if(tf[x.x])continue;
			tf[x.x]=true;G[i].push_back(x.x);W[i].push_back(c);
			for(int j=0;j<g[x.x].size();j++)
			q.push({g[x.x][j],x.v+w[x.x][j]});
		}
	}
	memset(tf,false,sizeof tf);
	while(!q.empty())q.pop();
	q.push({s,0});
	while(!q.empty())
	{
		x=q.top();q.pop();
		if(x.x==T){printf("%lld\n",x.v);return 0;}
		if(tf[x.x])continue;
		tf[x.x]=true;
		for(int j=0;j<G[x.x].size();j++)
		q.push({G[x.x][j],x.v+W[x.x][j]});
	}
	printf("-1\n");
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int maxn=2010;
int n,m,s,T,u,v,ww,t,c;
bool tf[maxn];
struct node
{
	int x,v;
	bool operator<(node x)const{return v>x.v;}
}x;
priority_queue<node>q;
vector<int>g[maxn],w[maxn],G[maxn],W[maxn];
int main()
{
	scanf("%d%d",&n,&m);
	scanf("%d%d",&s,&T);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&u,&v,&ww);
		g[u].push_back(v);
		g[v].push_back(u);
		w[u].push_back(ww);
		w[v].push_back(ww);
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&t,&c);
		memset(tf,false,sizeof tf);
		while(!q.empty())q.pop();
		q.push({i,0});
		while(!q.empty())
		{
			x=q.top();q.pop();
			if(x.v>t)break;
			if(tf[x.x])continue;
			tf[x.x]=true;G[i].push_back(x.x);W[i].push_back(c);
			for(int j=0;j<g[x.x].size();j++)
			q.push({g[x.x][j],x.v+w[x.x][j]});
		}
	}
	memset(tf,false,sizeof tf);
	while(!q.empty())q.pop();
	q.push({s,0});
	while(!q.empty())
	{
		x=q.top();q.pop();
		if(x.x==T){printf("%d\n",x.v);return 0;}
		if(tf[x.x])continue;
		tf[x.x]=true;
		for(int j=0;j<G[x.x].size();j++)
		q.push({G[x.x][j],x.v+W[x.x][j]});
	}
	printf("-1\n");
	return 0;
}


//I Guds namn
#include <bits/stdc++.h>

using namespace std;

#define guk cout << "Guk" << endl;
#define in insert
#define mk make_pair
#define pb push_back

const int MAXN = 1e3 + 11;

int n, td[MAXN], tc[MAXN];

long long dist[MAXN];

vector<int> adj[MAXN], wei[MAXN], adjp[MAXN], weip[MAXN];

void dj(int u)
{
	set<pair<long long, int> > s;
	for(int i = 1;i <= n;i++)
		if(i != u)
		{
			dist[i] = 1e18;
			s.in(mk(dist[i], i));
		}
	dist[u] = 0;
	s.in(mk(0, u));
	for(int i = 0;i < n;i++)
	{
		int v = (*s.begin()).second;
		s.erase(s.begin());
		for(int j = 0;j < adj[v].size();j++)
		{
			int w =wei[v][j];
			int t = adj[v][j];
			if(dist[t] > dist[v] + w)
			{
				s.erase(s.find(mk(dist[t], t)));
				dist[t] = dist[v] + w;
				s.in(mk(dist[t], t));
			}
		}
	}
	for(int i = 1;i <= n;i++)
	{
		if(i != u and dist[i] <= td[u])
		{
			adjp[u].pb(i);
			weip[u].pb(tc[u]);
		}
	}
	return;
}

void djp(int u)
{
	set<pair<long long, int> > s;
	for(int i = 1;i <= n;i++)
		if(i != u)
		{
			dist[i] = 1e18;
			s.in(mk(dist[i], i));
		}
	dist[u] = 0;
	s.in(mk(0, u));
	for(int i = 0;i < n;i++)
	{
		int v = (*s.begin()).second;
		s.erase(s.begin());
		for(int j = 0;j < adjp[v].size();j++)
		{
			int w =weip[v][j];
			int t = adjp[v][j];
			if(dist[t] > dist[v] + w)
			{
				s.erase(s.find(mk(dist[t], t)));
				dist[t] = dist[v] + w;
				s.in(mk(dist[t], t));
			}
		}
	}
	return;
}

int main()
{
	int m, x, y;
	cin >> n >> m >> x >> y;
	for(int i = 0;i < m;i++)
	{
		int u, v, w;
		cin >> u >> v >> w;
		adj[u].pb(v);
		adj[v].pb(u);
		wei[u].pb(w);
		wei[v].pb(w);
	}
	for(int i = 0;i < n;i++)
	{
		cin >> td[i + 1] >> tc[i + 1];
	}
	for(int i = 1;i <= n;i++)
		dj(i);
	djp(x);
	if(dist[y] == 1e18)
	{
		cout << -1 << endl;
		return 0;
	}
	cout << dist[y] << endl;
	return 0;
}


//I Guds namn
#include <bits/stdc++.h>

using namespace std;

#define guk cout << "Guk" << endl;
#define in insert
#define mk make_pair
#define pb push_back

const int MAXN = 1e3 + 11;

int n, td[MAXN], tc[MAXN];

long long dist[MAXN];

vector<int> adj[MAXN], wei[MAXN], adjp[MAXN], weip[MAXN];

void dj(int u)
{
	set<pair<long long, int> > s;
	for(int i = 1;i <= n;i++)
		if(i != u)
		{
			dist[i] = 1e18;
			s.in(mk(dist[i], i));
		}
	dist[u] = 0;
	s.in(mk(0, u));
	for(int i = 0;i < n;i++)
	{
		int v = (*s.begin()).second;
		s.erase(s.begin());
		for(int j = 0;j < adj[v].size();j++)
		{
			int w =wei[v][j];
			int t = adj[v][j];
			if(dist[t] > dist[v] + w)
			{
				s.erase(s.find(mk(dist[t], t)));
				dist[t] = dist[v] + w;
				s.in(mk(dist[t], t));
			}
		}
	}
	for(int i = 1;i <= n;i++)
	{
		if(i != u and dist[i] <= td[u])
		{
			adjp[u].pb(i);
			weip[u].pb(tc[u]);
		}
	}
	return;
}

void djp(int u)
{
	set<pair<long long, int> > s;
	for(int i = 1;i <= n;i++)
		if(i != u)
		{
			dist[i] = 1e18;
			s.in(mk(dist[i], i));
		}
	dist[u] = 0;
	s.in(mk(0, u));
	for(int i = 0;i < n;i++)
	{
		int v = (*s.begin()).second;
		s.erase(s.begin());
		for(int j = 0;j < adjp[v].size();j++)
		{
			int w =weip[v][j];
			int t = adjp[v][j];
			if(dist[t] > dist[v] + w)
			{
				s.erase(s.find(mk(dist[t], t)));
				dist[t] = dist[v] + w;
				s.in(mk(dist[t], t));
			}
		}
	}
	return;
}

int main()
{
	int m, x, y;
	cin >> n >> m >> x >> y;
	for(int i = 0;i < m;i++)
	{
		int u, v, w;
		cin >> u >> v >> w;
		adj[u].pb(v);
		adj[v].pb(u);
		wei[u].pb(w);
		wei[v].pb(w);
	}
	for(int i = 0;i < n;i++)
	{
		cin >> td[i + 1] >> tc[i + 1];
	}
	for(int i = 1;i <= n;i++)
		dj(i);
	djp(x);
	if(dist[u] = 1e18)
	{
		cout << -1 << endl;
		return 0;
	}
	cout << dist[y] << endl;
	return 0;
}


//I Guds namn
#include <bits/stdc++.h>

using namespace std;

#define Guk cout << "Guk" << endl;

#define pb push_back

const int MAX = 1e3 + 11;

bool mark[MAX];

int tdis[MAX], tcos[MAX], n;

long long dist[MAX];

vector<int> adj[MAX], wei[MAX], adjp[MAX], weip[MAX];

void relax(int u)
{
	for(int i = 0;i < adj[u].size();i++)
	{
		int v = adj[u][i];
		if(dist[v] > dist[u] + wei[u][i])
			dist[v] = dist[u] + wei[u][i];
	}
}

void dj(int u)
{
	for(int i = 1;i <= n;i++)
		dist[i] = 1e18;
	dist[u] = 0;
	int cur = -1;
	for(int i = 1;i <= n;i++)
	{
		int cur = -1;
		for(int j = 1;j <= n;j++)
			if(!mark[j] and (cur == -1 or dist[cur] > dist[j]))
				cur = j;
		if(dist[cur] <= tdis[u] and cur != u)
		{
			adjp[u].pb(cur);
			weip[u].pb(tcos[u]);
		}
		mark[cur] = true;
		relax(cur);
	}

}

void relaxp(int u)
{
	for(int i = 0;i < adjp[u].size();i++)
	{
		int v = adjp[u][i];
		if(dist[v] > dist[u] + weip[u][i])
			dist[v] = dist[u] + weip[u][i];
	}
}

void djp(int u)
{
	for(int i = 1;i <= n;i++)
		dist[i] = 1e18;
	dist[u] = 0;
	int cur = -1;
	for(int i = 1;i <= n;i++)
	{
		int cur = -1;
		for(int j = 1;j <= n;j++)
			if(!mark[j] and (cur == -1 or dist[cur] > dist[j]))
				cur = j;
		mark[cur] = true;
		relaxp(cur);
	}

}

int main()
{
	int m, x, y;
	cin >> n >> m >> x >> y;
	for(int i = 0;i < m;i++)
	{
		int u, v, w;
		cin >> u >> v >> w;
		adj[u].pb(v);
		adj[v].pb(u);
		wei[u].pb(w);
		wei[v].pb(w);
	}
	for(int i = 1;i <= n;i++)
		cin >> tdis[i] >> tcos[i];
	for(int i = 1;i <= n;i++)
	{
		dj(i);
		memset(mark, 0, sizeof mark);
	}
	djp(x);
	if(dist[y] == 1e18)
	{
		cout << -1 << endl;
		return 0;
	}
	cout << dist[y] << endl;
	return 0;
}


//I Guds namn
#include <bits/stdc++.h>

using namespace std;

#define Guk cout << "Guk" << endl;

#define pb push_back

const int MAX = 1e3 + 11;

bool mark[MAX];

int tdis[MAX], tcos[MAX], n;

long long dist[MAX];

vector<int> adj[MAX], wei[MAX], adjp[MAX], weip[MAX];

void relax(int u)
{
	for(int i = 0;i < adj[u].size();i++)
	{
		int v = adj[u][i];
		if(dist[v] > dist[u] + wei[u][i])
			dist[v] = dist[u] + wei[u][i];
	}
}

void dj(int u)
{
	for(int i = 1;i <= n;i++)
		dist[i] = 1e18;
	dist[u] = 0;
	int cur = -1;
	for(int i = 1;i <= n;i++)
	{
		int cur = -1;
		for(int j = 1;j <= n;j++)
			if(!mark[j] and (cur == -1 or dist[cur] > dist[j]))
				cur = j;
		if(dist[cur] <= tdis[u] and cur != u)
		{
			adjp[u].pb(cur);
			weip[u].pb(tcos[u]);
		}
		mark[cur] = true;
		relax(cur);
	}

}

void relaxp(int u)
{
	for(int i = 0;i < adjp[u].size();i++)
	{
		int v = adjp[u][i];
		if(dist[v] > dist[u] + weip[u][i])
			dist[v] = dist[u] + weip[u][i];
	}
}

void djp(int u)
{
	for(int i = 1;i <= n;i++)
		dist[i] = 1e18;
	dist[u] = 0;
	int cur = -1;
	for(int i = 1;i <= n;i++)
	{
		int cur = -1;
		for(int j = 1;j <= n;j++)
			if(!mark[j] and (cur == -1 or dist[cur] > dist[j]))
				cur = j;
		mark[cur] = true;
		relaxp(cur);
	}

}

int main()
{
	int m, x, y;
	cin >> n >> m >> x >> y;
	for(int i = 0;i < m;i++)
	{
		int u, v, w;
		cin >> u >> v >> w;
		adj[u].pb(v);
		adj[v].pb(u);
		wei[u].pb(w);
		wei[v].pb(w);
	}
	for(int i = 1;i <= n;i++)
		cin >> tdis[i] >> tcos[i];
	for(int i = 1;i <= n;i++)
	{
		dj(i);
		memset(mark, 0, sizeof mark);
	}
	djp(x);
	cout << dist[y] << endl;
	return 0;
}


//I Guds namn
#include <bits/stdc++.h>

using namespace std;

#define guk cout << "Guk" << endl;
#define in insert
#define mk make_pair
#define pb push_back

const int MAXN = 1e3 + 11;

int n, td[MAXN], tc[MAXN];

long long dist[MAXN];

vector<int> adj[MAXN], wei[MAXN], adjp[MAXN], weip[MAXN];

void dj(int u)
{
	set<pair<long long, int> > s;
	for(int i = 1;i <= n;i++)
		if(i != u)
		{
			dist[i] = 1e18;
			s.in(mk(dist[i], i));
		}
	dist[u] = 0;
	s.in(mk(0, u));
	for(int i = 0;i < n;i++)
	{
		int v = (*s.begin()).second;
		s.erase(s.begin());
		for(int j = 0;j < adj[v].size();j++)
		{
			int w =wei[v][j];
			int t = adj[v][j];
			if(dist[t] > dist[v] + w)
			{
				s.erase(s.find(mk(dist[t], t)));
				dist[t] = dist[v] + w;
				s.in(mk(dist[t], t));
			}
		}
	}
	for(int i = 1;i <= n;i++)
	{
		if(i != u and dist[i] <= td[u])
		{
			adjp[u].pb(i);
			weip[u].pb(tc[u]);
		}
	}
	return;
}

void djp(int u)
{
	set<pair<long long, int> > s;
	for(int i = 1;i <= n;i++)
		if(i != u)
		{
			dist[i] = 1e18;
			s.in(mk(dist[i], i));
		}
	dist[u] = 0;
	s.in(mk(0, u));
	for(int i = 0;i < n;i++)
	{
		int v = (*s.begin()).second;
		s.erase(s.begin());
		for(int j = 0;j < adjp[v].size();j++)
		{
			int w =weip[v][j];
			int t = adjp[v][j];
			if(dist[t] > dist[v] + w)
			{
				s.erase(s.find(mk(dist[t], t)));
				dist[t] = dist[v] + w;
				s.in(mk(dist[t], t));
			}
		}
	}
	return;
}

int main()
{
	int m, x, y;
	cin >> n >> m >> x >> y;
	for(int i = 0;i < m;i++)
	{
		int u, v, w;
		cin >> u >> v >> w;
		adj[u].pb(v);
		adj[v].pb(u);
		wei[u].pb(w);
		wei[v].pb(w);
	}
	for(int i = 0;i < n;i++)
	{
		cin >> td[i + 1] >> tc[i + 1];
	}
	for(int i = 1;i <= n;i++)
		dj(i);
	djp(x);
	cout << dist[y] << endl;
	return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <string>
#include <iostream>
#include <list>
#define lowbit(x) (x&(-x))
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = int(1010);
int head1[maxn], head2[maxn], tot1 = 0, tot2 = 0;
long long dis2[maxn];
struct node
{
	int next, to;
	long long w;
	bool operator < (const node& cmp)const
	{
		return w > cmp.w;
	}
} edge1[maxn << 1], edge2[maxn];

struct dd
{
	int u, v, t, c;
} driver[maxn];

inline void addedge1(int u, int v, int w)
{
	edge1[tot1].w = w;
	edge1[tot1].to = v;
	edge1[tot1].next = head1[u];
	head1[u] = tot1++;
}
inline void addedge2(int u, int v, int w)
{
	edge2[tot2].w = w;
	edge2[tot2].to = v;
	edge2[tot2].next = head2[u];
	head2[u] = tot2++;
}

long long dji1(int s,int t)
{
	const long long inff = 0x3f3f3f3f3f3f3f3f;
	bool vis[maxn];
	node temp;
	priority_queue<node> q;
	memset(dis2, 0x3f, sizeof dis2);
	memset(vis, 0, sizeof vis);
	vis[s] = true;
	dis2[s] = 0;
	for (int i = head2[s]; ~i; i = edge2[i].next)
	{
		int v = edge2[i].to;
		dis2[v] = min(dis2[v], edge2[i].w);
		q.push(edge2[i]);
	}
	while (!q.empty())
	{
		temp = q.top();
		q.pop();
		if (vis[temp.to])continue;
		vis[temp.to] = true;
		for (int i = head2[temp.to]; ~i; i = edge2[i].next)
		{
			int v = edge2[i].to;
			if (!vis[v] && dis2[v] > dis2[temp.to] + edge2[i].w)
			{
				dis2[v] = dis2[temp.to] + edge2[i].w;
				q.push({ 0,v,dis2[v] });
			}
		}
	}
	return dis2[t] == inff ? -1 : dis2[t];
}

int visdis[maxn][maxn];
queue<dd> que;
void bfs(int s)
{

	memset(visdis, 0x3f, sizeof visdis);
	dd temp, k;
	while (!que.empty())
	{
		k = que.front();
		que.pop();
		for (int i = head1[k.v]; ~i; i = edge1[i].next)
		{
			temp = k;
			if (temp.t < edge1[i].w)continue;
			if (visdis[temp.u][edge1[i].to] <= temp.c)continue;
			if (temp.u == edge1[i].to) continue;
			visdis[temp.u][edge1[i].to] = temp.c;
			temp.t -= edge1[i].w;
			temp.v = edge1[i].to;
			addedge2(temp.u, edge1[i].to, temp.c);
			if (temp.t)que.push(temp);
		}
	}
}

int main()
{
	int n, m, s, t, u, v, w;
	scanf("%d%d", &n, &m);
	scanf("%d%d", &s, &t);
	memset(head1, -1, sizeof head1);
	memset(head2, -1, sizeof head2);
	for (int i = 0; i < m; ++i)
	{
		scanf("%d%d%d", &u, &v, &w);
		addedge1(u, v, w);
		addedge1(v, u, w);
	}
	for (int i = 1; i <= n; ++i)
	{
		scanf("%d%d", &u, &v);
		que.push({ i,i,u,v });
	}
	bfs(s);
	printf("%I64d\n", dji1(s, t));
//	system("pause");
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <string>
#include <iostream>
#include <list>
#define lowbit(x) (x&(-x))
#define inf 0x3f3f3f3f3f3f3f3fLL
using namespace std;
const int maxn = int(1010);
int head[maxn], tot = 0;
long long mp[maxn][maxn];
struct node
{
	int next, to;
	long long w;
	bool operator < (const node& cmp)const
	{
		return w > cmp.w;
	}
} edge[maxn << 1];

inline void addedge(int u, int v, int w)
{
	edge[tot].w = w;
	edge[tot].to = v;
	edge[tot].next = head[u];
	head[u] = tot++;
}
void djik(int s,long long *dis)
{
	bool vis[maxn];
	node k, temp;
	memset(vis, 0, sizeof vis);
	vis[s] = true;
	dis[s] = 0;
	priority_queue<node> que;
	for (int i = head[s]; ~i; i = edge[i].next)
	{
		int v = edge[i].to;
		dis[v] = min(dis[v], edge[i].w);
		que.push(edge[i]);
	}
	while (!que.empty())
	{
		k = que.top();
		que.pop();
		if (vis[k.to])continue;
		vis[k.to] = true;
		for (int i = head[k.to]; ~i; i = edge[i].next)
		{
			int v = edge[i].to;
			if (!vis[v] && dis[v] > dis[k.to] + edge[i].w)
			{
				dis[v] = dis[k.to] + edge[i].w;
				que.push({ 0,v,dis[v] });
			}
		}
	}
}

int main()
{
	int n, m, s, t, u, v, w, tt, cc;
	scanf("%d%d", &n, &m);
	scanf("%d%d", &s, &t);
	memset(head, -1, sizeof head);
	memset(mp, 0x3f, sizeof mp);
	for (int i = 0; i < m; ++i)
	{
		scanf("%d%d%d", &u, &v, &w);
		addedge(u, v, w);
		addedge(v, u, w);
	}
	for (int i = 1; i <= n; ++i)
		djik(i, mp[i]);
	memset(head, -1, sizeof head);
	memset(edge, 0, sizeof edge);
	tot = 0;
	for (int i = 1; i <= n; ++i)
	{
		scanf("%d%d", &tt, &cc);
		for (int j = 1; j <= n; ++j)
			if (mp[i][j] <= tt && i != j)addedge(i, j, cc);
	}
	memset(mp[s], 0x3f, sizeof mp[s]);
	djik(s, mp[s]);
	printf("%I64d\n", mp[s][t] == inf ? -1 : mp[s][t]);
//	system("pause");
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <string>
#include <iostream>
#include <list>
#define lowbit(x) (x&(-x))
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = int(1010);
int head1[maxn], head2[maxn], tot1 = 0, tot2 = 0;
long long dis2[maxn];
struct node
{
	int next, to;
	long long w;
	bool operator < (const node& cmp)const
	{
		return w > cmp.w;
	}
} edge1[maxn << 1], edge2[maxn];

struct dd
{
	int u, v, t, c;
} driver[maxn];

inline void addedge1(int u, int v, int w)
{
	edge1[tot1].w = w;
	edge1[tot1].to = v;
	edge1[tot1].next = head1[u];
	head1[u] = tot1++;
}
inline void addedge2(int u, int v, int w)
{
	edge2[tot2].w = w;
	edge2[tot2].to = v;
	edge2[tot2].next = head2[u];
	head2[u] = tot2++;
}

long long dji1(int s,int t)
{
	const long long inff = 0x3f3f3f3f3f3f3f3f;
	bool vis[maxn];
	node temp;
	priority_queue<node> q;
	memset(dis2, 0x3f, sizeof dis2);
	memset(vis, 0, sizeof vis);
	vis[s] = true;
	dis2[s] = 0;
	for (int i = head2[s]; ~i; i = edge2[i].next)
	{
		int v = edge2[i].to;
		dis2[v] = min(dis2[v], edge2[i].w);
		q.push(edge2[i]);
	}
	while (!q.empty())
	{
		temp = q.top();
		q.pop();
		if (vis[temp.to])continue;
		vis[temp.to] = true;
		for (int i = head2[temp.to]; ~i; i = edge2[i].next)
		{
			int v = edge2[i].to;
			if (!vis[v] && dis2[v] > dis2[temp.to] + edge2[i].w)
			{
				dis2[v] = dis2[temp.to] + edge2[i].w;
				q.push(edge2[i]);
			}
		}
	}
	return dis2[t] == inff ? -1 : dis2[t];
}

int visdis[maxn][maxn];
queue<dd> que;
void bfs(int s)
{

	memset(visdis, 0x3f, sizeof visdis);
	dd temp, k;
	while (!que.empty())
	{
		k = que.front();
		que.pop();
		for (int i = head1[k.v]; ~i; i = edge1[i].next)
		{
			temp = k;
			if (temp.t < edge1[i].w)continue;
			if (visdis[temp.u][edge1[i].to] <= temp.c)continue;
			if (temp.u == edge1[i].to) continue;
			visdis[temp.u][edge1[i].to] = temp.c;
			temp.t -= edge1[i].w;
			temp.v = edge1[i].to;
			addedge2(temp.u, edge1[i].to, temp.c);
			if (temp.t)que.push(temp);
		}
	}
}

int main()
{
	int n, m, s, t, u, v, w;
	scanf("%d%d", &n, &m);
	scanf("%d%d", &s, &t);
	memset(head1, -1, sizeof head1);
	memset(head2, -1, sizeof head2);
	for (int i = 0; i < m; ++i)
	{
		scanf("%d%d%d", &u, &v, &w);
		addedge1(u, v, w);
		addedge1(v, u, w);
	}
	for (int i = 1; i <= n; ++i)
	{
		scanf("%d%d", &u, &v);
		que.push({ i,i,u,v });
	}
	bfs(s);
	printf("%I64d\n", dji1(s, t));
//	system("pause");
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <string>
#include <iostream>
#include <list>
#define lowbit(x) (x&(-x))
#define inf 0x3f3f3f3f3f3f3f3fLL
using namespace std;
const int maxn = int(1e6 + 10);
int head[1010], tot = 0;
long long mp[1010][1010];
struct node
{
	int next, to;
	long long w;
	bool operator < (const node& cmp)const
	{
		return w > cmp.w;
	}
} edge[maxn];

inline void addedge(int u, int v, int w)
{
	edge[tot].w = w;
	edge[tot].to = v;
	edge[tot].next = head[u];
	head[u] = tot++;
}
void djik(int s,long long *dis)
{
	bool vis[maxn];
	node k, temp;
	memset(vis, 0, sizeof vis);
	vis[s] = true;
	dis[s] = 0;
	priority_queue<node> que;
	for (int i = head[s]; ~i; i = edge[i].next)
	{
		int v = edge[i].to;
		dis[v] = min(dis[v], edge[i].w);
		que.push(edge[i]);
	}
	while (!que.empty())
	{
		k = que.top();
		que.pop();
		if (vis[k.to])continue;
		vis[k.to] = true;
		for (int i = head[k.to]; ~i; i = edge[i].next)
		{
			int v = edge[i].to;
			if (!vis[v] && dis[v] > dis[k.to] + edge[i].w)
			{
				dis[v] = dis[k.to] + edge[i].w;
				que.push({ 0,v,dis[v] });
			}
		}
	}
}

int main()
{
	int n, m, s, t, u, v, w, tt, cc;
	scanf("%d%d", &n, &m);
	scanf("%d%d", &s, &t);
	memset(head, -1, sizeof head);
	memset(mp, 0x3f, sizeof mp);
	for (int i = 0; i < m; ++i)
	{
		scanf("%d%d%d", &u, &v, &w);
		addedge(u, v, w);
		addedge(v, u, w);
	}
	for (int i = 1; i <= n; ++i)
		djik(i, mp[i]);
	memset(head, -1, sizeof head);
	memset(edge, 0, sizeof edge);
	tot = 0;
	for (int i = 1; i <= n; ++i)
	{
		scanf("%d%d", &tt, &cc);
		for (int j = 1; j <= n; ++j)
			if (mp[i][j] <= tt && i != j)addedge(i, j, cc);
	}
	memset(mp[s], 0x3f, sizeof mp[s]);
	djik(s, mp[s]);
	printf("%I64d\n", mp[s][t] == inf ? -1 : mp[s][t]);
//	system("pause");
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <string>
#include <iostream>
#include <list>
#define lowbit(x) (x&(-x))
#define inf 0x3f3f3f3f3f3f3f3fLL
using namespace std;
const int maxn = int(1500);
int head[maxn], tot = 0;
long long mp[maxn][maxn];
struct node
{
	int next, to;
	long long w;
	bool operator < (const node& cmp)const
	{
		return w > cmp.w;
	}
} edge[maxn << 1];

inline void addedge(int u, int v, int w)
{
	edge[tot].w = w;
	edge[tot].to = v;
	edge[tot].next = head[u];
	head[u] = tot++;
}
void djik(int s,long long *dis)
{
	bool vis[maxn];
	node k, temp;
	memset(vis, 0, sizeof vis);
	vis[s] = true;
	dis[s] = 0;
	priority_queue<node> que;
	for (int i = head[s]; ~i; i = edge[i].next)
	{
		int v = edge[i].to;
		dis[v] = min(dis[v], edge[i].w);
		que.push(edge[i]);
	}
	while (!que.empty())
	{
		k = que.top();
		que.pop();
		if (vis[k.to])continue;
		vis[k.to] = true;
		for (int i = head[k.to]; ~i; i = edge[i].next)
		{
			int v = edge[i].to;
			if (!vis[v] && dis[v] > dis[k.to] + edge[i].w)
			{
				dis[v] = dis[k.to] + edge[i].w;
				que.push({ 0,v,dis[v] });
			}
		}
	}
}

int main()
{
	int n, m, s, t, u, v, w, tt, cc;
	scanf("%d%d", &n, &m);
	scanf("%d%d", &s, &t);
	memset(head, -1, sizeof head);
	memset(mp, 0x3f, sizeof mp);
	for (int i = 0; i < m; ++i)
	{
		scanf("%d%d%d", &u, &v, &w);
		addedge(u, v, w);
		addedge(v, u, w);
	}
	for (int i = 1; i <= n; ++i)
		djik(i, mp[i]);
	memset(head, -1, sizeof head);
	memset(edge, 0, sizeof edge);
	tot = 0;
	for (int i = 1; i <= n; ++i)
	{
		scanf("%d%d", &tt, &cc);
		for (int j = 1; j <= n; ++j)
			if (mp[i][j] <= tt && i != j)addedge(i, j, cc);
	}
	memset(mp[s], 0x3f, sizeof mp[s]);
	djik(s, mp[s]);
	printf("%I64d\n", mp[s][t] == inf ? -1 : mp[s][t]);
//	system("pause");
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <string>
#include <iostream>
#include <list>
#define lowbit(x) (x&(-x))
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = int(1010);
int head1[maxn], head2[maxn], tot1 = 0, tot2 = 0;
long long dis2[maxn];
struct node
{
	int next, to;
	long long w;
	bool operator < (const node& cmp)const
	{
		return w > cmp.w;
	}
} edge1[maxn << 1], edge2[maxn];

struct dd
{
	int u, v, t, c, pre;
} driver[maxn];

inline void addedge1(int u, int v, int w)
{
	edge1[tot1].w = w;
	edge1[tot1].to = v;
	edge1[tot1].next = head1[u];
	head1[u] = tot1++;
}
inline void addedge2(int u, int v, int w)
{
	edge2[tot2].w = w;
	edge2[tot2].to = v;
	edge2[tot2].next = head2[u];
	head2[u] = tot2++;
}

long long dji1(int s,int t)
{
	bool vis[maxn];
	node temp;
	priority_queue<node> q;
	memset(dis2, 0x3f, sizeof dis2);
	memset(vis, 0, sizeof vis);
	vis[s] = true;
	dis2[s] = 0;
	for (int i = head2[s]; ~i; i = edge2[i].next)
	{
		int v = edge2[i].to;
		dis2[v] = min(dis2[v], edge2[i].w);
		q.push(edge2[i]);
	}
	while (!q.empty())
	{
		temp = q.top();
		q.pop();
		if (vis[temp.to])continue;
		vis[temp.to] = true;
		for (int i = head2[temp.to]; ~i; i = edge2[i].next)
		{
			int v = edge2[i].to;
			if (!vis[v] && dis2[v] > dis2[temp.to] + edge2[i].w)
			{
				dis2[v] = dis2[temp.to] + edge2[i].w;
				q.push(edge2[i]);
			}
		}
	}
	return dis2[t];
}

int visdis[maxn][maxn];
queue<dd> que;
void bfs(int s)
{

	memset(visdis, 0x3f, sizeof visdis);
	dd temp, k;
	while (!que.empty())
	{
		k = que.front();
		que.pop();
		for (int i = head1[k.v]; ~i; i = edge1[i].next)
		{
			temp = k;
			if (temp.t < edge1[i].w || visdis[temp.u][edge1[i].to] <= temp.c) continue;
			visdis[temp.u][edge1[i].to] = temp.c;
			temp.t -= edge1[i].w;
			temp.v = edge1[i].to;
			addedge2(temp.u, edge1[i].to, temp.c);
			if (temp.t)que.push(temp);
		}
	}
}

int main()
{
	int n, m, s, t, u, v, w;
	scanf("%d%d", &n, &m);
	scanf("%d%d", &s, &t);
	memset(head1, -1, sizeof head1);
	memset(head2, -1, sizeof head2);
	for (int i = 0; i < m; ++i)
	{
		scanf("%d%d%d", &u, &v, &w);
		addedge1(u, v, w);
		addedge1(v, u, w);
	}
	for (int i = 1; i <= n; ++i)
	{
		scanf("%d%d", &u, &v);
		que.push({ i,i,u,v,i });
	}
	bfs(s);
	printf("%I64d\n", dji1(s, t));
//	system("pause");
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <string>
#include <iostream>
#include <list>
#define lowbit(x) (x&(-x))
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = int(1010);
int head1[maxn], head2[maxn], tot1 = 0, tot2 = 0;
long long dis2[maxn];
struct node
{
	int next, to;
	long long w;
	bool operator < (const node& cmp)const
	{
		return w > cmp.w;
	}
} edge1[maxn << 1], edge2[maxn];

struct dd
{
	int u, v, t, c, pre;
} driver[maxn];

inline void addedge1(int u, int v, int w)
{
	edge1[tot1].w = w;
	edge1[tot1].to = v;
	edge1[tot1].next = head1[u];
	head1[u] = tot1++;
}
inline void addedge2(int u, int v, int w)
{
	edge2[tot2].w = w;
	edge2[tot2].to = v;
	edge2[tot2].next = head2[u];
	head2[u] = tot2++;
}

long long dji1(int s,int t)
{
	const long long inff = 0x3f3f3f3f3f3f3f3f;
	bool vis[maxn];
	node temp;
	priority_queue<node> q;
	memset(dis2, 0x3f, sizeof dis2);
	memset(vis, 0, sizeof vis);
	vis[s] = true;
	dis2[s] = 0;
	for (int i = head2[s]; ~i; i = edge2[i].next)
	{
		int v = edge2[i].to;
		dis2[v] = min(dis2[v], edge2[i].w);
		q.push(edge2[i]);
	}
	while (!q.empty())
	{
		temp = q.top();
		q.pop();
		if (vis[temp.to])continue;
		vis[temp.to] = true;
		for (int i = head2[temp.to]; ~i; i = edge2[i].next)
		{
			int v = edge2[i].to;
			if (!vis[v] && dis2[v] > dis2[temp.to] + edge2[i].w)
			{
				dis2[v] = dis2[temp.to] + edge2[i].w;
				q.push(edge2[i]);
			}
		}
	}
	return dis2[t] == inff ? -1 : dis2[t];
}

int visdis[maxn][maxn];
queue<dd> que;
void bfs(int s)
{

	memset(visdis, 0x3f, sizeof visdis);
	dd temp, k;
	while (!que.empty())
	{
		k = que.front();
		que.pop();
		for (int i = head1[k.v]; ~i; i = edge1[i].next)
		{
			temp = k;
			if (temp.t < edge1[i].w || visdis[temp.u][edge1[i].to] <= temp.c) continue;
			visdis[temp.u][edge1[i].to] = temp.c;
			temp.t -= edge1[i].w;
			temp.v = edge1[i].to;
			addedge2(temp.u, edge1[i].to, temp.c);
			if (temp.t)que.push(temp);
		}
	}
}

int main()
{
	int n, m, s, t, u, v, w;
	scanf("%d%d", &n, &m);
	scanf("%d%d", &s, &t);
	memset(head1, -1, sizeof head1);
	memset(head2, -1, sizeof head2);
	for (int i = 0; i < m; ++i)
	{
		scanf("%d%d%d", &u, &v, &w);
		addedge1(u, v, w);
		addedge1(v, u, w);
	}
	for (int i = 1; i <= n; ++i)
	{
		scanf("%d%d", &u, &v);
		que.push({ i,i,u,v,i });
	}
	bfs(s);
	printf("%I64d\n", dji1(s, t));
//	system("pause");
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <string>
#include <iostream>
#include <list>
#define lowbit(x) (x&(-x))
#define inf 0x3f3f3f3f3f3f3f3fLL
using namespace std;
const int maxn = int(10);
int head[maxn], tot = 0;
long long mp[maxn][maxn];
struct node
{
	int next, to;
	long long w;
	bool operator < (const node& cmp)const
	{
		return w > cmp.w;
	}
} edge[maxn << 1];

inline void addedge(int u, int v, int w)
{
	edge[tot].w = w;
	edge[tot].to = v;
	edge[tot].next = head[u];
	head[u] = tot++;
}
void djik(int s,long long *dis)
{
	bool vis[maxn];
	node k, temp;
	memset(vis, 0, sizeof vis);
	vis[s] = true;
	dis[s] = 0;
	priority_queue<node> que;
	for (int i = head[s]; ~i; i = edge[i].next)
	{
		int v = edge[i].to;
		dis[v] = min(dis[v], edge[i].w);
		que.push(edge[i]);
	}
	while (!que.empty())
	{
		k = que.top();
		que.pop();
		if (vis[k.to])continue;
		vis[k.to] = true;
		for (int i = head[k.to]; ~i; i = edge[i].next)
		{
			int v = edge[i].to;
			if (!vis[v] && dis[v] > dis[k.to] + edge[i].w)
			{
				dis[v] = dis[k.to] + edge[i].w;
				que.push({ 0,v,dis[v] });
			}
		}
	}
}

int main()
{
	int n, m, s, t, u, v, w, tt, cc;
	scanf("%d%d", &n, &m);
	scanf("%d%d", &s, &t);
	memset(head, -1, sizeof head);
	memset(mp, 0x3f, sizeof mp);
	for (int i = 0; i < m; ++i)
	{
		scanf("%d%d%d", &u, &v, &w);
		addedge(u, v, w);
		addedge(v, u, w);
	}
	for (int i = 1; i <= n; ++i)
		djik(i, mp[i]);
	memset(head, -1, sizeof head);
	memset(edge, 0, sizeof edge);
	tot = 0;
	for (int i = 1; i <= n; ++i)
	{
		scanf("%d%d", &tt, &cc);
		for (int j = 1; j <= n; ++j)
			if (mp[i][j] <= tt && i != j)addedge(i, j, cc);
	}
	memset(mp[s], 0x3f, sizeof mp[s]);
	djik(s, mp[s]);
	printf("%I64d\n", mp[s][t] == inf ? -1 : mp[s][t]);
//	system("pause");
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <string>
#include <iostream>
#include <list>
#define lowbit(x) (x&(-x))
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = int(1010);
int head1[maxn], head2[maxn], tot1 = 0, tot2 = 0;
int dis1[maxn], dis2[maxn];
struct node
{
	int next, to, w;
	bool operator < (const node& cmp)const
	{
		return w > cmp.w;
	}
} edge1[maxn << 1], edge2[maxn];

struct dd
{
	int u, v, t, c, pre;
} driver[maxn];

inline void addedge1(int u, int v, int w)
{
	edge1[tot1].w = w;
	edge1[tot1].to = v;
	edge1[tot1].next = head1[u];
	head1[u] = tot1++;
}
inline void addedge2(int u, int v, int w)
{
	edge2[tot2].w = w;
	edge2[tot2].to = v;
	edge2[tot2].next = head2[u];
	head2[u] = tot2++;
}

int dji1(int s,int t)
{
	bool vis[maxn];
	node temp;
	priority_queue<node> q;
	memset(dis2, 0x3f, sizeof dis2);
	memset(vis, 0, sizeof vis);
	vis[s] = true;
	dis2[s] = 0;
	for (int i = head2[s]; ~i; i = edge2[i].next)
	{
		int v = edge2[i].to;
		dis2[v] = min(dis2[v], edge2[i].w);
		q.push(edge2[i]);
	}
	while (!q.empty())
	{
		temp = q.top();
		q.pop();
		if (vis[temp.to])continue;
		vis[temp.to] = true;
		for (int i = head2[temp.to]; ~i; i = edge2[i].next)
		{
			int v = edge2[i].to;
			if (!vis[v] && dis2[v] > dis2[temp.to] + edge2[i].w)
			{
				dis2[v] = dis2[temp.to] + edge2[i].w;
				q.push(edge2[i]);
			}
		}
	}
	return dis2[t];
}

queue<dd> que;
void bfs(int s)
{
	dd temp, k;
	while (!que.empty())
	{
		k = que.front();
		que.pop();
		for (int i = head1[k.v]; ~i; i = edge1[i].next)
		{
			temp = k;
			if (temp.t < edge1[i].w || temp.pre == edge1[i].to)continue;
			temp.t -= edge1[i].w;
			temp.v = edge1[i].to;
			addedge2(temp.u, edge1[i].to, temp.c);
			if (temp.t)que.push(temp);
		}
	}
}

int main()
{
	int n, m, s, t, u, v, w;
	scanf("%d%d", &n, &m);
	scanf("%d%d", &s, &t);
	memset(head1, -1, sizeof head1);
	memset(head2, -1, sizeof head2);
	for (int i = 0; i < m; ++i)
	{
		scanf("%d%d%d", &u, &v, &w);
		addedge1(u, v, w);
		addedge1(v, u, w);
	}
	for (int i = 1; i <= n; ++i)
	{
		scanf("%d%d", &u, &v);
		que.push({ i,i,u,v,i });
	}
	bfs(s);
	printf("%d\n", dji1(s, t));
//	system("pause");
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <string>
#include <iostream>
#include <list>
#define lowbit(x) (x&(-x))
#define inf 0x3f3f3f3f3f3f3f3fLL
using namespace std;
const int maxn = int(1e4 + 10);
int head[1010], tot = 0;
long long mp[1010][1010];
struct node
{
	int next, to;
	long long w;
	bool operator < (const node& cmp)const
	{
		return w > cmp.w;
	}
} edge[maxn << 1];

inline void addedge(int u, int v, int w)
{
	edge[tot].w = w;
	edge[tot].to = v;
	edge[tot].next = head[u];
	head[u] = tot++;
}
void djik(int s,long long *dis)
{
	bool vis[maxn];
	node k, temp;
	memset(vis, 0, sizeof vis);
	vis[s] = true;
	dis[s] = 0;
	priority_queue<node> que;
	for (int i = head[s]; ~i; i = edge[i].next)
	{
		int v = edge[i].to;
		dis[v] = min(dis[v], edge[i].w);
		que.push(edge[i]);
	}
	while (!que.empty())
	{
		k = que.top();
		que.pop();
		if (vis[k.to])continue;
		vis[k.to] = true;
		for (int i = head[k.to]; ~i; i = edge[i].next)
		{
			int v = edge[i].to;
			if (!vis[v] && dis[v] > dis[k.to] + edge[i].w)
			{
				dis[v] = dis[k.to] + edge[i].w;
				que.push({ 0,v,dis[v] });
			}
		}
	}
}

int main()
{
	int n, m, s, t, u, v, w, tt, cc;
	scanf("%d%d", &n, &m);
	scanf("%d%d", &s, &t);
	memset(head, -1, sizeof head);
	memset(mp, 0x3f, sizeof mp);
	for (int i = 0; i < m; ++i)
	{
		scanf("%d%d%d", &u, &v, &w);
		addedge(u, v, w);
		addedge(v, u, w);
	}
	for (int i = 1; i <= n; ++i)
		djik(i, mp[i]);
	memset(head, -1, sizeof head);
	memset(edge, 0, sizeof edge);
	tot = 0;
	for (int i = 1; i <= n; ++i)
	{
		scanf("%d%d", &tt, &cc);
		for (int j = 1; j <= n; ++j)
			if (mp[i][j] <= tt && i != j)addedge(i, j, cc);
	}
	memset(mp[s], 0x3f, sizeof mp[s]);
	djik(s, mp[s]);
	printf("%I64d\n", mp[s][t] == inf ? -1 : mp[s][t]);
//	system("pause");
}


#include<bits/stdc++.h>
#define MAXN 1005
#define ll long long
using namespace std;
inline int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
typedef pair<ll,int>pli;
struct Edge
{
	int v,next;ll w;
}e[MAXN*MAXN];
int head[MAXN],cnt=0;
inline void addedge(int u,int v,ll w){cnt++;e[cnt].v=v;e[cnt].w=w;e[cnt].next=head[u];head[u]=cnt;}
int n,m,S,T;
ll dis[MAXN][MAXN];
bool vis[MAXN];
priority_queue<pli>q;
void dijsktra(int x,ll *dis)
{
	for(int i=1;i<=n;i++) dis[i]=1e16,vis[i]=0;
	q.push(pli(dis[x]=0,x));
	while(!q.empty())
	{
		int u=q.top().second;
		q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=head[u];i;i=e[i].next)
		{
			int v=e[i].v;
			if(dis[v]>dis[u]+e[i].w)
			{
				dis[v]=dis[u]+e[i].w;
				q.push(pli(dis[v],v));
			}
		}
	}
}
int main()
{
	n=read(),m=read(),S=read(),T=read();
	for(int i=1;i<=m;i++)
	{
		ll u=read(),v=read(),w=read();
		addedge(u,v,w);
		addedge(v,u,w);
	}
	for(int i=1;i<=n;i++) dijsktra(i,dis[i]);
	memset(head,0,sizeof(head));
	cnt=0;
	for(int i=1;i<=n;i++)
	{
		ll t=read(),c=read();
		for(int j=1;j<=n;j++)
			if(i!=j&&dis[i][j]<=t)
				addedge(i,j,c);
	}
	dijsktra(S,dis[S]);
	if(dis[S][T]>=1e16) cout<<-1;
	else cout<<dis[S][T];
}


#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
#define inf 1000000000000000000LL
long long mp[1001][1001];
long long mp2[1001][1001];
vector<pair<long long,long long> > edge[1001];
long long n,m,x,y,u,v,w,t,c;
void dijkstra(long long v,long long *d)
{
    long long t;
    priority_queue<pair<long long,long long>,vector<pair<long long,long long> >,greater<pair<long long,long long> > > pq;
    for(long long i=1;i<=n;i++)
        d[i]=inf;
    d[v]=0;
    pq.push(make_pair(0,v));
    while(!pq.empty())
    {
        t=pq.top().second;
        pq.pop();
        for(long long i=0;i<edge[t].size();i++)
            if(d[edge[t][i].first]>d[t]+edge[t][i].second)
            {
                d[edge[t][i].first]=d[t]+edge[t][i].second;
                pq.push(make_pair(d[edge[t][i].first],edge[t][i].first));
            }
    }
    return;
}
int main()
{
    scanf("%I64d%I64d",&n,&m);
    scanf("%I64d%I64d",&x,&y);
    for(long long i=0;i<m;i++)
    {
        scanf("%I64d%I64d%I64d",&u,&v,&w);
        edge[u].push_back(make_pair(v,w));
        edge[v].push_back(make_pair(u,w));
    }
    for(long long i=1;i<=n;i++)
        dijkstra(i,mp[i]);
    for(long long i=1;i<=n;i++)
        edge[i].clear();
    for(long long i=1;i<=n;i++)
    {
        scanf("%I64d%I64d",&t,&c);
        for(long long j=1;j<=n;j++)
            if(j!=i&&mp[i][j]<=t)
                edge[i].push_back(make_pair(j,c));
    }
    dijkstra(x,mp2[x]);
    if(mp2[x][y]!=inf)
        printf("%I64d\n",mp2[x][y]);
    else printf("-1\n");
    return 0;
}


#include<bits/stdc++.h>
#define MAXN 1005
#define ll long long
using namespace std;
inline int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
typedef pair<ll,int>pli;
struct Edge
{
	int v,next;ll w;
}e[MAXN*MAXN];
int head[MAXN],cnt=0;
inline void addedge(int u,int v,ll w){cnt++;e[cnt].v=v;e[cnt].w=w;e[cnt].next=head[u];head[u]=cnt;}
int n,m,S,T;
ll dis[MAXN][MAXN];
bool vis[MAXN];
void dijsktra(int x,ll *dis)
{
	for(int i=1;i<=n;i++) dis[i]=1e15,vis[i]=0;
	priority_queue<pli>q;
	q.push(pli(dis[x]=0,x));
	while(!q.empty())
	{
		int u=q.top().second;
		q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=head[u];i;i=e[i].next)
		{
			int v=e[i].v;
			if(dis[v]>dis[u]+e[i].w)
			{
				dis[v]=dis[u]+e[i].w;
				q.push(pli(dis[v],v));
			}
		}
	}
}
int main()
{
	n=read(),m=read(),S=read(),T=read();
	for(int i=1;i<=m;i++)
	{
		int u=read(),v=read(),w=read();
		addedge(u,v,w);
		addedge(v,u,w);
	}
	for(int i=1;i<=n;i++) dijsktra(i,dis[i]);
	memset(head,0,sizeof(head));
	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)
				addedge(i,j,c);
	}
	dijsktra(S,dis[S]);
	if(dis[S][T]>=1e15) cout<<-1;
	else cout<<dis[S][T];
}


#include<bits/stdc++.h>
//#pragma comment(linker,"/STACK:1024000000,1024000000")
//251103FD
//4008802802
using namespace std;
#define PB pop_back
#define PF pop_front
#define np next_permutation
#define eb emplace_back
#define pb push_back
#define bf push_front
#define mp make_pair
#define s second
#define f first
#define foreach(it, a) for(__typeof((a).begin()) it=(a).begin(); it!=(a).end(); it++)
#define Foreach(it, a) for(__typeof((a).rbegin()) it=(a).rbegin(); it!=(a).rend(); it++)
#define forn(i, a) for(register int i=0; i<a; ++i)
#define Forn(i, a) for(register int i=1; i<=a; ++i)
#define memINF 127
#define all(x) x.begin(), x.end()
#define FAST ios::sync_with_stdio(false)
#define lid id*2+1
#define rid id*2+2
#define lson lid, l, (l+r)>>1
#define rson rid, (l+r)>>1, r
#define base 0, 0, n

typedef long long ll;
typedef pair<ll,int> pi;
typedef pair<pi,int> pii;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef unsigned int uint;
typedef vector<vector<ll> > matrix;

inline int in()
{
    int x=0, c;
    while((uint)((c=getchar())-48)>=10)
		if(c=='-')
			return -in();
    do
	{ x=(x<<3)+(x<<1)+(c^48); }
	while((uint)((c=getchar())^48)<10);
    return x;
}

inline int lcm(int a, int b){return a*b/__gcd(a, b);}

const int MAX=1005;

ll dist[MAX][MAX], C_dist[MAX], cur;
vector<pair<int,int> > e[MAX];
int N, M, T, C, st, ed, a, b, c, fr;
priority_queue<pi, vector<pi>, greater<pi> >q;

inline void get_edge(int x, int length, int cost, ll *d)
{
    e[x].clear();
    Forn(i, N)
        if(i!=x&&d[i]<=length)
            e[x].eb(mp(i, cost));
}

inline void Dij(ll *d, int x)
{
    d[x]=0;
    q.push(mp(0, x));
    while(!q.empty())
    {
        cur=q.top().f, fr=q.top().s, q.pop();
        if(d[fr]!=cur)
            continue;
        foreach(it, e[fr])
            if(d[it->f]>cur+it->s)
                d[it->f]=cur+it->s, q.push(mp(d[it->f], it->f));
    }
}

int main()
{
    N=in(), M=in(), st=in(), ed=in();
    memset(dist, memINF, sizeof(dist));
    memset(C_dist, memINF, sizeof(C_dist));
    while(M--)
    {
        a=in(), b=in(), c=in();
        e[a].eb(mp(b, c));
        e[b].eb(mp(a, c));
    }
    Forn(i, N)
        Dij(dist[i], i);
    Forn(i, N)
    {
        T=in(), C=in();
        get_edge(i, T, C, dist[i]);
    }
    Dij(C_dist, st);
    if(C_dist[ed]>1e18)
        puts("-1");
    else
        printf("%I64d\n", C_dist[ed]);
    return 0;
}


#include<bits/stdc++.h>
//#pragma comment(linker,"/STACK:1024000000,1024000000")
//251103FD
//4008802802
using namespace std;
#define PB pop_back
#define PF pop_front
#define np next_permutation
#define eb emplace_back
#define pb push_back
#define bf push_front
#define mp make_pair
#define s second
#define f first
#define foreach(it, a) for(__typeof((a).begin()) it=(a).begin(); it!=(a).end(); it++)
#define Foreach(it, a) for(__typeof((a).rbegin()) it=(a).rbegin(); it!=(a).rend(); it++)
#define forn(i, a) for(register int i=0; i<a; ++i)
#define Forn(i, a) for(register int i=1; i<=a; ++i)
#define memINF 127
#define all(x) x.begin(), x.end()
#define FAST ios::sync_with_stdio(false)
#define lid id*2+1
#define rid id*2+2
#define lson lid, l, (l+r)>>1
#define rson rid, (l+r)>>1, r
#define base 0, 0, n

typedef long long ll;
typedef pair<ll,int> pi;
typedef pair<pi,int> pii;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef unsigned int uint;
typedef vector<vector<ll> > matrix;

inline int in()
{
    int x=0, c;
    while((uint)((c=getchar())-48)>=10)
		if(c=='-')
			return -in();
    do
	{ x=(x<<3)+(x<<1)+(c^48); }
	while((uint)((c=getchar())^48)<10);
    return x;
}

inline int lcm(int a, int b){return a*b/__gcd(a, b);}

const int MAX=1005;

bool inq[MAX];
ll dist[MAX][MAX], C_dist[MAX];
vector<pair<int,int> > e[MAX];
int N, M, T, C, st, ed, a, b, c, fr, q[MAX], l, r;

inline void get_edge(int x, int length, int cost, ll *d)
{
    e[x].clear();
    Forn(i, N)
        if(i!=x&&d[i]<=length)
            e[x].eb(mp(i, cost));
}

inline int pop()
{
    int a=q[l++];
    if(l==MAX)
        l=0;
    inq[a]=false;
    return a;
}

inline void push(int a)
{
    if(inq[a])
        return;
    inq[a]=true;
    q[r++]=a;
    if(r==MAX)
        r=0;
}

inline void spfa(ll *d, int x)
{
    d[x]=0;
    push(x);
    while(l!=r)
    {
        fr=pop();
        foreach(it, e[fr])
            if(d[it->f]>d[fr]+it->s)
                d[it->f]=d[fr]+it->s, push(it->f);
    }
}

int main()
{
    N=in(), M=in(), st=in(), ed=in();
    memset(dist, memINF, sizeof(dist));
    memset(C_dist, memINF, sizeof(C_dist));
    while(M--)
    {
        a=in(), b=in(), c=in();
        e[a].eb(mp(b, c));
        e[b].eb(mp(a, c));
    }
    Forn(i, N)
        spfa(dist[i], i);
    Forn(i, N)
    {
        T=in(), C=in();
        get_edge(i, T, C, dist[i]);
    }
    spfa(C_dist, st);
    if(C_dist[ed]>1e18)
        puts("-1");
    else
        printf("%I64d\n", C_dist[ed]);
    return 0;
}


#include<bits/stdc++.h>
//#pragma comment(linker,"/STACK:1024000000,1024000000")
//251103FD
//4008802802
using namespace std;
#define PB pop_back
#define PF pop_front
#define np next_permutation
#define eb emplace_back
#define pb push_back
#define bf push_front
#define mp make_pair
#define s second
#define f first
#define foreach(it, a) for(__typeof((a).begin()) it=(a).begin(); it!=(a).end(); it++)
#define Foreach(it, a) for(__typeof((a).rbegin()) it=(a).rbegin(); it!=(a).rend(); it++)
#define forn(i, a) for(register int i=0; i<a; ++i)
#define Forn(i, a) for(register int i=1; i<=a; ++i)
#define memINF 127
#define all(x) x.begin(), x.end()
#define FAST ios::sync_with_stdio(false)
#define lid id*2+1
#define rid id*2+2
#define lson lid, l, (l+r)>>1
#define rson rid, (l+r)>>1, r
#define base 0, 0, n

typedef long long ll;
typedef pair<ll,int> pi;
typedef pair<pi,int> pii;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef unsigned int uint;
typedef vector<vector<ll> > matrix;

inline int in()
{
    int x=0, c;
    while((uint)((c=getchar())-48)>=10)
		if(c=='-')
			return -in();
    do
	{ x=(x<<3)+(x<<1)+(c^48); }
	while((uint)((c=getchar())^48)<10);
    return x;
}

inline int lcm(int a, int b){return a*b/__gcd(a, b);}

const int MAX=1005;

ll dist[MAX][MAX], C_dist[MAX], cur;
list<pair<int,int> > e[MAX];
int N, M, T, C, st, ed, a, b, c, fr;
priority_queue<pi, vector<pi>, greater<pi> >q;

inline void get_edge(int x, int length, int cost, ll *d)
{
    e[x].clear();
    Forn(i, N)
        if(i!=x&&d[i]<=length)
            e[x].eb(mp(i, cost));
}

inline void Dij(ll *d, int x)
{
    d[x]=0;
    q.push(mp(0, x));
    while(!q.empty())
    {
        cur=q.top().f, fr=q.top().s, q.pop();
        if(d[fr]!=cur)
            continue;
        foreach(it, e[fr])
            if(d[it->f]>cur+it->s)
                d[it->f]=cur+it->s, q.push(mp(d[it->f], it->f));
    }
}

int main()
{
    N=in(), M=in(), st=in(), ed=in();
    memset(dist, memINF, sizeof(dist));
    memset(C_dist, memINF, sizeof(C_dist));
    while(M--)
    {
        a=in(), b=in(), c=in();
        e[a].eb(mp(b, c));
        e[b].eb(mp(a, c));
    }
    Forn(i, N)
        Dij(dist[i], i);
    Forn(i, N)
    {
        T=in(), C=in();
        get_edge(i, T, C, dist[i]);
    }
    Dij(C_dist, st);
    if(C_dist[ed]>1e18)
        puts("-1");
    else
        printf("%I64d\n", C_dist[ed]);
    return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define inf 1e11
using namespace std;
typedef long long int ll;
typedef pair<int,int> ii;
vector<pair<ll,int> >graph[1001],money_graph[1001];
vector<ll>t,c;
vector<bool>vis;
vector<vector<ll> >dis;
priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > >pq;
int n,m;bool opt=true;
void dijkstras(const int& u)
{
	dis[u][u]=0;
	vis.clear();
	vis.resize(n+1,false);
	pq.push({0,u});
	while(!pq.empty())
	{
		int par=pq.top().second;
		pq.pop();
		if(vis[par])continue;
		vis[par]=true;
		for(auto child:((opt)?(graph[par]):(money_graph[par])))
		{
			if(dis[u][child.second] > dis[u][par]+child.first)
			{
				dis[u][child.second]=child.first+dis[u][par];
				pq.push({dis[u][child.second],child.second});
			}
		}
	}
}
int main()
{
	//freopen("/home/kislaya/inp.txt","r",stdin);
	cin.sync_with_stdio(0),cin.tie(0);
	int x,y,u,v;ll w;
	cin>>n>>m>>x>>y;
	t.resize(n+1),c.resize(n+1),dis.resize(n+1,vector<ll>(n+1,inf));
	for(int i=0;i<m;i++)
		cin>>u>>v>>w,graph[u].pb({w,v}),graph[v].pb({w,u});
	for(int i=1;i<=n;i++)
		cin>>t[i]>>c[i];
	for(int i=1;i<=n;i++)
		{
			dijkstras(i);
			for(int j=1;j<=n;j++)
				if(dis[i][j]<=t[i] && i!=j)
					money_graph[i].pb({c[i],j});
		}
	opt=false;
	fill(dis[x].begin(),dis[x].end(),inf);
	dijkstras(x);
	cout<<dis[x][y]<<"\n";
	return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define inf 1e11
using namespace std;
typedef long long int ll;
typedef pair<int,int> ii;
vector<pair<ll,int> >graph[1001],money_graph[1001];
vector<ll>t,c;
vector<bool>vis;
vector<vector<ll> >dis;
priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > >pq;
int n,m;bool opt=true;
void dijkstras(const int& u)
{
	dis[u][u]=0;
	vis.clear();
	vis.resize(n+1,false);
	pq.push({0,u});
	while(!pq.empty())
	{
		int par=pq.top().second;
		pq.pop();
		if(vis[par])continue;
		vis[par]=true;
		for(auto child:((opt)?(graph[par]):(money_graph[par])))
		{
			if(dis[u][child.second] > dis[u][par]+child.first)
			{
				dis[u][child.second]=child.first+dis[u][par];
				pq.push({dis[u][child.second],child.second});
			}
		}
	}
}
int main()
{
	//freopen("/home/kislaya/inp.txt","r",stdin);
	cin.sync_with_stdio(0),cin.tie(0);
	int x,y,u,v;ll w;
	cin>>n>>m>>x>>y;
	t.resize(n+1),c.resize(n+1),dis.resize(n+1,vector<ll>(n+1,inf));
	for(int i=0;i<m;i++)
		cin>>u>>v>>w,graph[u].pb({w,v}),graph[v].pb({w,u});
	for(int i=1;i<=n;i++)
		cin>>t[i]>>c[i];
	for(int i=1;i<=n;i++)
		{
			dijkstras(i);
			for(int j=1;j<=n;j++)
				if(dis[i][j]<=t[i] && i!=j)
					money_graph[i].pb({c[i],j});
		}
	opt=false;
	fill(dis[x].begin(),dis[x].end(),inf);
	dijkstras(x);
	if(dis[x][y]>=inf)dis[x][y]=-1;
	cout<<dis[x][y]<<"\n";
	return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define inf 1e18
using namespace std;
typedef long long int ll;
typedef pair<int,int> ii;
vector<pair<ll,int> >graph[1001],money_graph[1001];
vector<ll>t,c;
vector<bool>vis;
vector<vector<ll> >dis;
priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > >pq;
int n,m;bool opt=true;
void dijkstras(const int& u)
{
	dis[u][u]=0;
	vis.clear();
	vis.resize(n+1,false);
	pq.push({0,u});
	while(!pq.empty())
	{
		int par=pq.top().second;
		pq.pop();
		if(vis[par])continue;
		vis[par]=true;
		for(auto child:((opt)?(graph[par]):(money_graph[par])))
		{
			if(dis[u][child.second] > dis[u][par]+child.first)
			{
				dis[u][child.second]=child.first+dis[u][par];
				pq.push({dis[u][child.second],child.second});
			}
		}
	}
}
int main()
{
	//freopen("/home/kislaya/inp.txt","r",stdin);
	cin.sync_with_stdio(0),cin.tie(0);
	int x,y,u,v;ll w;
	cin>>n>>m>>x>>y;
	t.resize(n+1),c.resize(n+1),dis.resize(n+1,vector<ll>(n+1,inf));
	for(int i=0;i<m;i++)
		cin>>u>>v>>w,graph[u].pb({w,v}),graph[v].pb({w,u});
	for(int i=1;i<=n;i++)
		cin>>t[i]>>c[i];
	for(int i=1;i<=n;i++)
		{
			dijkstras(i);
			for(int j=1;j<=n;j++)
				if(dis[i][j]<=t[i] && i!=j)
					money_graph[i].pb({c[i],j});
		}
	opt=false;
	fill(dis[x].begin(),dis[x].end(),inf);
	dijkstras(x);
	if(dis[x][y]>=inf)dis[x][y]=-1;
	cout<<dis[x][y]<<"\n";
	return 0;
}


#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int iz=200005;
const long long inf=2e15;
typedef long long ll;
int x,y,s,t,n,m;
int u,v,tot=0;
ll e[1005][1005],w[iz<<1],dis[1005],p;
int Head[1005],Next[iz<<1],to[iz<<1];

inline void add(int q,int r,int k){
	to[++tot]=r; w[tot]=k;
	Next[tot]=Head[q];
	Head[q]=tot;
}
struct Heap{
	long long d;
	int id;
	bool operator < (const Heap &a) const{
		return d>a.d;
	}
}z;
priority_queue<Heap> q;

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		dis[i]=inf;
		for(int j=1;j<=n;j++)e[i][j]=inf;
	}
	scanf("%d%d",&s,&t);
	for(int i=1;i<=m;i++){
		scanf("%d%d%I64d",&u,&v,&p);
		e[u][v]=e[v][u]=min(e[u][v],p);
	}
	for(int i=1;i<=n;i++)e[i][i]=0;
	for(int k=1;k<=n;k++){
		for(int i=1;i<=n;i++){
			if(e[i][k]==inf)continue;
			for(int j=1;j<=n;j++){
				e[i][j]=e[i][j]<e[i][k]+e[k][j]?e[i][j]:e[i][k]+e[k][j];
			}
		}
	}
	for(int i=1;i<=n;i++){
		scanf("%d%d",&x,&y);
		for(int j=1;j<=n;j++){
			if(e[i][j]<=x && i!=j){
				add(i,j,y);
			}
		}
	}
	z.id=s; z.d=0; q.push(z); dis[s]=0;
	while(!q.empty()){
		if(dis[q.top().id]!=q.top().d){q.pop(); continue;}
		z=q.top(); q.pop();
		for(int i=Head[z.id];i;i=Next[i]){
			if(dis[to[i]]>dis[z.id]+w[i]){
				dis[to[i]]=dis[z.id]+w[i];
				q.push((Heap){dis[to[i]],to[i]});
			}
		}
	}
	if(dis[t]==inf)printf("-1");
	else printf("%I64d",dis[t]);
}


#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int iz=200005;
const long long inf=2e15;
const int iz2=1005;
typedef long long ll;
int x,y,s,t,n,m;
int u,v,tot=0;
ll e[1005][1005],w[iz<<1],dis[1005],p;
int Head[1005],Next[iz<<1],to[iz<<1];
int H2[1005],N2[iz2<<1],t2[iz2<<1],w2[iz2<<1];
ll d[1005],vis[1005];

inline void add(int q,int r,int k){
    to[++tot]=r; w[tot]=k;
    Next[tot]=Head[q];
    Head[q]=tot;
}
inline void A2(int q,int r,int k){
    t2[++tot]=r; w2[tot]=k;
    N2[tot]=H2[q];
    H2[q]=tot;
}
struct Heap{
    long long d;
    int id;
    bool operator < (const Heap &a) const{
        return d>a.d;
    }
}z;
priority_queue<Heap> q;

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        dis[i]=inf;
	}
    tot=0;
    scanf("%d%d",&s,&t);
    for(int i=1;i<=m;i++){
        scanf("%d%d%I64d",&u,&v,&p);
        A2(u,v,p); A2(v,u,p);
    }
    tot=0;
    for(int i=1;i<=n;i++){
        scanf("%d%d",&x,&y);
        for(int j=1;j<=n;j++)d[j]=inf;
        memset(vis,0,sizeof(vis));
        q.push((Heap){0,i}); d[i]=0;
        while(!q.empty()){
            if(vis[q.top().id]){q.pop(); continue;}
            z=q.top(); q.pop(); vis[z.id]=true;
            for(int j=H2[z.id];j;j=N2[j]){
                if(!vis[t2[j]] && d[t2[j]]>d[z.id]+w2[j]){
                    d[t2[j]]=d[z.id]+w2[j];
                    q.push((Heap){d[t2[j]],t2[j]});
                }
            }
        }
        for(int j=1;j<=n;j++){
            if(d[j]<=x && i!=j){
                add(i,j,y);
            }
        }
    }
    z.id=s; z.d=0; q.push(z); dis[s]=0;
    memset(vis,0,sizeof(vis));
    while(!q.empty()){
        if(vis[q.top().id]){q.pop(); continue;}
        z=q.top(); q.pop(); vis[z.id]=true;
        if(z.id==t)break;
        for(int i=Head[z.id];i;i=Next[i]){
            if(!vis[to[i]] && dis[to[i]]>dis[z.id]+w[i]){
                dis[to[i]]=dis[z.id]+w[i];
                q.push((Heap){dis[to[i]],to[i]});
            }
        }
    }
    if(dis[t]==inf)printf("-1");
    else printf("%I64d",dis[t]);
}


#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int iz=200005;
const long long inf=2e15;
const int iz2=1005;
typedef long long ll;
int x,y,s,t,n,m;
int u,v,tot=0;
ll e[1005][1005],w[iz<<1],dis[1005],p;
int Head[1005],Next[iz<<1],to[iz<<1];
int H2[1005],N2[iz2<<1],t2[iz2<<1],w2[iz2<<1];

inline void add(int q,int r,int k){
	to[++tot]=r; w[tot]=k;
	Next[tot]=Head[q];
	Head[q]=tot;
}
inline void A2(int q,int r,int k){
	t2[++tot]=r; w2[tot]=k;
	N2[tot]=H2[q];
	H2[q]=tot;
}
struct Heap{
	long long d;
	int id;
	bool operator < (const Heap &a) const{
		return d>a.d;
	}
}z;
priority_queue<Heap> q;

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		dis[i]=inf;
		for(int j=1;j<=n;j++)e[i][j]=inf;
	}
	tot=0;
	scanf("%d%d",&s,&t);
	for(int i=1;i<=m;i++){
		scanf("%d%d%I64d",&u,&v,&p);
		A2(u,v,p); A2(v,u,p);
	}
	for(int i=1;i<=n;i++){
		q.push((Heap){0,i}); e[i][i]=0;
		while(!q.empty()){
			if(e[i][q.top().id]!=q.top().d){q.pop(); continue;}
			z=q.top(); q.pop();
			for(int j=H2[z.id];j;j=N2[j]){
				if(t2[j]>i && e[i][t2[j]]>e[i][z.id]+w2[j]){
					e[i][t2[j]]=e[t2[j]][i]=e[i][z.id]+w2[j];
					q.push((Heap){e[i][t2[j]],t2[j]});
				}
			}
		}
	}
	tot=0;
	for(int i=1;i<=n;i++){
		scanf("%d%d",&x,&y);
		for(int j=1;j<=n;j++){
			if(e[i][j]<=x && i!=j){
				add(i,j,y);
			}
		}
	}
	z.id=s; z.d=0; q.push(z); dis[s]=0;
	while(!q.empty()){
		if(dis[q.top().id]!=q.top().d){q.pop(); continue;}
		z=q.top(); q.pop();
		for(int i=Head[z.id];i;i=Next[i]){
			if(dis[to[i]]>dis[z.id]+w[i]){
				dis[to[i]]=dis[z.id]+w[i];
				q.push((Heap){dis[to[i]],to[i]});
			}
		}
	}
	if(dis[t]==inf)printf("-1");
	else printf("%I64d",dis[t]);
}


#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int iz=200005;
const long long inf=2e15;
const int iz2=1005;
typedef long long ll;
int x,y,s,t,n,m;
int u,v,tot=0;
ll e[1005][1005],w[iz<<1],dis[1005],p;
int Head[1005],Next[iz<<1],to[iz<<1];
int H2[1005],N2[iz2<<1],t2[iz2<<1],w2[iz2<<1];
ll d[1005],vis[1005];

inline void add(int q,int r,int k){
    to[++tot]=r; w[tot]=k;
    Next[tot]=Head[q];
    Head[q]=tot;
}
inline void A2(int q,int r,int k){
    t2[++tot]=r; w2[tot]=k;
    N2[tot]=H2[q];
    H2[q]=tot;
}
queue<int> q;

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        dis[i]=inf;
	}
    tot=0;
    scanf("%d%d",&s,&t);
    for(int i=1;i<=m;i++){
        scanf("%d%d%I64d",&u,&v,&p);
        A2(u,v,p); A2(v,u,p);
    }
    tot=0;
    for(int i=1;i<=n;i++){
        scanf("%d%d",&x,&y);
        for(int j=1;j<=n;j++)d[j]=inf;
        memset(vis,0,sizeof(vis));
        q.push(i); d[i]=0; vis[i]=true;
        while(!q.empty()){
        	int u=q.front(); q.pop(); vis[u]=false;
        	for(int j=H2[u];j;j=N2[j]){
        		if(d[t2[j]]>d[u]+w2[j]){
        			d[t2[j]]=d[u]+w2[j];
        			if(!vis[t2[j]])vis[t2[j]]=true,q.push(t2[j]);
        		}
        	}
        }
        for(int j=1;j<=n;j++){
            if(d[j]<=x && i!=j){
                add(i,j,y);
            }
        }
    }
    for(int j=1;j<=n;j++)dis[j]=inf;
    memset(vis,0,sizeof(vis));
    q.push(s); vis[s]=true; dis[s]=0;
    while(!q.empty()){
        int u=q.front(); q.pop(); vis[u]=false;
        for(int i=Head[u];i;i=Next[i]){
        	if(dis[to[i]]>dis[u]+w[i]){
        		dis[to[i]]=dis[u]+w[i];
        		if(!vis[to[i]])vis[to[i]]=true,q.push(to[i]);
        	}
        }
	}
    if(dis[t]==inf)printf("-1");
    else printf("%I64d",dis[t]);
}


#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int iz=500005;
const long long inf=2e15;
const int iz2=1005;
typedef long long ll;
int x,y,s,t,n,m;
int u,v,tot=0;
ll e[1005][1005],w[iz<<1],dis[1005],p;
int Head[1005],Next[iz<<1],to[iz<<1];
int H2[1005],N2[iz2<<1],t2[iz2<<1],w2[iz2<<1];
ll d[1005],vis[1005];

inline void add(int q,int r,int k){
    to[++tot]=r; w[tot]=k;
    Next[tot]=Head[q];
    Head[q]=tot;
}
inline void A2(int q,int r,int k){
    t2[++tot]=r; w2[tot]=k;
    N2[tot]=H2[q];
    H2[q]=tot;
}
struct Heap{
    long long d;
    int id;
    bool operator < (const Heap &a) const{
        return d>a.d;
    }
}z;
priority_queue<Heap> q;

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        dis[i]=inf;
	}
    tot=0;
    scanf("%d%d",&s,&t);
    for(int i=1;i<=m;i++){
        scanf("%d%d%I64d",&u,&v,&p);
        A2(u,v,p); A2(v,u,p);
    }
    tot=0;
    for(int i=1;i<=n;i++){
        scanf("%d%d",&x,&y);
        for(int j=1;j<=n;j++)d[j]=inf;
        memset(vis,0,sizeof(vis));
        q.push((Heap){0,i}); d[i]=0;
        while(!q.empty()){
            if(vis[q.top().id]){q.pop(); continue;}
            z=q.top(); q.pop(); vis[z.id]=true;
            for(int j=H2[z.id];j;j=N2[j]){
                if(!vis[t2[j]] && d[t2[j]]>d[z.id]+w2[j]){
                    d[t2[j]]=d[z.id]+w2[j];
                    q.push((Heap){d[t2[j]],t2[j]});
                }
            }
        }
        for(int j=1;j<=n;j++){
            if(d[j]<=x && i!=j){
                add(i,j,y);
            }
        }
    }
    z.id=s; z.d=0; q.push(z); dis[s]=0;
    memset(vis,0,sizeof(vis));
    while(!q.empty()){
        if(vis[q.top().id]){q.pop(); continue;}
        z=q.top(); q.pop(); vis[z.id]=true;
        if(z.id==t)break;
        for(int i=Head[z.id];i;i=Next[i]){
            if(!vis[to[i]] && dis[to[i]]>dis[z.id]+w[i]){
                dis[to[i]]=dis[z.id]+w[i];
                q.push((Heap){dis[to[i]],to[i]});
            }
        }
    }
    if(dis[t]==inf)printf("-1");
    else printf("%I64d",dis[t]);
}


#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int iz=200005;
const long long inf=2e15;
const int iz2=1005;
typedef long long ll;
int x,y,s,t,n,m;
int u,v,tot=0;
ll e[1005][1005],w[iz<<1],dis[1005],p;
int Head[1005],Next[iz<<1],to[iz<<1];
int H2[1005],N2[iz2<<1],t2[iz2<<1],w2[iz2<<1];
ll d[1005],vis[1005];

inline void add(int q,int r,int k){
    to[++tot]=r; w[tot]=k;
    Next[tot]=Head[q];
    Head[q]=tot;
}
inline void A2(int q,int r,int k){
    t2[++tot]=r; w2[tot]=k;
    N2[tot]=H2[q];
    H2[q]=tot;
}
struct Heap{
    long long d;
    int id;
    bool operator < (const Heap &a) const{
        return d>a.d;
    }
}z;
priority_queue<Heap> q;

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        dis[i]=inf;
	}
    tot=0;
    scanf("%d%d",&s,&t);
    for(int i=1;i<=m;i++){
        scanf("%d%d%I64d",&u,&v,&p);
        A2(u,v,p); A2(v,u,p);
    }
    tot=0;
    for(int i=1;i<=n;i++){
        scanf("%d%d",&x,&y);
        for(int j=1;j<=n;j++)d[j]=inf;
        memset(vis,0,sizeof(vis));
        q.push((Heap){0,i}); d[i]=0;
        while(!q.empty()){
            if(vis[q.top().id]){q.pop(); continue;}
            z=q.top(); q.pop();
            for(int j=H2[z.id];j;j=N2[j]){
                if(d[t2[j]]>d[z.id]+w2[j]){
                    d[t2[j]]=d[z.id]+w2[j];
                    q.push((Heap){d[t2[j]],t2[j]});
                }
            }
        }
        for(int j=1;j<=n;j++){
            if(d[j]<=x && i!=j){
                add(i,j,y);
            }
        }
    }
    z.id=s; z.d=0; q.push(z); dis[s]=0;
    memset(vis,0,sizeof(vis));
    while(!q.empty()){
        if(vis[q.top().id]){q.pop(); continue;}
        z=q.top(); q.pop();
        for(int i=Head[z.id];i;i=Next[i]){
            if(dis[to[i]]>dis[z.id]+w[i]){
                dis[to[i]]=dis[z.id]+w[i];
                q.push((Heap){dis[to[i]],to[i]});
            }
        }
    }
    if(dis[t]==inf)printf("-1");
    else printf("%I64d",dis[t]);
}


#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int iz=100005;
const long long inf=2e15;
typedef long long ll;
int x,y,s,t,n,m;
int u,v,tot=0;
ll e[1005][1005],w[iz<<1],dis[1005],p;
int Head[1005],Next[iz<<1],to[iz<<1];

inline void add(int q,int r,int k){
	to[++tot]=r; w[tot]=k;
	Next[tot]=Head[q];
	Head[q]=tot;
}
struct Heap{
	long long d;
	int id;
	bool operator < (const Heap &a) const{
		return d>a.d;
	}
}z;
priority_queue<Heap> q;

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		dis[i]=inf;
		for(int j=1;j<=n;j++)e[i][j]=inf;
	}
	scanf("%d%d",&s,&t);
	for(int i=1;i<=m;i++){
		scanf("%d%d%I64d",&u,&v,&p);
//		printf("%I64d\n",e[u][v]);
		e[u][v]=e[v][u]=min(e[u][v],p);
	}
	for(int i=1;i<=n;i++)e[i][i]=0;
	for(int k=1;k<=n;k++){
		for(int i=1;i<=n;i++){
			if(e[i][k]==inf)continue;
			for(int j=1;j<=n;j++){
				e[i][j]=min(e[i][j],e[i][k]+e[k][j]);
			}
		}
	}
	for(int i=1;i<=n;i++){
		scanf("%d%d",&x,&y);
		for(int j=1;j<=n;j++){
			if(e[i][j]<=x && i!=j){
				add(i,j,y);
			}
		}
	}
	z.id=s; z.d=0; q.push(z); dis[s]=0;
	while(!q.empty()){
		if(dis[q.top().id]!=q.top().d){q.pop(); continue;}
		z=q.top(); q.pop();
		for(int i=Head[z.id];i;i=Next[i]){
			if(dis[to[i]]>dis[z.id]+w[i]){
				dis[to[i]]=dis[z.id]+w[i];
				q.push((Heap){dis[to[i]],to[i]});
			}
		}
	}
	if(dis[t]==inf)printf("-1");
	else printf("%I64d",dis[t]);
}


#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int iz=200005;
const long long inf=2e15;
const int iz2=1005;
typedef long long ll;
int x,y,s,t,n,m;
int u,v,tot=0;
ll e[1005][1005],w[iz<<1],dis[1005],p;
int Head[1005],Next[iz<<1],to[iz<<1];
int H2[1005],N2[iz2<<1],t2[iz2<<1],w2[iz2<<1];
ll d[1005],vis[1005];

inline void add(int q,int r,int k){
    to[++tot]=r; w[tot]=k;
    Next[tot]=Head[q];
    Head[q]=tot;
}
inline void A2(int q,int r,int k){
    t2[++tot]=r; w2[tot]=k;
    N2[tot]=H2[q];
    H2[q]=tot;
}
struct Heap{
    long long d;
    int id;
    bool operator < (const Heap &a) const{
        return d>a.d;
    }
}z;
priority_queue<Heap> q;

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        dis[i]=inf;
	}
    tot=0;
    scanf("%d%d",&s,&t);
    for(int i=1;i<=m;i++){
        scanf("%d%d%I64d",&u,&v,&p);
        A2(u,v,p); A2(v,u,p);
    }
    tot=0;
    for(int i=1;i<=n;i++){
        scanf("%d%d",&x,&y);
        for(int j=1;j<=n;j++)d[j]=inf;
        memset(vis,0,sizeof(vis));
        q.push((Heap){0,i}); e[i][i]=0;
        while(!q.empty()){
            if(vis[q.top().id]){q.pop(); continue;}
            z=q.top(); q.pop(); vis[z.id]=true;
            for(int j=H2[z.id];j;j=N2[j]){
                if(!vis[t2[j]] && d[t2[j]]>d[z.id]+w2[j]){
                    d[t2[j]]=d[z.id]+w2[j];
                    q.push((Heap){d[t2[j]],t2[j]});
                }
            }
        }
        for(int j=1;j<=n;j++){
            if(d[j]<=x && i!=j){
                add(i,j,y);
            }
        }
    }
    z.id=s; z.d=0; q.push(z); dis[s]=0;
    memset(vis,0,sizeof(vis));
    while(!q.empty()){
        if(vis[q.top().id]){q.pop(); continue;}
        z=q.top(); q.pop();
        for(int i=Head[z.id];i;i=Next[i]){
            if(!vis[to[i]] && dis[to[i]]>dis[z.id]+w[i]){
                dis[to[i]]=dis[z.id]+w[i];
                q.push((Heap){dis[to[i]],to[i]});
            }
        }
    }
    if(dis[t]==inf)printf("-1");
    else printf("%I64d",dis[t]);
}


#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int iz=200005;
const long long inf=2e15;
const int iz2=1005;
typedef long long ll;
int x,y,s,t,n,m;
int u,v,tot=0;
ll e[1005][1005],w[iz<<1],dis[1005],p;
int Head[1005],Next[iz<<1],to[iz<<1];
int H2[1005],N2[iz2<<1],t2[iz2<<1],w2[iz2<<1];
ll d[1005];

inline void add(int q,int r,int k){
    to[++tot]=r; w[tot]=k;
    Next[tot]=Head[q];
    Head[q]=tot;
}
inline void A2(int q,int r,int k){
    t2[++tot]=r; w2[tot]=k;
    N2[tot]=H2[q];
    H2[q]=tot;
}
struct Heap{
    long long d;
    int id;
    bool operator < (const Heap &a) const{
        return d>a.d;
    }
}z;
priority_queue<Heap> q;

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        dis[i]=inf;
	}
    tot=0;
    scanf("%d%d",&s,&t);
    for(int i=1;i<=m;i++){
        scanf("%d%d%I64d",&u,&v,&p);
        A2(u,v,p); A2(v,u,p);
    }
    tot=0;
    for(int i=1;i<=n;i++){
        scanf("%d%d",&x,&y);
        for(int j=1;j<=n;j++)d[j]=inf;
        q.push((Heap){0,i}); d[i]=0;
        while(!q.empty()){
            if(d[q.top().id]!=q.top().d){q.pop(); continue;}
            z=q.top(); q.pop();
            for(int j=H2[z.id];j;j=N2[j]){
                if(d[t2[j]]>d[z.id]+w2[j]){
                    d[t2[j]]=d[z.id]+w2[j];
                    q.push((Heap){d[t2[j]],t2[j]});
                }
            }
        }
        for(int j=1;j<=n;j++){
            if(d[j]<=x && i!=j){
                add(i,j,y);
            }
        }
    }
    z.id=s; z.d=0; q.push(z); dis[s]=0;
    while(!q.empty()){
        if(dis[q.top().id]!=q.top().d){q.pop(); continue;}
        z=q.top(); q.pop();
        for(int i=Head[z.id];i;i=Next[i]){
            if(dis[to[i]]>dis[z.id]+w[i]){
                dis[to[i]]=dis[z.id]+w[i];
                q.push((Heap){dis[to[i]],to[i]});
            }
        }
    }
    if(dis[t]==inf)printf("-1");
    else printf("%I64d",dis[t]);
}


#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int iz=200005;
const long long inf=2e15;
const int iz2=1005;
typedef long long ll;
int x,y,s,t,n,m;
int u,v,tot=0;
ll e[1005][1005],w[iz<<1],dis[1005],p;
int Head[1005],Next[iz<<1],to[iz<<1];
int H2[1005],N2[iz2<<1],t2[iz2<<1],w2[iz2<<1];

inline void add(int q,int r,int k){
	to[++tot]=r; w[tot]=k;
	Next[tot]=Head[q];
	Head[q]=tot;
}
inline void A2(int q,int r,int k){
	t2[++tot]=r; w2[tot]=k;
	N2[tot]=H2[q];
	H2[q]=tot;
}
struct Heap{
	long long d;
	int id;
	bool operator < (const Heap &a) const{
		return d>a.d;
	}
}z;
priority_queue<Heap> q;

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		dis[i]=inf;
		for(int j=1;j<=n;j++)e[i][j]=inf;
	}
	tot=0;
	scanf("%d%d",&s,&t);
	for(int i=1;i<=m;i++){
		scanf("%d%d%I64d",&u,&v,&p);
		A2(u,v,p); A2(v,u,p);
	}
	for(int i=1;i<=n;i++){
		q.push((Heap){0,i}); e[i][i]=0;
		while(!q.empty()){
			if(e[i][q.top().id]!=q.top().d){q.pop(); continue;}
			z=q.top(); q.pop();
			for(int j=H2[z.id];j;j=N2[j]){
				if(t2[j]>i && e[i][t2[j]]>e[i][z.id]+w2[j]){
					e[i][t2[j]]=e[i][z.id]+w2[j];
					q.push((Heap){e[i][t2[j]],t2[j]});
				}
			}
		}
	}
	tot=0;
	for(int i=1;i<=n;i++){
		scanf("%d%d",&x,&y);
		for(int j=1;j<=n;j++){
			if(e[min(i,j)][max(i,j)]<=x && i!=j){
				add(i,j,y);
			}
		}
	}
	z.id=s; z.d=0; q.push(z); dis[s]=0;
	while(!q.empty()){
		if(dis[q.top().id]!=q.top().d){q.pop(); continue;}
		z=q.top(); q.pop();
		for(int i=Head[z.id];i;i=Next[i]){
			if(dis[to[i]]>dis[z.id]+w[i]){
				dis[to[i]]=dis[z.id]+w[i];
				q.push((Heap){dis[to[i]],to[i]});
			}
		}
	}
	if(dis[t]==inf)printf("-1");
	else printf("%I64d",dis[t]);
}


#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int iz=200005;
const long long inf=2e15;
const int iz2=1005;
typedef long long ll;
int x,y,s,t,n,m;
int u,v,tot=0;
ll e[1005][1005],w[iz<<1],dis[1005],p;
int Head[1005],Next[iz<<1],to[iz<<1];
int H2[1005],N2[iz2<<1],t2[iz2<<1],w2[iz2<<1];

inline void add(int q,int r,int k){
	to[++tot]=r; w[tot]=k;
	Next[tot]=Head[q];
	Head[q]=tot;
}
inline void A2(int q,int r,int k){
	t2[++tot]=r; w2[tot]=k;
	N2[tot]=H2[q];
	H2[q]=tot;
}
struct Heap{
	long long d;
	int id;
	bool operator < (const Heap &a) const{
		return d>a.d;
	}
}z;
priority_queue<Heap> q;

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		dis[i]=inf;
		for(int j=1;j<=n;j++)e[i][j]=inf;
	}
//	for(int i=1;i<=n;i++){
//		for(int j=1;j<=n;j++)printf("%I64d ",e[i][j]==inf?-1:e[i][j]);
//		printf("\n");
//	}
	tot=0;
	scanf("%d%d",&s,&t);
	for(int i=1;i<=m;i++){
		scanf("%d%d%I64d",&u,&v,&p);
		A2(u,v,p); A2(v,u,p);
	}
	for(int i=1;i<=n;i++){
		q.push((Heap){0,i}); e[i][i]=0;
		while(!q.empty()){
			if(e[i][q.top().id]!=q.top().d){q.pop(); continue;}
			z=q.top(); q.pop();
//			printf("cur: %d %d %I64d\n",i,z.id,z.d);
			for(int j=H2[z.id];j;j=N2[j]){
//				printf("to: %d %I64d\n",t2[j],w2[j]);
				if(e[i][t2[j]]>e[i][z.id]+w2[j]){
					e[i][t2[j]]=e[i][z.id]+w2[j];
					q.push((Heap){e[i][t2[j]],t2[j]});
				}
			}
		}
	}
//	for(int i=1;i<=n;i++){
//		for(int j=1;j<=n;j++)printf("%I64d ",e[i][j]==inf?-1:e[i][j]);
//		printf("\n");
//	}
	tot=0;
	for(int i=1;i<=n;i++){
		scanf("%d%d",&x,&y);
		for(int j=1;j<=n;j++){
			if(e[i][j]<=x && i!=j){
				add(i,j,y);
			}
		}
	}
	z.id=s; z.d=0; q.push(z); dis[s]=0;
	while(!q.empty()){
		if(dis[q.top().id]!=q.top().d){q.pop(); continue;}
		z=q.top(); q.pop();
		for(int i=Head[z.id];i;i=Next[i]){
			if(dis[to[i]]>dis[z.id]+w[i]){
				dis[to[i]]=dis[z.id]+w[i];
				q.push((Heap){dis[to[i]],to[i]});
			}
		}
	}
	if(dis[t]==inf)printf("-1");
	else printf("%I64d",dis[t]);
}