#include <cstring>
#include <iostream>
#include <algorithm>
#include <deque>
using namespace std;
const int N = 1010, M = 20010;
int n, m, k;
int head[N], e[M], ne[M], w[M], idx;
int dist[N];
deque<int> q;
bool st[N];
void add(int a, int b, int c) {
e[idx] = b;
w[idx] = c;
ne[idx] = head[a];
head[a] = idx ++;
}
// 双端队列BFS
// 是否存在一条路径使得这条路径花费超过x的电线数小于等于k
bool check(int bound) {
memset(dist, 0x3f, sizeof dist);
memset(st, 0, sizeof st);
q.push_back(1);
dist[1] = 0;
while (q.size()) {
// 为什么要用双端队列,因为bfs只能处理边权为1的情况
// 如果边权>1,那么就要离他最近的点就不一定是他的邻点了
// 用双端队列(相当于堆),把边权为0的放在前面(近)
// 把边权为1的点放在后面(远)
// bfs是找最近的点,而这题边权只有0和1,那么刚好,不需要堆(nlog(n))
// 直接用deque (1)
int t = q.front();
q.pop_front();
if (st[t]) continue;
st[t] = true;
// 将边权>x的点权值设为1,边权小于x的点权值设为0
// 统计一下从1点到达n点的最短路径有多少条权值大于x的电线
// dist[n] 存储的就是点1到点n最少有多少条边权大于x的电线
for (int i = head[t]; i != -1; i = ne[i]) {
int j = e[i], x = w[i] > bound;
if (dist[j] > dist[t] + x) {
dist[j] = dist[t] + x;
if (!x) q.push_front(j); // 如果是小于x的边,可以多用,反正免费
else q.push_back(j); // 如果是大于x的边,那就往后稍稍
}
}
}
return dist[n] <= k; // 如果不超过限制,那么OK,可以取这个x
}
// 最短路跟二分结合
// 一条路径的权值被定义为第 k + 1大值
int main() {
cin >> n >> m >> k;
memset(head, -1, sizeof head);
while (m --) {
int a, b, c;
cin >> a >> b >> c;
add(a, b, c);
add(b, a, c);
}
// 将花费二分,求一个限定条件下的最小值
// 左端点为0,是因为答案是有可能为0的(花费为0)
// 右端点为 1e6 + 1 而不是 1e6
// 由于1~N不一定是连通的,如果不连通,那么二分的时候一定会分到1e6
// 如果连通的话,x也有可能取1e6,所以如果返回1e6的话是无法确定x到底是无解
// 还是说解为1e6,所以右端点取1e6 + 1
int l = 0, r = 1e6 + 1;
while (l < r) {
int mid = l + r >> 1;
if (check(mid)) r = mid; // x满足条件, x给高了,还能再减点
else l = mid + 1; // x给少了,高过x的电线还是太多了(>k),要添点
}
if (r == 1e6 + 1) cout << -1 << endl;
else cout << r << endl;
return 0;
}