#include <bits/stdc++.h>
using namespace std;
const int maxn = 2007;
int n, m;
int cnt;
long long maxe;
struct node {
  int from, to, val, nxt;
} edge[maxn * maxn];
int head[maxn];
long long dis[maxn][maxn];
int vis[maxn];
struct Node {
  int val, id;
  bool operator<(const Node &b) const {
    if (val == b.val) return id < b.id;
    return val > b.val;
  }
};
void init() {
  memset(head, -1, sizeof(head));
  cnt = 1;
}
void addedge(int u, int v, int w) {
  edge[cnt].from = u;
  edge[cnt].to = v;
  edge[cnt].val = w;
  edge[cnt].nxt = head[u];
  head[u] = cnt++;
}
void dijkstra(int s) {
  memset(vis, 0, sizeof(vis));
  memset(dis[s], 0x3f, sizeof(dis[s]));
  maxe = dis[s][s];
  Node now;
  priority_queue<Node> q;
  while (q.size()) q.pop();
  now.val = 0;
  now.id = s;
  dis[s][s] = 0;
  q.push(now);
  while (!q.empty()) {
    Node u = q.top();
    q.pop();
    if (vis[u.id]) continue;
    vis[u.id] = 1;
    for (int i = head[u.id]; ~i; i = edge[i].nxt) {
      int v = edge[i].to;
      if (dis[s][u.id] + edge[i].val < dis[s][v]) {
        dis[s][v] = dis[s][u.id] + edge[i].val;
        Node tmp;
        tmp.id = v;
        tmp.val = dis[s][v];
        q.push(tmp);
      }
    }
  }
}
int main() {
  scanf("%d%d", &n, &m);
  int st, ed;
  scanf("%d%d", &st, &ed);
  init();
  for (int i = 1; i <= m; i++) {
    int u, v, w;
    scanf("%d%d%d", &u, &v, &w);
    addedge(u, v, w);
    addedge(v, u, w);
  }
  for (int i = 1; i <= n; i++) {
    dijkstra(i);
  }
  init();
  for (int i = 1; i <= n; i++) {
    int t, c;
    scanf("%d%d", &t, &c);
    for (int j = 1; j <= n; j++) {
      if (i == j) continue;
      if (dis[i][j] <= t) {
        addedge(i, j, c);
      }
    }
  }
  dijkstra(st);
  if (dis[st][ed] >= 0x3f3f3f3f3f3f3f3fLL) dis[st][ed] = -1;
  cout << dis[st][ed] << endl;
  return 0;
}
