using System; using static System.Console; using System.Linq; using System.Collections.Generic; class Program { static int NN => int.Parse(ReadLine()); static int[] NList => ReadLine().Split().Select(int.Parse).ToArray(); static int[][] NArr(long n) => Enumerable.Repeat(0, (int)n).Select(_ => NList).ToArray(); public static void Main() { Solve(); } static void Solve() { var c = NList; var (n, m, k, s, t) = (c[0], c[1], c[2], c[3], c[4]); var map = NArr(m); var list = new List<(int from, int to)>[n - 1]; for (var i = 0; i < n - 1; ++i) list[i] = new List<(int from, int to)>(); foreach (var edge in map) { list[edge[0] - 1].Add((edge[1], edge[2])); } var clist = new List<(int f, long l)> { (s, 0) }; for (var i = 0; i + 1 < n; ++i) { var nclist = new List<(int f, long l)>(); if (list[i].Count == 0) { WriteLine(-1); return; } if (clist.Count * list[i].Count < 200) { foreach (var li in list[i]) { var min = long.MaxValue; foreach (var ci in clist) { min = Math.Min(min, ci.l + Math.Abs(ci.f - li.from)); } nclist.Add((li.to, min)); } } else { var plist = new List(clist.Count); var lseg = new AtCoder.Segtree(clist.Count); var rseg = new AtCoder.Segtree(clist.Count); for (var j = 0; j < clist.Count; ++j) { plist.Add(clist[j].f); lseg[j] = clist[j].l + clist[j].f; rseg[j] = clist[j].l + k - clist[j].f; } foreach (var li in list[i]) { var pos = LowerBound(0, li.from, plist); nclist.Add((li.to, Math.Min(lseg.Prod(pos, clist.Count) - li.from, rseg.Prod(0, pos) - k + li.from))); } } clist = nclist; } var ans = long.MaxValue; foreach (var ci in clist) ans = Math.Min(ans, ci.l + Math.Abs(t - ci.f)); WriteLine(ans); } static int LowerBound(int left, int min, IList list) { if (list[left] >= min) return left; var ng = left; var ok = list.Count; while (ok - ng > 1) { var mid = (ng + ok) / 2; if (list[mid] < min) ng = mid; else ok = mid; } return ok; } struct SegOp : AtCoder.ISegtreeOperator { public long Identity => long.MaxValue; public long Operate(long x, long y) { return Math.Min(x, y); } } }