#include <bits/stdc++.h>
using namespace std;
inline void err(istringstream *iss) {}
template <typename T, typename... Args>
void err(istringstream *iss, const T &$val, const Args &...args) {
  string $name;
  *iss >> $name;
  if ($name.back() == ',') $name.pop_back();
  cout << $name << " = " << $val << "; ", err(iss, args...);
}
using ll = long long;
using ull = unsigned long long;
using ld = long double;
int n, m, K, T, Q, cn;
int x, y, t[1005], c[1005];
ll d[1005][1005];
struct Node {
  int at;
  ll cost;
  bool operator<(const Node &b) const { return cost > b.cost; }
};
struct Out {
  int v, w;
};
list<Out> adj[1005];
priority_queue<Node> pq;
ll dist[1005];
int prv[1005];
void dijkstra(int src) {
  memset(dist, 63, sizeof(dist));
  dist[src] = 0, pq.push({src, 0}), prv[src] = -1;
  while (!pq.empty()) {
    Node u = pq.top();
    pq.pop();
    if (u.cost != dist[u.at]) continue;
    ll dynamicCostAddition = 0;
    for (auto &i : adj[u.at]) {
      ll os = u.cost + i.w + dynamicCostAddition;
      if (dist[i.v] > os) pq.push({i.v, dist[i.v] = os}), prv[i.v] = u.at;
    }
  }
}
int main() {
  cin.tie(NULL);
  scanf("%d%d%d%d", &n, &m, &x, &y);
  for (int i = 0; i < m; i++) {
    int u, v, w;
    scanf("%d%d%d", &u, &v, &w);
    adj[u].push_back({v, w}), adj[v].push_back({u, w});
  }
  for (int i = 1; i <= n; i++) {
    dijkstra(i);
    for (int j = 1; j <= n; j++) {
      d[i][j] = dist[j];
    }
  }
  for (int i = 1; i <= n; i++) {
    scanf("%d%d", &t[i], &c[i]);
    adj[i].clear();
    for (int j = 1; j <= n; j++) {
      if (i != j and d[i][j] <= t[i]) adj[i].push_back({j, c[i]});
    }
  }
  dijkstra(x);
  printf("%lld\n", dist[y] != dist[1005 - 1] ? dist[y] : -1);
  return 0;
}
