#include<iostream>
#include<vector>
#include<queue>
using namespace std;
struct node {
int u, dis;
node(int u, int dis) {
this->u = u;
this->dis = dis;
}
bool operator<(const node& a)const {
return dis > a.dis;
}
};
struct vertex {
int v, w;
vertex(int v, int w) {
this->v = v;
this->w = w;
}
};
const long long MAXSIZE(10010), INF(0x7FFFFFFFFFFFFFFF);
vector<vertex> vec[MAXSIZE * 15];
priority_queue<node> q;
long long dis[MAXSIZE * 15], N, M, K;
bool flag[MAXSIZE * 15];
void init() {
for (int i = 0; i < MAXSIZE * 15; i++) {
flag[i] = false;
dis[i] = INF;
}
}
void buildEdge(int u, int v, int w) {
for (int i = 0; i < K; i++) {
vec[u].push_back(vertex(v + N * (1 + i), 0));
vec[v].push_back(vertex(u + N * (1 + i), 0));
vec[u + N * (1 + i)].push_back(vertex(v + N * (1 + i), w));
vec[v + N * (1 + i)].push_back(vertex(u + N * (1 + i), w));
}
}
void dijkstra(int u) {
q.push(node(u, 0));
dis[u] = 0;
while (!q.empty()) {
node n = q.top();
q.pop();
if (flag[n.u]) continue;
flag[n.u] = true;
for (int i = 0; i < vec[n.u].size(); i++) {
vertex v = vec[n.u][i];
if (n.dis + v.w <= dis[v.v]) {
dis[v.v] = n.dis + v.w;
q.push(node(v.v, n.dis + v.w));
}
}
}
}
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
long long s, t, u, v, w, answer(INF);
cin >> N >> M >> K;
cin >> s >> t;
init();
while (M--) {
cin >> u >> v >> w;
vec[u].push_back(vertex(v, w));
vec[v].push_back(vertex(u, w));
buildEdge(u, v, w);
}
dijkstra(s);
for (int i = 0; i <= K; i++) {
answer = min(answer, dis[t + N * i]);
}
cout << answer;
return 0;
}