#include <bits/stdc++.h>
using std::cin;
using std::cout;
using std::fill;
using std::make_pair;
using std::pair;
using std::set;
using std::vector;
const unsigned long long MAX_COST = (unsigned long long)-1;
struct MyPriorityQueue {
  void add(pair<unsigned long long, unsigned short> const& qe) {
    _queue.insert(qe);
  }
  void add(unsigned long long d, unsigned short v) {
    _queue.insert(make_pair(d, v));
  }
  void decrease_key(unsigned short const v, unsigned long long const old_key,
                    unsigned long long const new_key) {
    _queue.erase(make_pair(old_key, v));
    _queue.insert(make_pair(new_key, v));
  }
  pair<unsigned long long, unsigned short> const& extract_min() {
    pair<unsigned long long, unsigned short> qe = *_queue.begin();
    _queue.erase(_queue.begin());
    return qe;
  }
  bool is_not_empty() { return !_queue.empty(); }

 private:
  set<pair<unsigned long long, unsigned short> > _queue;
};
void dijkstra(
    vector<vector<pair<unsigned short, unsigned long long> > > const& graph,
    unsigned short const s, vector<unsigned long long>& distances) {
  MyPriorityQueue queue;
  fill(distances.begin(), distances.end(), MAX_COST);
  distances[s] = 0;
  queue.add(0, s);
  while (queue.is_not_empty()) {
    unsigned short u = queue.extract_min().second;
    for (size_t i = 0; i != graph[u].size(); ++i) {
      unsigned short v = graph[u][i].first;
      unsigned long long length = graph[u][i].second;
      unsigned long long old_distance = distances[v];
      unsigned long long new_distance = distances[u] + length;
      if (old_distance > new_distance) {
        distances[v] = new_distance;
        queue.decrease_key(v, old_distance, new_distance);
      }
    }
  }
}
int main() {
  unsigned short n;
  unsigned short m;
  cin >> n >> m;
  unsigned short x;
  unsigned short y;
  cin >> x >> y;
  if (x == y) {
    cout << "0\n";
  } else {
    if (m == 0) {
      cout << "-1\n";
    } else {
      vector<vector<pair<unsigned short, unsigned long long> > > graph(n);
      for (size_t i = 0; i != m; ++i) {
        unsigned short u, v;
        unsigned long long w;
        cin >> u >> v >> w;
        graph[u - 1].push_back(make_pair(v - 1, w));
        graph[v - 1].push_back(make_pair(u - 1, w));
      }
      vector<pair<unsigned long long, unsigned long long> > drivers;
      for (size_t i = 0; i != n; ++i) {
        unsigned long long t;
        unsigned long long c;
        cin >> t >> c;
        drivers.push_back(make_pair(t, c));
      }
      vector<vector<pair<unsigned short, unsigned long long> > > routes(n);
      vector<unsigned long long> distances(n);
      for (unsigned short v = 0; v != n; ++v) {
        dijkstra(graph, v, distances);
        for (unsigned short i = 0; i != n; ++i) {
          if (distances[i] <= drivers[v].first) {
            routes[v].push_back(make_pair(i, drivers[v].second));
          }
        }
      }
      dijkstra(routes, x - 1, distances);
      if (distances[y - 1] == MAX_COST) {
        cout << "-1\n";
      } else {
        cout << distances[y - 1] << "\n";
      }
    }
  }
  return 0;
}
