#include <bits/stdc++.h>
using namespace std;
struct dt {
  int pos;
  long long distance;
};
bool operator<(const struct dt &a, const struct dt &b) {
  if (a.distance == b.distance) return a.pos > b.pos;
  return a.distance > b.distance;
}
int main() {
  int n, m, x, y, ui, vi;
  long long wi, ti, ci, res;
  bool visited[1010];
  vector<dt> road[1010];
  vector<dt> newRoad[1010];
  long long time[1010];
  long long cost[1010];
  priority_queue<dt> pq1;
  priority_queue<dt> pq2;
  scanf("%d %d", &n, &m);
  scanf("%d %d", &x, &y);
  x--;
  y--;
  for (int i = 0; i < m; i++) {
    scanf("%d %d %I64d", &ui, &vi, &wi);
    ui--;
    vi--;
    road[ui].push_back((dt){vi, wi});
    road[vi].push_back((dt){ui, wi});
  }
  for (int i = 0; i < n; i++) {
    scanf("%I64d %I64d", &ti, &ci);
    time[i] = ti;
    cost[i] = ci;
  }
  for (int i = 0; i < n; i++) {
    memset(visited, false, sizeof(visited));
    pq1.push((dt){i, 0});
    while (!pq1.empty()) {
      dt top = pq1.top();
      pq1.pop();
      if (visited[top.pos]) continue;
      visited[top.pos] = true;
      if (i != top.pos) {
        newRoad[i].push_back((dt){top.pos, top.distance});
      }
      for (int j = 0; j < road[top.pos].size(); j++) {
        pq1.push((dt){road[top.pos][j].pos,
                      top.distance + road[top.pos][j].distance});
      }
    }
  }
  bool ok = false;
  memset(visited, false, sizeof(visited));
  pq2.push((dt){x, 0});
  while (!pq2.empty()) {
    dt top = pq2.top();
    pq2.pop();
    if (visited[top.pos]) continue;
    visited[top.pos] = true;
    if (top.pos == y) {
      ok = true;
      res = top.distance;
      break;
    }
    for (int j = 0; j < newRoad[top.pos].size(); j++) {
      if (newRoad[top.pos][j].distance <= time[top.pos]) {
        pq2.push((dt){newRoad[top.pos][j].pos, top.distance + cost[top.pos]});
      }
    }
  }
  if (!ok) {
    printf("-1\n");
  } else {
    printf("%I64d\n", res);
  }
  return 0;
}
