#include<bits/stdc++.h>

using namespace std;

typedef long long int64;
const int64 INF = 1LL << 58;
typedef pair< int64, pair< int, int > > Pi;

struct edge
{
  int vv, time, cost, nxt_ptr;

  bool operator<(const edge &e) const
  {
    return (time < e.time);
  }

  bool operator<(int t) const
  {
    return (time < t);
  }
};

int main()
{
  int N, M, S, G;
  vector< edge > g[100000];

  cin >> N >> M >> S >> G;
  --S, --G;

  for(int i = 0; i < M; i++) {
    int u, v, t, c;
    cin >> u >> v >> t >> c;
    --u, --v;
    g[u].push_back((edge) {v, t, c});
  }

  for(int i = 0; i < N; i++) {
    sort(begin(g[i]), end(g[i]));
  }

  for(int i = 0; i < N; i++) {
    for(auto &e : g[i]) {
      e.nxt_ptr = lower_bound(begin(g[e.vv]), end(g[e.vv]), e.time + e.cost) - begin(g[e.vv]);
    }
  }


  priority_queue< Pi, vector< Pi >, greater< Pi > > que;
  map< pair< int, int >, int64 > vv;
  que.emplace(g[S][0].time, make_pair(S, 0));
  vv[{S, 0}] = g[S][0].time;

  while(!que.empty()) {
    auto p = que.top();
    que.pop();

    int idx, now;
    tie(idx, now) = p.second;

    if(p.first > vv[{idx, now}]) continue;

    if(idx == G) {
      cout << p.first << endl;
      return (0);
    }

    if(now + 1 < g[idx].size()) {
      int64 nt = p.first + g[idx][now + 1].time - g[idx][now].time;
      if(!vv.count({idx, now + 1}) || nt < vv[{idx, now + 1}]) {
        vv[{idx, now + 1}] = nt;
        que.emplace(nt, make_pair(idx, now + 1));
      }
    }

    if(now < g[idx].size()) {
      auto &ee = g[idx][now];
      int64 nt = p.first;
      if(ee.vv != G) {
        if(ee.nxt_ptr >= g[ee.vv].size()) continue;
        nt += g[ee.vv][ee.nxt_ptr].time - (ee.time + ee.cost);
      }
      if(!vv.count({ee.vv, ee.nxt_ptr}) || nt < vv[{ee.vv, ee.nxt_ptr}]) {
        vv[{ee.vv, ee.nxt_ptr}] = nt;
        que.emplace(nt, make_pair(ee.vv, ee.nxt_ptr));
      }
    }
  }

}