#include <bits/stdc++.h>
using namespace std;
template <class T, class U>
void maximize(T &x, U y) {
  if (x < y) x = y;
}
template <class T, class U>
void minimize(T &x, U y) {
  if (x > y) x = y;
}
template <class T>
T Abs(T x) {
  return (x < 0 ? -x : x);
}
template <class T>
T safe_sqrt(T x) {
  return sqrt(max(x, (T)0));
}
template <class T, class U, class V>
T addmod(T x, U k, V __base) {
  return ((x + k) % __base + __base) % __base;
}
template <class T, class U, class V>
T submod(T x, U k, V __base) {
  return ((x - k) % __base + __base) % __base;
}
template <class T, class U, class V>
T mul(T x, U y, V __base) {
  return (long long)x * y % __base;
}
namespace taskC {
const int N = 1e3 + 3;
const long long inf = 1e18;
vector<pair<int, int> > adj[2][N];
vector<long long> dist;
int t[N], c[N];
int n, m, s, des;
void loadGr() {
  scanf("%d%d%d%d", &n, &m, &s, &des);
  for (int u, v, c, i = 1; i <= m; i++) {
    scanf("%d%d%d", &u, &v, &c);
    adj[0][u].push_back(make_pair(v, c));
    adj[0][v].push_back(make_pair(u, c));
  }
  for (int i = 1; i <= n; i++) scanf("%d%d", &t[i], &c[i]);
}
set<pair<long long, int> > heap;
void dijkstra(int k, int src) {
  dist.assign(n + 5, inf);
  dist[src] = 0;
  heap.insert(make_pair(dist[src], src));
  while (!heap.empty()) {
    pair<long long, int> top = *heap.begin();
    heap.erase(heap.begin());
    int u = top.second;
    for (auto edge : adj[k][u]) {
      int v = edge.first, c = edge.second;
      if (dist[v] > dist[u] + 1ll * c) {
        if (dist[v] != inf) heap.erase(make_pair(dist[v], v));
        dist[v] = dist[u] + 1ll * c;
        heap.insert(make_pair(dist[v], v));
      }
    }
  }
}
long long solve() {
  loadGr();
  for (int i = 1; i <= n; i++) {
    dijkstra(0, i);
    for (int j = 1; j <= n; j++)
      if (i != j and dist[j] <= t[i]) adj[1][i].push_back(make_pair(j, c[i]));
  }
  dijkstra(1, s);
  return (dist[des] == inf ? -1ll : dist[des]);
}
}  // namespace taskC
int main(void) { printf("%I64d", taskC::solve()); }
