#include <bits/stdc++.h>
#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector")
using namespace std;
const int N = 1005;
const long long inf = 4e18;
struct Edge {
  int v;
  long long dist;
};
struct Taxi {
  long long dist, cost;
} taxi[N];
vector<Edge> graph[N];
long long dist[N][N];
int n, m;
int second, t;
void dijkstra(int second, long long dist[]) {
  for (auto u = (1) - ((1) > (n + 1)); u != n + 1 - ((1) > (n + 1));
       u += 1 - 2 * ((1) > (n + 1)))
    dist[u] = inf;
  priority_queue<pair<long long, int> > pq;
  pq.emplace(dist[second] = 0, second);
  while (!pq.empty()) {
    long long d = -pq.top().first;
    int u = pq.top().second;
    pq.pop();
    for (Edge &e : graph[u])
      if (dist[u] + e.dist < dist[e.v]) {
        dist[e.v] = dist[u] + e.dist;
        pq.emplace(-dist[e.v], e.v);
      }
  }
}
long long mem[N];
bool vis[N], done[N];
long long dfs(int u) {
  if (u == t) return 0LL;
  long long &mn = mem[u];
  if (!done[u]) {
    done[u] = 1;
    mn = inf;
    for (auto v = (1) - ((1) > (n + 1)); v != n + 1 - ((1) > (n + 1));
         v += 1 - 2 * ((1) > (n + 1)))
      if (!vis[v]) {
        if (dist[u][v] <= taxi[u].dist) {
          vis[v] = 1;
          mn = min(mn, dfs(v) + taxi[u].cost);
          vis[v] = 0;
        }
      }
  }
  return mn;
}
int main() {
  cin.tie(0)->sync_with_stdio(0), cout.tie(0);
  cin >> n >> m >> second >> t;
  for (auto i = (0) - ((0) > (m)); i != m - ((0) > (m));
       i += 1 - 2 * ((0) > (m))) {
    int u, v;
    long long dist;
    cin >> u >> v >> dist;
    graph[u].push_back({v, dist});
    graph[v].push_back({u, dist});
  }
  for (auto u = (1) - ((1) > (n + 1)); u != n + 1 - ((1) > (n + 1));
       u += 1 - 2 * ((1) > (n + 1))) {
    cin >> taxi[u].dist >> taxi[u].cost;
    dijkstra(u, dist[u]);
  }
  vis[second] = 1;
  long long mn = dfs(second);
  if (mn == inf) mn = -1;
  cout << mn << '\n';
  return 0;
}
