#pragma GCC otimize("O2")
#pragma GCC otimize("O3")
#pragma GCC otimize("O2")
#include<bits/stdc++.h>
using namespace std;
inline int qr() {
int f = 0, fu = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-')fu = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
f = (f << 3) + (f << 1) + c - 48;
c = getchar();
}
return f * fu;
}
const int N = 1e3 + 10, M = 1e5 + 10;
struct Leftist_Tree {
int tot, rt[N];
struct node {
int dis, lc, rc, x, val;
} t[N * 45];
Leftist_Tree() { t[0].dis = -1; }
inline int merge(int x, int y) {
if (!x || !y)return x | y;
if (t[x].val > t[y].val)swap(x, y);
int p = ++tot;
t[p] = t[x], t[p].rc = merge(t[x].rc, y);
if (t[t[p].lc].dis < t[t[p].rc].dis)swap(t[p].lc, t[p].rc);
t[p].dis = t[t[p].rc].dis + 1;
return p;
}
inline void insert(int &p, int x, int v) {
++tot, t[tot] = {0, 0, 0, x, v};
p = merge(p, tot);
}
} L;
struct Kth_Path {
int n, m, S, T, K;
int head[N], ver[M], edge[M], Next[M], tot;
int rh[N], rv[M], re[M], rn[M], rt;
int d[N], fa[N];
bool v[N], vis[N], ot[M];
inline void add(int x, int y, int z) {
ver[++tot] = y;
edge[tot] = z;
Next[tot] = head[x];
head[x] = tot;
}
inline void add_r(int x, int y, int z) {
rv[++rt] = y;
re[rt] = z;
rn[rt] = rh[x];
rh[x] = rt;
}
struct node {
int x, v;
inline bool operator<(node a) const {
return v > a.v;
}
};
inline void dijkstra() {
memset(d, 0x3f, sizeof(int) * (n + 1));
memset(vis, false, sizeof(bool) * (n + 1));
priority_queue<node> q;
d[T] = 0;
q.push({T, 0});
while (!q.empty()) {
int x = q.top().x;
q.pop();
if (vis[x])continue;
vis[x] = true;
for (int i = rh[x]; i; i = rn[i]) {
int y = rv[i], z = re[i];
if (d[y] > d[x] + z)d[y] = d[x] + z, q.push({y, d[y]});
}
}
}
inline void init() {
tot = rt = 0;
memset(head, 0, sizeof(int) * (n + 1));
memset(rh, 0, sizeof(int) * (n + 1));
}
inline void bfs1() {
queue<int> q;
memset(ot, false, sizeof(bool) * (m + 1));
memset(v, false, sizeof(bool) * (n + 1));
v[T] = true, q.push(T);
while (!q.empty()) {
int x = q.front();
q.pop();
for (int i = rh[x]; i; i = rn[i]) {
int y = rv[i], z = re[i];
if (v[y] || d[y] != d[x] + z)continue;
fa[y] = x, v[y] = ot[i] = true, q.push(y);
}
}
}
inline void bfs2() {
queue<int> q;
memset(v, false, sizeof(bool) * (n + 1));
v[T] = true, q.push(T);
while (!q.empty()) {
int x = q.front();
q.pop();
if (fa[x])L.rt[x] = L.merge(L.rt[x], L.rt[fa[x]]);
for (int i = rh[x]; i; i = rn[i])
if (ot[i] && !v[rv[i]])v[rv[i]] = true, q.push(rv[i]);
}
}
inline int solve() {
n = qr(), m = qr(), init();
for (int i = 1; i <= m; i++) {
int x = qr(), y = qr(), z = qr();
add(x, y, z), add_r(y, x, z);
}
S = qr(), T = qr(), K = qr();
if (S == T)K++;
dijkstra();
if (!vis[S])return -1;
if (K == 1)return d[S];
bfs1();
for (int x = 1; x <= n; x++) {
if (!vis[x])continue;
for (int i = head[x]; i; i = Next[i])
if (!ot[i] && vis[ver[i]])
L.insert(L.rt[x], ver[i], d[ver[i]] + edge[i] - d[x]);
}
bfs2();
priority_queue<node> q;
if (L.rt[S])q.push({L.rt[S], d[S] + L.t[L.rt[S]].val});
K--;
while (!q.empty()) {
node t = q.top();
q.pop();
if (!--K)return t.v;
if (L.t[t.x].lc)q.push({L.t[t.x].lc, t.v - L.t[t.x].val + L.t[L.t[t.x].lc].val});
if (L.t[t.x].rc)q.push({L.t[t.x].rc, t.v - L.t[t.x].val + L.t[L.t[t.x].rc].val});
if (L.rt[L.t[t.x].x])q.push({L.rt[L.t[t.x].x], t.v + L.t[L.rt[L.t[t.x].x]].val});
}
return -1;
}
} K;
int main() {
printf("%d\n", K.solve());
return 0;
}