Problem:
Problem G:
Test Case Tweaking
You are a judge of a programming contest. You are preparing a dataset for a graph problem to seek for the cost of the minimum cost path. You've generated some random cases, but they are not interesting. You want to produce a dataset whose answer is a desired value such as the number representing this year 2010. So you will tweak (which means 'adjust') the cost of the minimum cost path to a given value by changing the costs of some edges. The number of changes should be made as few as possible.
A non-negative integer c and a directed graph
G
are given. Each edge of
G
is associated with a cost of a non-negative integer. Given a path from one node of
G
to another, we can define the cost of the path as the sum of the costs of edges constituting the path. Given a pair of nodes in
G
, we can associate it with a non-negative cost which is the minimum of the costs of paths connecting them.
Given a graph and a pair of nodes in it, you are asked to adjust the costs of edges so that the minimum cost path from one node to the other will be the given target cost
c
. You can assume that
c
is smaller than the cost of the minimum cost path between the given nodes in the original graph.
For example, in Figure G.1, the minimum cost of the path from node 1 to node 3 in the given graph is 6. In order to adjust this minimum cost to 2, we can change the cost of the edge from node 1 to node 3 to 2. This direct edge becomes the minimum cost path after the change.
For another example, in Figure G.2, the minimum cost of the path from node 1 to node 12 in the given graph is 4022. In order to adjust this minimum cost to 2010, we can change the cost of the edge from node 6 to node 12 and one of the six edges in the right half of the graph. There are many possibilities of edge modification, but the minimum number of modified edges is 2.
Input
The input is a sequence of datasets. Each dataset is formatted as follows.
n m c
f
1
t
1
c
1
f
2
t
2
c
2
.
.
.
f
m
t
m
c
m
Figure G.1: Example 1 of graph
Figure G.2: Example 2 of graph
The integers
n
,
m
and
c
are the number of the nodes, the number of the edges, and the target cost, respectively, each separated by a single space, where 2 ≤
n
≤ 100, 1 ≤
m
≤ 1000 and 0 ≤
c
≤ 100000.
Each node in the graph is represented by an integer 1 through
n
.
The following
m
lines represent edges: the integers
f
i
,
t
i
and
c
i
(1 ≤
i
≤
m
) are the originating node, the destination node and the associated cost of the
i
-th edge, each separated by a single space. They satisfy 1 ≤
f
i
,
t
i
≤
n
and 0 ≤
c
i
≤ 10000. You can assume that
f
i
≠
t
i
and (
f
i
,
t
i
) ≠ (
f
j
,
t
j
) when
i
≠
j
.
You can assume that, for each dataset, there is at least one path from node 1 to node
n
, and that the cost of the minimum cost path from node 1 to node
n
of the given graph is greater than
c
.
The end of the input is indicated by a line containing three zeros separated by single spaces.
Output
For each dataset, output a line containing
...(truncated)

Submitted solutions:

code_snippet: /* ***********************************************
Author        :kuangbin
Created Time  :2013/11/15 16:30:39
File Name     :G.cpp
************************************************ */

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int INF = 0x3f3f3f3f;
struct Edge
{
	int to,next;
	int w;
}edge[20010];
int head[110];
int tot;
void addedge(int u,int v,int w)
{
	edge[tot].to = v;
	edge[tot].next = head[u];
	edge[tot].w = w;
	head[u] = tot++;
}

void init()
{
	tot = 0;
	memset(head,-1,sizeof(head));
}
int dp[110][1010];
int n,m;
bool vis[110][1010];
void SPFA(int s)
{
	queue<pair<int,int> >q;
	q.push(make_pair(s,0));
	for(int i = 1;i <= n;i++)
		for(int j = 0;j < 1010;j++)
			dp[i][j] = INF;
	memset(vis,false,sizeof(vis));
	dp[s][0] = 0;
	vis[s][0] = true;
	while(!q.empty())
	{
		pair<int,int> tmp = q.front();
		int u = tmp.first;
		int k = tmp.second;
		//printf("%d %d\n",u,k);
		q.pop();
		vis[u][k] = false;
		for(int i = head[u];i != -1;i = edge[i].next)
		{
			int v = edge[i].to;
			//cout<<v<<endl;
		//	printf("%d %d\n",dp[v][k],dp[u][k] + edge[i].w);

			if(dp[v][k] > dp[u][k] + edge[i].w)
			{
			//	cout<<"*"<<endl;
				dp[v][k] = dp[u][k] + edge[i].w;
				if(!vis[v][k])
				{
					q.push(make_pair(v,k));
					vis[v][k] = true;
				}
			}

			if(k < m &&  dp[v][k+1] > dp[u][k] )
			{
				dp[v][k+1] = dp[u][k] ;
				if(!vis[v][k+1])
				{
					q.push(make_pair(v,k+1));
					vis[v][k+1] = true;
				}
			}
		}
	}
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int c;
	while(scanf("%d%d%d",&n,&m,&c) == 3)
	{
		if(n == 0 && m == 0 && c == 0)break;
		init();
		int u,v,w;
		for(int i = 0;i < m;i++)
		{
			scanf("%d%d%d",&u,&v,&w);
			addedge(u,v,w);
		}
		SPFA(1);
	//	for(int i = 1;i <= n;i++)
	//		for(int j = 0;j <= m;j++)
	//			printf(" %d %d %d\n",i,j,dp[i][j]);
		int ans = m ;
		for(int i = 0;i <= m;i++)
			if(dp[n][i] <= c)
			{
				ans = i;
				break;
			}
		cout<<ans<<endl;
	}
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3916
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    int n, m, C;
    cin >> n >> m >> C;
    while(n) {
        int inf = 1 << 30;
        vector dis(n, vector(m + 1, inf));
        vector<vector<pair<int, int>>> v(n);
        rep(i, m) {
            int a, b, c; cin >> a >> b >> c;
            a --; b --;
            v[a].push_back({b, c});
        }
        dis[0][0] = 0;
        multiset<tuple<int, int, int>> ms;
        ms.insert({0, 0, 0});
        while(!ms.empty()) {
            auto [d, now, k] = *ms.begin();
            ms.erase(ms.begin());
            for(auto [to, cost] : v[now]) {
                if(dis[to][k] > d + cost) {
                    dis[to][k] = d + cost;
                    ms.insert({dis[to][k], to, k});
                }
                if(k < m and dis[to][k + 1] > d) {
                    dis[to][k + 1] = d;
                    ms.insert({dis[to][k + 1], to, k + 1});
                }
            }
        }
        int ans = inf;
        rep(i, m + 1) if(dis[n - 1][i] <= C) ans = min(ans, i);
        cout << ans << endl; 
        cin >> n >> m >> C;
    }

    return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 10088
final_rank: 15

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
while(1) {
    int N, M, K;
    cin >> N >> M >> K;
    if (N == 0) return 0;
    vector<vector<int>> G(N);
    vector<int> A(M), B(M), C(M);
    rep(i,0,M) {
        cin >> A[i] >> B[i] >> C[i];
        A[i]--, B[i]--;
        G[A[i]].push_back(i);
    }
    vector<vector<int>> DP(N,vector<int>(N+1,inf));
    priority_queue<pair<int,pair<int,int>>,vector<pair<int,pair<int,int>>>,greater<pair<int,pair<int,int>>>> PQ;
    DP[0][0] = 0;
    PQ.push({0,{0,0}});
    while(!PQ.empty()) {
        auto [D,P] = PQ.top();
        auto [V,X] = P;
        PQ.pop();
        if (D > DP[V][X]) continue;
        for (int i : G[V]) {
            int NV = B[i], Cost = C[i];
            if (chmin(DP[NV][X],DP[V][X]+Cost)) {
                PQ.push({DP[NV][X],{NV,X}});
            }
            if (X < N) {
                if (chmin(DP[NV][X+1],DP[V][X])) {
                    PQ.push({DP[NV][X+1],{NV,X+1}});
                }
            }
        }
    }
    int ANS = inf;
    rep(i,0,N+1) {
        if (DP[N-1][i] <= K) chmin(ANS,i);
    }
    cout << ANS << endl;
}
}
accuracy: 1
time_ms: 40
memory_kb: 3676
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define rep(i, a, b) for(ll i = a; i < b; ++i)
#define rrep(i, a, b) for(ll i = a; i >= b; --i)
constexpr ll inf = 4e18;
struct SetupIO {
    SetupIO() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout << fixed << setprecision(30);
    }
} setup_io;
template <typename T = int>
struct Edge {
    int from, to;
    T cost;
    int idx;
    Edge()
        : from(-1), to(-1), cost(-1), idx(-1) {}
    Edge(int from, int to, T cost = 1, int idx = -1)
        : from(from), to(to), cost(cost), idx(idx) {}
    operator int() const {
        return to;
    }
};
template <typename T = int>
struct Graph {
    Graph(int N)
        : n(N), es(0), g(N) {}
    int size() const {
        return n;
    }
    int edge_size() const {
        return es;
    }
    void add_edge(int from, int to, T cost = 1) {
        assert(0 <= from and from < n);
        assert(0 <= to and to < n);
        g[from].emplace_back(from, to, cost, es);
        g[to].emplace_back(to, from, cost, es++);
    }
    void add_directed_edge(int from, int to, T cost = 1) {
        assert(0 <= from and from < n);
        assert(0 <= to and to < n);
        g[from].emplace_back(from, to, cost, es++);
    }
    inline vector<Edge<T>>& operator[](const int& k) {
        assert(0 <= k and k < n);
        return g[k];
    }
    inline const vector<Edge<T>>& operator[](const int& k) const {
        assert(0 <= k and k < n);
        return g[k];
    }

   private:
    int n, es;
    vector<vector<Edge<T>>> g;
};
template <typename T = int>
using Edges = vector<Edge<T>>;
template <typename T>
vector<pair<T, int>> dijkstra(const Graph<T>& g, const int s = 0) {
    int n = g.size();
    assert(0 <= s and s < n);
    vector<pair<T, int>> d(n, {numeric_limits<T>::max(), -1});
    priority_queue<pair<T, int>, vector<pair<T, int>>, greater<pair<T, int>>> pq;
    d[s] = {0, -1};
    pq.push({0, s});
    while(!pq.empty()) {
        pair<T, int> p = pq.top();
        pq.pop();
        T dist = p.first;
        int cur = p.second;
        if(d[cur].first < dist) continue;
        for(const Edge<T>& edge : g[cur]) {
            if(d[edge.to].first > d[cur].first + edge.cost) {
                d[edge.to] = {d[cur].first + edge.cost, cur};
                pq.push({d[edge.to].first, edge.to});
            }
        }
    }
    return d;
}
int main(void) {
    while(true) {
        int n, m, c;
        cin >> n >> m >> c;
        if(n == 0 and m == 0 and c == 0) break;
        Graph<int> g(n * (m + 1));
        rep(i, 0, m) {
            int f, t, w;
            cin >> f >> t >> w;
            f--;
            t--;
            rep(j, 0, m) {
                g.add_directed_edge(f * (m + 1) + j, t * (m + 1) + j + 1, 0);
            }
            rep(j, 0, m + 1) {
                g.add_directed_edge(f * (m + 1) + j, t * (m + 1) + j, w);
            }
        }
        vector<pair<int, int>> d = dijkstra(g);
        int ans = m;
        rep(i, 0, m + 1) {
            if(d[(n - 1) * (m + 1) + i].first <= c) {
                ans = i;
                break;
            }
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 790
memory_kb: 56420
final_rank: 20

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

} // namespace macro

using namespace macro;
#line 1 "cp-library/src/graph/shortest_path.hpp"
// g <- pair < v , cost > 
template < class T >
vector< T > dijkstra(vector<vector<pair<int, T>>> &graph, int s) {
    T INF = numeric_limits< T >::max();
    vector<T> dist(graph.size(), INF);
    priority_queue<pair<T,int>, vector<pair<T,int>>, greater<pair<T,int>>> q;
    q.push({dist[s] = T(0), s});
    while(!q.empty()){
        auto [uc, ui] = q.top(); q.pop();
        if(uc != dist[ui]) continue;
        for(auto [vi, vc] : graph[ui]) if(dist[vi] > uc + vc) 
            q.push({dist[vi] = uc + vc, vi});
    }
    return dist;
}

// g <- pair < v , cost > 
template < class T >
vector< T > dijkstra(vector<vector<pair<int, T>>> &graph, vector<int> &starts) {
    T INF = numeric_limits< T >::max();
    vector<T> dist(graph.size(), INF);
    priority_queue<pair<T,int>, vector<pair<T,int>>, greater<pair<T,int>>> q;
    for(int s : starts) q.push({dist[s] = T(0), s});
    while(!q.empty()){
        auto [uc, ui] = q.top(); q.pop();
        if(uc != dist[ui]) continue;
        for(auto [vi, vc] : graph[ui]) if(dist[vi] > uc + vc) 
            q.push({dist[vi] = uc + vc, vi});
    }
    return dist;
}

// g <- pair < v , cost > 
template < class T >
pair< T, vector<int> > shortest_path(vector<vector<pair<int, T>>> &graph, int s, int t) {
    T INF = numeric_limits< T >::max();
    vector<T> dist(graph.size(), INF);
    vector<int> prev(graph.size(), -1);
    priority_queue<pair<T,int>, vector<pair<T,int>>, greater<pair<T,int>>> q;
    q.push({dist[s] = T(0), s});
    while(!q.empty()){
        auto [uc, ui] = q.top(); q.pop();
        if(uc != dist[ui]) continue;
        for(auto [vi, vc] : graph[ui]) if(dist[vi] > uc + vc) 
            q.push({dist[vi] = uc + vc, vi}), prev[vi] = ui;
    }

    vector<int> path;
    if(dist[t] != INF) {
        for(int v = t; v != -1; v = prev[v]) path.push_back(v);
        reverse(path.begin(), path.end());
    }
    return {dist[t], path};
}
#line 4 "A.cpp"

int solve(int n, int m, int target_cost) {
    vector<vector<pair<int,int>>> g(n * (m + 1));
    auto h = [&](int v, int e) { return v * (m + 1) + e; };
    for(int _ : rep(m)) {
        int f = in(), t = in(), c = in(); f--, t--;
        for(int e = 0; e <= m; e++) {
            g[h(f, e)].push_back({h(t, e), c});
            if(e + 1 <= m)
                g[h(f, e)].push_back({h(t, e + 1), 0});
        }
    }

    vector<int> dist = dijkstra(g, h(0, 0));
    for(int e = 0; e <= m; e++) {
        if(dist[h(n - 1, e)] <= target_cost) {
            return e;
        }
    }

    assert(0);
}

int main() {
    while(true) {
        int n = in(), m = in(), c = in();
        if(make_tuple(n, m, c) == make_tuple(0, 0, 0)) return 0;
        print(solve(n, m, c));
    }
}
accuracy: 1
time_ms: 600
memory_kb: 33568
final_rank: 17

code_snippet: #include<bits/stdc++.h>

using namespace std;

#define rep(i, n) for(int i = 0; i < (n); i++)
#define per(i, n) for(int i = (n)-1; i >= 0; i--)
#define rep2(i, l, r) for(int i = (l); i < (r); i++)
#define per2(i, l, r) for(int i = (r)-1; i >= (l); i--)
#define each(e, x) for(auto &e : x)
#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define eb emplace_back
#define MM << ' ' <<
#define TT template<typename T>
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

TT bool chmin(T &x, T y) { return x > y ? (x = y, true) : false; }

TT bool chmax(T &x, T y) { return x < y ? (x = y, true) : false; }

TT using minheap = priority_queue<T, vector<T>, greater<T>>;
TT using maxheap = priority_queue<T>;

TT void print(vector<T> v, T x = 0) {
    int n = sz(v);
    rep(i, n) cout << v[i] + x << (i == n - 1 ? '\n' : ' ');
    if (n == 0) cout << '\n';
}

TT void printn(vector<T> v, T x = 0) {
    int n = sz(v);
    rep(i, n) cout << v[i] + x << '\n';
}

TT void rearrange(vector<T> &v) {
    sort(all(v));
    v.erase(unique(all(v)), end(v));
}

TT int lb(vector<T> &v, T x) { return lower_bound(all(v), x) - begin(v); }

TT int ub(vector<T> &v, T x) { return upper_bound(all(v), x) - begin(v); }

const int inf = (1 << 30) - 1;
const ll INF = (1LL << 60) - 1;

struct io_setup {
    io_setup() {
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        cout << fixed << setprecision(15);
    }
} io_setup;

int main() {
    while (1) {
        int n, m, c;
        cin >> n >> m >> c;
        if (!n)
            break;
        vector<vector<pii>> g(n);
        rep(i, m) {
            int u, v, w;
            cin >> u >> v >> w;
            u--, v--;
            g[u].eb(v, w);
        }
        vector<vector<int>> d(n, vector<int>(n, 1e9));
        minheap<pair<int, pii>> que;
        d[0][0] = 0, que.emplace(0, pair(0, 0));
        while (sz(que)) {
            auto [nd, ij] = que.top();
            que.pop();
            auto [ni, nj] = ij;
            if (nd != d[ni][nj])
                continue;
            for (auto [e, cost] : g[ni]) {
                if (chmin(d[e][nj], nd + cost))
                    que.emplace(nd + cost, pair(e, nj));
                if (nj + 1 < n && chmin(d[e][nj + 1], nd))
                    que.emplace(nd, pair(e, nj + 1));
            }
        }
        rep(j, n) {
            if (d[n - 1][j] <= c) {
                cout << j << '\n';
                break;
            }
        }
    }
}
accuracy: 1
time_ms: 30
memory_kb: 3440
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;

template<class T>
bool chmin(T &a, const T b) {if (a > b) {a = b; return 1;} return 0;}

template<class T>
bool chmax(T &a, const T b) {if (a < b) {a = b; return 1;} return 0;}

bool is_end = false;

struct edge
{
	ll to, cost;
	
	edge() = default;
	edge(ll t, ll c) : to(t), cost(c) { }
};

void calc()
{
	ll N, M, C; cin >> N >> M >> C;
	
	if (N == 0)
	{
		is_end = true;
		return;
	}
	
	vector<vector<edge>> G(N);
	for (int i = 0; i < M; ++i)
	{
		ll f, t, c; cin >> f >> t >> c;
		f--, t--;
		G[f].emplace_back(edge(t, c));
	}
	
	const ll INF = 1e18;
	vector<vector<ll>> dist(N, vector<ll>(M+1, INF));
	dist[0][0] = 0;
	priority_queue<tuple<ll, ll, ll>, vector<tuple<ll, ll, ll>>, greater<tuple<ll, ll, ll>>> pq;
	pq.push({dist[0][0], 0, 0});
	
	while (!pq.empty())
	{
		auto [d, v, m] = pq.top();
		pq.pop();
		
		if (dist[v][m] < d) {continue;}
				
		for (auto e : G[v])
		{
			ll nv = e.to, cst = e.cost;
			if (chmin(dist[nv][m], dist[v][m] + cst))
			{
				pq.push({dist[nv][m], nv, m});
			}
			if (m == M) {continue;}
			if (chmin(dist[nv][m+1], dist[v][m] + 0))
			{
				pq.push({dist[nv][m+1], nv, m+1});
			}
		}
		
	}
	
	// for (int v = 0; v < N; ++v)
	// {
	// 	cout << endl;
	// 	for (int i = 0; i <= M; ++i)
	// 	{
	// 		if (dist[v][i] < INF)
	// 		{
	// 			cout << v << " " << i << " " << dist[v][i] << endl;
	// 		}
	// 	}
	// }
	
	ll res = M;
	for (ll i = 0; i <= M; ++i)
	{
		if (dist[N-1][i] <= C) {chmin(res, i);}
	}
	cout << res << endl;
	
	
	return;
}

int main()
{
	while (!is_end)
	{
		calc();
	}
	
	return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 9320
final_rank: 14

code_snippet: #line 1 "c.cpp"
/**
 *	author: nok0
 *	created: 2022.07.05 15:55:33
**/
#line 1 "/Users/nok0/Documents/Programming/nok0/cftemp.hpp"
#include <bits/stdc++.h>
using namespace std;

#pragma region Macros
// rep macro
#define foa(v, a) for(auto &v : a)
#define repname(a, b, c, d, e, ...) e
#define rep(...) repname(__VA_ARGS__, rep3, rep2, rep1, rep0)(__VA_ARGS__)
#define rep0(x) for(int i = 0; i < (x); ++i)
#define rep1(i, x) for(int i = 0; i < (x); ++i)
#define rep2(i, l, r) for(int i = (l); i < (r); ++i)
#define rep3(i, l, r, c) for(int i = (l); i < (r); i += (c))
#define repsname(a, b, c, ...) c
#define reps(...) repsname(__VA_ARGS__, reps1, reps0)(__VA_ARGS__)
#define reps0(x) for(int i = 1; i <= (x); ++i)
#define reps1(i, x) for(int i = 1; i <= (x); ++i)
#define rrepname(a, b, c, d, e, ...) e
#define rrep(...) rrepname(__VA_ARGS__, rrep3, rrep2, rrep1, rrep0)(__VA_ARGS__)
#define rrep0(x) for(int i = (x)-1; i >= 0; --i)
#define rrep1(i, x) for(int i = (x)-1; i >= 0; --i)
#define rrep2(i, r, l) for(int i = (r)-1; i >= (l); --i)
#define rrep3(i, r, l, c) for(int i = (r)-1; i >= (l); i -= (c))
#define rrepsname(a, b, c, ...) c
#define rreps(...) rrepsname(__VA_ARGS__, rreps1, rreps0)(__VA_ARGS__)
#define rreps0(x) for(int i = (x); i >= 1; --i)
#define rreps1(i, x) for(int i = (x); i >= 1; --i)

// name macro
#define pb push_back
#define eb emplace_back
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define popcnt(x) __builtin_popcountll(x)
template <class T = int>
using V = std::vector<T>;
template <class T = int>
using VV = std::vector<std::vector<T>>;
template <class T>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
using ll = long long;
using ld = long double;
using int128 = __int128_t;
using pii = std::pair<int, int>;
using pll = std::pair<long long, long long>;

// input macro
template <class T, class U>
std::istream &operator>>(std::istream &is, std::pair<T, U> &p) {
	is >> p.first >> p.second;
	return is;
}
template <class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
	for(T &i : v) is >> i;
	return is;
}
std::istream &operator>>(std::istream &is, __int128_t &a) {
	std::string s;
	is >> s;
	__int128_t ret = 0;
	for(int i = 0; i < s.length(); i++)
		if('0' <= s[i] and s[i] <= '9')
			ret = 10 * ret + s[i] - '0';
	a = ret * (s[0] == '-' ? -1 : 1);
	return is;
}
namespace scanner {
void scan(int &a) { std::cin >> a; }
void scan(long long &a) { std::cin >> a; }
void scan(std::string &a) { std::cin >> a; }
void scan(char &a) { std::cin >> a; }
void scan(char a[]) { std::scanf("%s", a); }
void scan(double &a) { std::cin >> a; }
void scan(long double &a) { std::cin >> a; }
template <class T, class U>
void scan(std::pair<T, U> &p) { std::cin >> p; }
template <class T>
void scan(std::vector<T> &a) { std::cin >> a; }
void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &...tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner
#define VEC(type, name, size)     \
	std::vector<type> name(size); \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                                    \
	std::vector<std::vector<type>> name(h, std::vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)             \
	std::string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHAR(...)     \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DOUBLE(...)     \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)

// output-macro
template <class T, class U>
std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &p) {
	os << p.first << " " << p.second;
	return os;
}
template <class T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &a) {
	for(int i = 0; i < int(a.size()); ++i) {
		if(i) os << " ";
		os << a[i];
	}
	return os;
}
std::ostream &operator<<(std::ostream &dest, __int128_t &value) {
	std::ostream::sentry s(dest);
	if(s) {
		__uint128_t tmp = value < 0 ? -value : value;
		char buffer[128];
		char *d = std::end(buffer);
		do {
			--d;
			*d = "0123456789"[tmp % 10];
			tmp /= 10;
		} while(tmp != 0);
		if(value < 0) {
			--d;
			*d = '-';
		}
		int len = std::end(buffer) - d;
		if(dest.rdbuf()->sputn(d, len) != len) {
			dest.setstate(std::ios_base::badbit);
		}
	}
	return dest;
}
template <class T>
void print(const T a) { std::cout << a << '\n'; }
template <class Head, class... Tail>
void print(Head H, Tail... T) {
	std::cout << H << ' ';
	print(T...);
}
template <class T>
void printel(const T a) { std::cout << a << '\n'; }
template <class T>
void printel(const std::vector<T> &a) {
	for(const auto &v : a)
		std::cout << v << '\n';
}
template <class Head, class... Tail>
void printel(Head H, Tail... T) {
	std::cout << H << '\n';
	printel(T...);
}
void Yes(const bool b = true) { std::cout << (b ? "Yes\n" : "No\n"); }
void No() { std::cout << "No\n"; }
void YES(const bool b = true) { std::cout << (b ? "YES\n" : "NO\n"); }
void NO() { std::cout << "NO\n"; }
void err(const bool b = true) {
	if(b) {
		std::cout << "-1\n", exit(0);
	}
}

//debug macro
namespace debugger {
template <class T>
void view(const std::vector<T> &a) {
	std::cerr << "{ ";
	for(const auto &v : a) {
		std::cerr << v << ", ";
	}
	std::cerr << "\b\b }";
}
template <class T>
void view(const std::vector<std::vector<T>> &a) {
	std::cerr << "{\n";
	for(const auto &v : a) {
		std::cerr << "\t";
		view(v);
		std::cerr << "\n";
	}
	std::cerr << "}";
}
template <class T, class U>
void view(const std::vector<std::pair<T, U>> &a) {
	std::cerr << "{\n";
	for(const auto &p : a) std::cerr << "\t(" << p.first << ", " << p.second << ")\n";
	std::cerr << "}";
}
template <class T, class U>
void view(const std::map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &p : m) std::cerr << "\t[" << p.first << "] : " << p.second << "\n";
	std::cerr << "}";
}
template <class T, class U>
void view(const std::pair<T, U> &p) { std::cerr << "(" << p.first << ", " << p.second << ")"; }
template <class T>
void view(const std::set<T> &s) {
	std::cerr << "{ ";
	for(auto &v : s) {
		view(v);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <class T>
void view(const T &e) { std::cerr << e; }
}  // namespace debugger
#ifdef LOCAL
void debug_out() {}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	debugger::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "\b\b]\n";                                   \
	} while(false)
#else
#define debug(...) (void(0))
#endif

// vector macro
template <class T>
int lb(const std::vector<T> &a, const T x) { return std::distance((a).begin(), std::lower_bound((a).begin(), (a).end(), (x))); }
template <class T>
int ub(const std::vector<T> &a, const T x) { return std::distance((a).begin(), std::upper_bound((a).begin(), (a).end(), (x))); }
template <class T>
void UNIQUE(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<T> press(std::vector<T> &a) {
	auto res = a;
	UNIQUE(res);
	for(auto &v : a)
		v = lb(res, v);
	return res;
}
#define SORTname(a, b, c, ...) c
#define SORT(...) SORTname(__VA_ARGS__, SORT1, SORT0, ...)(__VA_ARGS__)
#define SORT0(a) std::sort((a).begin(), (a).end())
#define SORT1(a, c) std::sort((a).begin(), (a).end(), [](const auto x, const auto y) { return x c y; })
template <class T>
void ADD(std::vector<T> &a, const T x = 1) {
	for(auto &v : a) v += x;
}
template <class T>
void SUB(std::vector<T> &a, const T x = 1) {
	for(auto &v : a) v -= x;
}
std::vector<std::pair<char, int>> rle(const string &s) {
	int n = s.size();
	std::vector<std::pair<char, int>> ret;
	for(int l = 0; l < n;) {
		int r = l + 1;
		for(; r < n and s[l] == s[r]; r++) {}
		ret.emplace_back(s[l], r - l);
		l = r;
	}
	return ret;
}
template <class T>
std::vector<std::pair<T, int>> rle(const std::vector<T> &v) {
	int n = v.size();
	std::vector<std::pair<T, int>> ret;
	for(int l = 0; l < n;) {
		int r = l + 1;
		for(; r < n and v[l] == v[r]; r++) {}
		ret.emplace_back(v[l], r - l);
		l = r;
	}
	return ret;
}
std::vector<int> iota(int n) {
	std::vector<int> p(n);
	std::iota(p.begin(), p.end(), 0);
	return p;
}
template <class T>
struct cum_vector {
public:
	cum_vector() = default;
	template <class U>
	cum_vector(const std::vector<U> &vec) : cum((int)vec.size() + 1) {
		for(int i = 0; i < (int)vec.size(); i++)
			cum[i + 1] = cum[i] + vec[i];
	}
	T prod(int l, int r) {
		return cum[r] - cum[l];
	}

private:
	std::vector<T> cum;
};

// math macro
template <class T, class U>
inline bool chmin(T &a, const U &b) { return a > b ? a = b, true : false; }
template <class T, class U>
inline bool chmax(T &a, const U &b) { return a < b ? a = b, true : false; }
template <class T>
T divup(T x, T y) { return (x + y - 1) / y; }
template <class T>
T POW(T a, long long n) {
	T ret = 1;
	while(n) {
		if(n & 1) ret *= a;
		a *= a;
		n >>= 1;
	}
	return ret;
}
// modpow
long long POW(long long a, long long n, const int mod) {
	long long ret = 1;
	a = (a % mod + mod) % mod;
	while(n) {
		if(n & 1) (ret *= a) %= mod;
		(a *= a) %= mod;
		n >>= 1;
	}
	return ret;
}
template <class T, class F>
T bin_search(T ok, T ng, const F &f) {
	while(abs(ok - ng) > 1) {
		T mid = (ok + ng) >> 1;
		(f(mid) ? ok : ng) = mid;
	}
	return ok;
}
template <class T, class F>
T bin_search(T ok, T ng, const F &f, int loop) {
	for(int i = 0; i < loop; i++) {
		T mid = (ok + ng) / 2;
		(f(mid) ? ok : ng) = mid;
	}
	return ok;
}

// others
struct fast_io {
	fast_io() {
		ios::sync_with_stdio(false);
		cin.tie(nullptr);
		cout << fixed << setprecision(15);
	}
} fast_io_;
const int inf = 1e9;
const ll INF = 1e18;
#pragma endregion

void main_();

int main() {
	main_();
	return 0;
}
#line 10 "/Users/nok0/Documents/Programming/nok0/graph/graph.hpp"

struct Edge {
	int to;
	long long cost;
	Edge() = default;
	Edge(int to_, long long cost_) : to(to_), cost(cost_) {}
	bool operator<(const Edge &a) const { return cost < a.cost; }
	bool operator>(const Edge &a) const { return cost > a.cost; }
	friend std::ostream &operator<<(std::ostream &s, Edge &a) {
		s << "to: " << a.to << ", cost: " << a.cost;
		return s;
	}
};

class graph {
	std::vector<std::vector<Edge>> edges;

	template <class F>
	struct rec_lambda {
		F f;
		rec_lambda(F &&f_) : f(std::forward<F>(f_)) {}
		template <class... Args>
		auto operator()(Args &&...args) const {
			return f(*this, std::forward<Args>(args)...);
		}
	};

public:
	inline const std::vector<Edge> &operator[](int k) const { return edges[k]; }
	inline std::vector<Edge> &operator[](int k) { return edges[k]; }

	int size() const { return edges.size(); }
	void resize(const int n) { edges.resize(n); }

	graph() = default;
	graph(int n) : edges(n) {}
	graph(int n, int e, bool weight = 0, bool directed = 0, int idx = 1) : edges(n) { input(e, weight, directed, idx); }
	const long long INF = 3e18;

	void input(int e = -1, bool weight = 0, bool directed = false, int idx = 1) {
		if(e == -1) e = size() - 1;
		while(e--) {
			int u, v;
			long long cost = 1;
			std::cin >> u >> v;
			if(weight) std::cin >> cost;
			u -= idx, v -= idx;
			edges[u].emplace_back(v, cost);
			if(!directed) edges[v].emplace_back(u, cost);
		}
	}

	void add_edge(int u, int v, long long cost = 1, bool directed = false, int idx = 0) {
		u -= idx, v -= idx;
		edges[u].emplace_back(v, cost);
		if(!directed) edges[v].emplace_back(u, cost);
	}

	// Ο(V+E)
	std::vector<long long> bfs(int s) {
		std::vector<long long> dist(size(), INF);
		std::queue<int> que;
		dist[s] = 0;
		que.push(s);
		while(!que.empty()) {
			int v = que.front();
			que.pop();
			for(auto &e : edges[v]) {
				if(dist[e.to] != INF) continue;
				dist[e.to] = dist[v] + e.cost;
				que.push(e.to);
			}
		}
		return dist;
	}

	// Ο(V+E)
	// constraint: cost of each edge is zero or one
	std::vector<long long> zero_one_bfs(int s) {
		std::vector<long long> dist(size(), INF);
		std::deque<int> deq;
		dist[s] = 0;
		deq.push_back(s);
		while(!deq.empty()) {
			int v = deq.front();
			deq.pop_front();
			for(auto &e : edges[v]) {
				assert(0LL <= e.cost and e.cost < 2LL);
				if(e.cost and dist[e.to] > dist[v] + 1) {
					dist[e.to] = dist[v] + 1;
					deq.push_back(e.to);
				} else if(!e.cost and dist[e.to] > dist[v]) {
					dist[e.to] = dist[v];
					deq.push_front(e.to);
				}
			}
		}
		return dist;
	}

	// Ο((E+V)logV)
	// cannot reach: INF
	std::vector<long long> dijkstra(int s) {  // verified
		std::vector<long long> dist(size(), INF);
		const auto compare = [](const std::pair<long long, int> &a, const std::pair<long long, int> &b) { return a.first > b.first; };
		std::priority_queue<std::pair<long long, int>, std::vector<std::pair<long long, int>>, decltype(compare)> que{compare};
		dist[s] = 0;
		que.emplace(0, s);
		while(!que.empty()) {
			std::pair<long long, int> p = que.top();
			que.pop();
			int v = p.second;
			if(dist[v] < p.first) continue;
			for(auto &e : edges[v]) {
				if(dist[e.to] > dist[v] + e.cost) {
					dist[e.to] = dist[v] + e.cost;
					que.emplace(dist[e.to], e.to);
				}
			}
		}
		return dist;
	}

	// Ο(VE)
	// cannot reach: INF
	// negative cycle: -INF
	std::vector<long long> bellman_ford(int s) {  // verified
		int n = size();
		std::vector<long long> res(n, INF);
		res[s] = 0;
		for(int loop = 0; loop < n - 1; loop++) {
			for(int v = 0; v < n; v++) {
				if(res[v] == INF) continue;
				for(auto &e : edges[v]) {
					res[e.to] = std::min(res[e.to], res[v] + e.cost);
				}
			}
		}
		std::queue<int> que;
		std::vector<int> chk(n);
		for(int v = 0; v < n; v++) {
			if(res[v] == INF) continue;
			for(auto &e : edges[v]) {
				if(res[e.to] > res[v] + e.cost and !chk[e.to]) {
					que.push(e.to);
					chk[e.to] = 1;
				}
			}
		}
		while(!que.empty()) {
			int now = que.front();
			que.pop();
			for(auto &e : edges[now]) {
				if(!chk[e.to]) {
					chk[e.to] = 1;
					que.push(e.to);
				}
			}
		}
		for(int i = 0; i < n; i++)
			if(chk[i]) res[i] = -INF;
		return res;
	}

	// Ο(V^3)
	std::vector<std::vector<long long>> warshall_floyd() {  // verified
		int n = size();
		std::vector<std::vector<long long>> dist(n, std::vector<long long>(n, INF));
		for(int i = 0; i < n; i++) dist[i][i] = 0;
		for(int i = 0; i < n; i++)
			for(auto &e : edges[i]) dist[i][e.to] = std::min(dist[i][e.to], e.cost);
		for(int k = 0; k < n; k++)
			for(int i = 0; i < n; i++) {
				if(dist[i][k] == INF) continue;
				for(int j = 0; j < n; j++) {
					if(dist[k][j] == INF) continue;
					dist[i][j] = std::min(dist[i][j], dist[i][k] + dist[k][j]);
				}
			}
		return dist;
	}

	// Ο(V) (using DFS)
	// if a directed cycle exists, return {}
	std::vector<int> topological_sort() {  // verified
		std::vector<int> res;
		int n = size();
		std::vector<int> used(n, 0);
		bool not_DAG = false;
		for(int i = 0; i < n; i++) {
			rec_lambda([&](auto &&dfs, int k) -> void {
				if(not_DAG) return;
				if(used[k]) {
					if(used[k] == 1) not_DAG = true;
					return;
				}
				used[k] = 1;
				for(auto &e : edges[k]) dfs(e.to);
				used[k] = 2;
				res.push_back(k);
			})(i);
		}
		if(not_DAG) return std::vector<int>{};
		std::reverse(res.begin(), res.end());
		return res;
	}

	bool is_DAG() { return !topological_sort().empty(); }  // verified

	// Ο(V)
	// array of the distance from each vertex to the most distant vertex
	std::vector<long long> height() {  // verified
		auto vec1 = bfs(0);
		int v1 = -1, v2 = -1;
		long long dia = -1;
		for(int i = 0; i < int(size()); i++)
			if(dia < vec1[i]) dia = vec1[i], v1 = i;
		vec1 = bfs(v1);
		dia = -1;
		for(int i = 0; i < int(size()); i++)
			if(dia < vec1[i]) dia = vec1[i], v2 = i;
		auto vec2 = bfs(v2);
		for(int i = 0; i < int(size()); i++)
			if(vec1[i] < vec2[i]) vec1[i] = vec2[i];
		return vec1;
	}

	// O(V+E)
	// vector<(int)(0 or 1)>
	// if it is not bipartite, return {}
	std::vector<int> bipartite_grouping() {
		std::vector<int> colors(size(), -1);
		auto dfs = [&](auto self, int now, int col) -> bool {
			colors[now] = col;
			for(auto &e : edges[now]) {
				if(col == colors[e.to]) return false;
				if(colors[e.to] == -1 and !self(self, e.to, !col)) return false;
			}
			return true;
		};
		for(int i = 0; i < int(size()); i++)
			if(colors[i] == -1 and !dfs(dfs, i, 0)) return std::vector<int>{};
		return colors;
	}

	bool is_bipartite() { return !bipartite_grouping().empty(); }

	// Ο(V+E)
	// ((v1, v2), diameter)
	std::pair<std::pair<int, int>, long long> diameter() {  // verified
		auto vec = bfs(0);
		int v1 = -1, v2 = -1;
		long long dia = -1;
		for(int i = 0; i < int(size()); i++)
			if(dia < vec[i]) dia = vec[i], v1 = i;
		vec = bfs(v1);
		dia = -1;
		for(int i = 0; i < int(size()); i++)
			if(dia < vec[i]) dia = vec[i], v2 = i;
		std::pair<std::pair<int, int>, long long> res = {{v1, v2}, dia};
		return res;
	}

	// Ο(V+E)
	// return {s, v1, v2, ... t}
	std::vector<int> diameter_path() {
		auto vec = bfs(0);
		int v1 = -1, v2 = -1;
		long long dia = -1;
		for(int i = 0; i < int(size()); i++)
			if(dia < vec[i]) dia = vec[i], v1 = i;
		auto vec2 = bfs(v1);
		dia = -1;
		for(int i = 0; i < int(size()); i++)
			if(dia < vec2[i]) dia = vec2[i], v2 = i;
		vec = bfs(v2);
		std::vector<int> ret;
		auto dfs = [&](auto self, int now, int p) -> void {
			ret.emplace_back(now);
			if(now == v2) return;
			for(auto &[to, cost] : (*this)[now]) {
				if(vec[to] + vec2[to] == dia and to != p)
					self(self, to, now);
			}
		};
		dfs(dfs, v1, -1);
		return ret;
	}

	// Ο(V+E)
	// return subtree_size, root = root
	std::vector<int> subtree_size(const int root) {
		int n = size();
		std::vector<int> ret(n, 1);
		rec_lambda([&](auto &&dfs, int now, int p) -> void {
			for(auto &[to, cost] : (*this)[now]) {
				if(to == p) continue;
				dfs(to, now);
				ret[now] += ret[to];
			}
		})(root, -1);
		return ret;
	}

	// Ο(ElogV)
	long long prim() {  // verified
		long long res = 0;
		std::priority_queue<Edge, std::vector<Edge>, std::greater<Edge>> que;
		for(auto &e : edges[0]) que.push(e);
		std::vector<int> chk(size());
		chk[0] = 1;
		int cnt = 1;
		while(cnt < size()) {
			auto e = que.top();
			que.pop();
			if(chk[e.to]) continue;
			cnt++;
			res += e.cost;
			chk[e.to] = 1;
			for(auto &e2 : edges[e.to]) que.push(e2);
		}
		return res;
	}

	// Ο(ElogE)
	long long kruskal() {  // verified
		std::vector<std::tuple<int, int, long long>> Edges;
		for(int i = 0; i < int(size()); i++)
			for(auto &e : edges[i]) Edges.emplace_back(i, e.to, e.cost);
		std::sort(Edges.begin(), Edges.end(), [](const std::tuple<int, int, long long> &a, const std::tuple<int, int, long long> &b) {
			return std::get<2>(a) < std::get<2>(b);
		});
		std::vector<int> uf_data(size(), -1);
		auto root = [&uf_data](auto self, int x) -> int {
			if(uf_data[x] < 0) return x;
			return uf_data[x] = self(self, uf_data[x]);
		};
		auto unite = [&uf_data, &root](int u, int v) -> bool {
			u = root(root, u), v = root(root, v);
			if(u == v) return false;
			if(uf_data[u] > uf_data[v]) std::swap(u, v);
			uf_data[u] += uf_data[v];
			uf_data[v] = u;
			return true;
		};
		long long ret = 0;
		for(auto &e : Edges)
			if(unite(std::get<0>(e), std::get<1>(e))) ret += std::get<2>(e);
		return ret;
	}

	graph build_mst() {
		std::vector<std::tuple<int, int, long long>> Edges;
		for(int i = 0; i < int(size()); i++)
			for(auto &e : edges[i]) Edges.emplace_back(i, e.to, e.cost);
		std::sort(Edges.begin(), Edges.end(), [](const std::tuple<int, int, long long> &a, const std::tuple<int, int, long long> &b) {
			return std::get<2>(a) < std::get<2>(b);
		});
		std::vector<int> uf_data(size(), -1);
		auto root = [&uf_data](auto self, int x) -> int {
			if(uf_data[x] < 0) return x;
			return uf_data[x] = self(self, uf_data[x]);
		};
		auto unite = [&uf_data, &root](int u, int v) -> bool {
			u = root(root, u), v = root(root, v);
			if(u == v) return false;
			if(uf_data[u] > uf_data[v]) std::swap(u, v);
			uf_data[u] += uf_data[v];
			uf_data[v] = u;
			return true;
		};
		graph g(this->size());
		for(auto &e : Edges)
			if(unite(std::get<0>(e), std::get<1>(e))) {
				g.add_edge(std::get<0>(e), std::get<1>(e), std::get<2>(e));
			}
		return g;
	}

	// O(V)
	std::vector<int> centroid() {
		int n = size();
		std::vector<int> centroid, sz(n);
		auto dfs = [&](auto self, int now, int per) -> void {
			sz[now] = 1;
			bool is_centroid = true;
			for(auto &e : edges[now]) {
				if(e.to != per) {
					self(self, e.to, now);
					sz[now] += sz[e.to];
					if(sz[e.to] > n / 2) is_centroid = false;
				}
			}
			if(n - sz[now] > n / 2) is_centroid = false;
			if(is_centroid) centroid.push_back(now);
		};
		dfs(dfs, 0, -1);
		return centroid;
	}

	// Ο(V+E)
	// directed graph from root to leaf
	graph root_to_leaf(int root = 0) {
		graph res(size());
		std::vector<int> chk(size(), 0);
		chk[root] = 1;
		auto dfs = [&](auto self, int now) -> void {
			for(auto &e : edges[now]) {
				if(chk[e.to] == 1) continue;
				chk[e.to] = 1;
				res.add_edge(now, e.to, e.cost, 1, 0);
				self(self, e.to);
			}
		};
		dfs(dfs, root);
		return res;
	}

	// Ο(V+E)
	// directed graph from leaf to root
	graph leaf_to_root(int root = 0) {
		graph res(size());
		std::vector<int> chk(size(), 0);
		chk[root] = 1;
		auto dfs = [&](auto self, int now) -> void {
			for(auto &e : edges[now]) {
				if(chk[e.to] == 1) continue;
				chk[e.to] = 1;
				res.add_edge(e.to, now, e.cost, 1, 0);
				self(self, e.to);
			}
		};
		dfs(dfs, root);
		return res;
	}

	// long long Chu_Liu_Edmonds(int root = 0) {}
};
#line 7 "c.cpp"

void solve() {
	INT(n, m, c);
	if(!n) exit(0);
	graph g(n, m, 1, 1);
	graph h(n * (m + 1));
	rep(i, n) {
		rep(j, m + 1) {
			for(auto [to, cost] : g[i]) {
				//skip する場合
				if(j + 1 <= m) h.add_edge(i * (m + 1) + j, to * (m + 1) + j + 1, 0, 1);
				h.add_edge(i * (m + 1) + j, to * (m + 1) + j, cost, 1);
			}
		}
	}
	auto d = h.dijkstra(0);
	rep(i, m + 1) {
		if(d[(n - 1) * (m + 1) + i] <= c) {
			print(i);
			return;
		}
	}
}

void main_() {
	while(1) solve();
}
accuracy: 1
time_ms: 590
memory_kb: 57500
final_rank: 19

code_snippet: #include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define _GLIBCXX_DEBUG
using namespace std;
using std::cout;
using std::cin;
using std::endl;
using ll=long long;
using ld=long double;
ll ILL=1167167167167167167;
const int INF=1050000000;
const ll mod=998244353;
#define rep(i,a) for (ll i=0;i<a;i++)
#define all(p) p.begin(),p.end()
template<class T> using _pq = priority_queue<T, vector<T>, greater<T>>;
template<class T> ll LB(vector<T> &v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> ll UB(vector<T> &v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> bool chmin(T &a,const T &b){if(a>b){a=b;return 1;}else return 0;}
template<class T> bool chmax(T &a,const T &b){if(a<b){a=b;return 1;}else return 0;}
template<class T> void So(vector<T> &v) {sort(v.begin(),v.end());}
template<class T> void Sore(vector<T> &v) {sort(v.begin(),v.end(),[](T x,T y){return x>y;});}
void yneos(bool a){if(a) cout<<"Yes\n"; else cout<<"No\n";}
template<class T> void vec_out(vector<T> &p){for(int i=0;i<(int)(p.size());i++){if(i) cout<<" ";cout<<p[i];}cout<<"\n";}

int N,M,C;

void solve();
// oddloop
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	
	while(cin>>N>>M>>C,N) solve();
}

void solve(){
	vector<vector<pair<int,int>>> G(N*(M+1));
	rep(i,M){
		int f,t,w;
		cin>>f>>t>>w;
		f--,t--;
		rep(j,M){
			G[f+j*N].push_back({t+j*N,w});
			G[f+j*N].push_back({t+j*N+N,0});
		}
	}
	vector<int> dp(N*(M+1),INF);
	_pq<pair<int,int>> pq;
	dp[0]=0;
	pq.push({0,0});
	while(!pq.empty()){
		int ind,time;
		tie(time,ind)=pq.top();
		pq.pop();
		if(dp[ind]>time) continue;
		for(auto x:G[ind]){
			if(chmin(dp[x.first],time+x.second)){
				pq.push({dp[x.first],x.first});
			}
		}
	}
	rep(i,M){
		if(dp[i*N+N-1]>C&&C>=dp[N*(i+2)-1]){
			cout<<i+1<<"\n";
			return;
		}
	}
}
accuracy: 1
time_ms: 600
memory_kb: 31504
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int INF = 1 << 30;

bool solve() {
    int n, m, c;
    cin >> n >> m >> c;
    if (n == 0 and m == 0 and c == 0) return false;
    vector<vector<pair<int, int>>> G(n);
    for (; m--;) {
        int f, t, x;
        cin >> f >> t >> x;
        G[--f].emplace_back(--t, x);
    }

    vector<vector<int>> dp(n, vector<int>(n, INF));
    priority_queue<tuple<int, int, int>> pq;
    dp[0][0] = 0;
    pq.emplace(-dp[0][0], 0, 0);

    while (!pq.empty()) {
        auto t = pq.top();
        pq.pop();
        int val, v, x;
        tie(val, v, x) = t;
        val *= -1;
        if (dp[v][x] < val) continue;
        for (auto& e : G[v]) {
            int u = e.first;
            if (val + e.second < dp[u][x]) {
                dp[u][x] = val + e.second;
                pq.emplace(-dp[u][x], u, x);
            }
            if (x + 1 < n and val < dp[u][x + 1]) {
                dp[u][x + 1] = val;
                pq.emplace(-dp[u][x + 1], u, x + 1);
            }
        }
    }

    int ans = n;
    for (int j = n - 1; j >= 0; j--) {
        if (dp[n - 1][j] <= c) {
            ans = j;
        }
    }

    cout << ans << '\n';
    return true;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    while (solve())
        ;
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 3436
final_rank: 9

code_snippet: #define LOCAL
#include <bits/stdc++.h>
using namespace std;
#pragma region Macros
typedef long long ll;
typedef __int128_t i128;
typedef unsigned int uint;
typedef unsigned long long ull;
#define ALL(x) (x).begin(), (x).end()

template <typename T> istream& operator>>(istream& is, vector<T>& v) {
    for (T& x : v) is >> x;
    return is;
}
template <typename T> ostream& operator<<(ostream& os, const vector<T>& v) {
    for (size_t i = 0; i < v.size(); i++) {
        os << v[i] << (i + 1 == v.size() ? "" : " ");
    }
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T, typename U> ostream& operator<<(ostream& os, const unordered_map<T, U>& m) {
    os << '{';
    for (auto itr = m.begin(); itr != m.end();) {
        os << '(' << itr->first << ',' << itr->second << ')';
        if (++itr != m.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const multiset<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const unordered_set<T>& s) {
    os << '{';
    for (auto itr = s.begin(); itr != s.end();) {
        os << *itr;
        if (++itr != s.end()) os << ',';
    }
    os << '}';
    return os;
}
template <typename T> ostream& operator<<(ostream& os, const deque<T>& v) {
    for (size_t i = 0; i < v.size(); i++) {
        os << v[i] << (i + 1 == v.size() ? "" : " ");
    }
    return os;
}
template <typename T, size_t N> ostream& operator<<(ostream& os, const array<T, N>& v) {
    for (size_t i = 0; i < N; i++) {
        os << v[i] << (i + 1 == N ? "" : " ");
    }
    return os;
}

template <int i, typename T> void print_tuple(ostream&, const T&) {}
template <int i, typename T, typename H, class... Args> void print_tuple(ostream& os, const T& t) {
    if (i) os << ',';
    os << get<i>(t);
    print_tuple<i + 1, T, Args...>(os, t);
}
template <typename... Args> ostream& operator<<(ostream& os, const tuple<Args...>& t) {
    os << '{';
    print_tuple<0, tuple<Args...>, Args...>(os, t);
    return os << '}';
}

void debug_out() { cerr << '\n'; }
template <class Head, class... Tail> void debug_out(Head&& head, Tail&&... tail) {
    cerr << head;
    if (sizeof...(Tail) > 0) cerr << ", ";
    debug_out(move(tail)...);
}
#ifdef LOCAL
#define debug(...)                                                                   \
    cerr << " ";                                                                     \
    cerr << #__VA_ARGS__ << " :[" << __LINE__ << ":" << __FUNCTION__ << "]" << '\n'; \
    cerr << " ";                                                                     \
    debug_out(__VA_ARGS__)
#else
#define debug(...) void(0)
#endif

template <typename T> T gcd(T x, T y) { return y != 0 ? gcd(y, x % y) : x; }
template <typename T> T lcm(T x, T y) { return x / gcd(x, y) * y; }

int topbit(signed t) { return t == 0 ? -1 : 31 - __builtin_clz(t); }
int topbit(long long t) { return t == 0 ? -1 : 63 - __builtin_clzll(t); }
int botbit(signed a) { return a == 0 ? 32 : __builtin_ctz(a); }
int botbit(long long a) { return a == 0 ? 64 : __builtin_ctzll(a); }
int popcount(signed t) { return __builtin_popcount(t); }
int popcount(long long t) { return __builtin_popcountll(t); }
bool ispow2(int i) { return i && (i & -i) == i; }
long long MSK(int n) { return (1LL << n) - 1; }

template <class T> T ceil(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <class T> T floor(T x, T y) {
    assert(y >= 1);
    return (x > 0 ? x / y : (x - y + 1) / y);
}

template <class T1, class T2> inline bool chmin(T1& a, T2 b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T1, class T2> inline bool chmax(T1& a, T2 b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

template <typename T> void mkuni(vector<T>& v) {
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
}
template <typename T> int lwb(const vector<T>& v, const T& x) { return lower_bound(v.begin(), v.end(), x) - v.begin(); }
#pragma endregion

const int INF = 1e9;
const long long IINF = 1e18;
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const char dir[4] = {'D', 'R', 'U', 'L'};
const long long MOD = 1000000007;
// const long long MOD = 998244353;

bool solve() {
    int n, m, c;
    cin >> n >> m >> c;
    if (n == 0 and m == 0 and c == 0) return false;
    vector<vector<pair<int, int>>> G(n);
    for (; m--;) {
        int f, t, x;
        cin >> f >> t >> x;
        G[--f].emplace_back(--t, x);
    }

    vector<vector<int>> dp(n, vector<int>(n, INF));
    priority_queue<tuple<int, int, int>> pq;
    dp[0][0] = 0;
    pq.emplace(-dp[0][0], 0, 0);

    while (!pq.empty()) {
        auto t = pq.top();
        pq.pop();
        int val, v, x;
        tie(val, v, x) = t;
        val *= -1;
        if (dp[v][x] < val) continue;
        for (auto& e : G[v]) {
            int u = e.first;
            if (val + e.second < dp[u][x]) {
                dp[u][x] = val + e.second;
                pq.emplace(-dp[u][x], u, x);
            }
            if (x + 1 < n and val < dp[u][x + 1]) {
                dp[u][x + 1] = val;
                pq.emplace(-dp[u][x + 1], u, x + 1);
            }
        }
    }

    int ans = n;
    for (int j = n - 1; j >= 0; j--) {
        if (dp[n - 1][j] <= c) {
            ans = j;
        }
    }

    cout << ans << '\n';
    return true;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    while (solve())
        ;
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 3560
final_rank: 10

code_snippet: #include<bits/stdc++.h> 
using namespace std;
using ll=long long int;
//using Int=__int128;
#define ALL(A) A.begin(),A.end()
template<typename T1,typename T2> bool chmin(T1 &a,T2 b){if(a<=b)return 0; a=b; return 1;}
template<typename T1,typename T2> bool chmax(T1 &a,T2 b){if(a>=b)return 0; a=b; return 1;}
template<typename T> constexpr int bitUP(T x,int a){return (x>>a)&1;}
//→　↓　←　↑ 
int dh[4]={0,1,0,-1}, dw[4]={1,0,-1,0};
//右上から時計回り
//int dh[8]={-1,0,1,1,1,0,-1,-1}, dw[8]={1,1,1,0,-1,-1,-1,0};
long double EPS = 1e-6;
long double PI = acos(-1);
const ll INF=(1LL<<62);
const int MAX=(1<<30);
constexpr ll MOD=1000000000+7;
//constexpr ll MOD=998244353;


inline void bin101(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(20);
}

using pii=pair<int,int>;
using pil=pair<int,ll>;
using pli=pair<ll,int>;
using pll=pair<ll,ll>;
using psi=pair<string,int>;
using pis=pair<int,string>;
using psl=pair<string,ll>;
using pls=pair<ll,string>;
using pss=pair<string,string>;

using Graph=vector<vector<int>>;

template<typename T >
struct edge {
	int to;
	T cost;
	edge()=default;
	edge(int to, T cost) : to(to), cost(cost) {}

};
template<typename T>
using WeightGraph=vector<vector<edge<T>>>;

template<typename T>
void CinGraph(int M,WeightGraph<T> &g,bool directed=false,bool index1=true){
    while(M--){
        int s,t;
        T cost;
        cin>>s>>t>>cost;
        if(index1) s--,t--;
        g[s].emplace_back(t,cost);
        if(not directed) g[t].emplace_back(s,cost);
    }
}

void CinGraph(int M,Graph &g,bool directed=false,bool index1=true){
    while(M--){
        int s,t;
        cin>>s>>t;
        if(index1) s--,t--;
        g[s].push_back(t);
        if(not directed) g[t].push_back(s);
    }
}


//0-indexed vector cin
template<typename T>
inline istream &operator>>(istream &is,vector<T> &v) {
    for(size_t i=0;i<v.size();i++) is>>v[i];
	return is;
}
 
//0-indexed vector cin
template<typename T>
inline istream &operator>>(istream &is,vector<vector<T>> &v) {
    for(size_t i=0;i<v.size();i++){
        is>>v[i];
    }
    return is;
}
//vector cout
template<typename T>
inline ostream &operator<<(ostream &os,const vector<T> &v) {
    for(size_t i=0;i<v.size();i++){
        if(i) os<<" ";
        os<<v[i];
    }
    return os;
}
//vector<vector> cout
template<typename T>
inline ostream &operator<<(ostream &os,const vector<vector<T>> &v) {
    for(size_t i=0;i<v.size();i++){
        os<<v[i];
        if(i+1!=v.size()) os<<"\n";
    }
    return os;
}

//Graph out
template<typename T>
inline ostream &operator<<(ostream &os,const Graph &g) {
    for(size_t i=0;i<g.size();i++){
        for(int to:g[i]){
            os<<i<<"->"<<to<<" ";
        }
        os<<endl;
    }
    return os;
}

//WeightGraph out
template<typename T>
inline ostream &operator<<(ostream &os,const WeightGraph<T> &g) {
    for(size_t i=0;i<g.size();i++){
        for(auto e:g[i]){
            os<<i<<"->"<<e.to<<"("<<e.cost<<") ";
        }
        os<<endl;
    }
    return os;
}


//要素数n 初期値x
template<typename T>
inline vector<T> vmake(size_t n,T x){
	return vector<T>(n,x);
}

//a,b,c,x data[a][b][c] 初期値x
template<typename... Args>
auto vmake(size_t n,Args... args){
	auto v=vmake(args...);
	return vector<decltype(v)>(n,move(v));
}
template<typename V,typename T>
void fill(V &v,const T value){
    v=value;
}

template<typename V,typename T>
void fill(vector<V> &vec,const T value){
    for(auto &v:vec) fill(v,value);
}

//pair cout
template<typename T, typename U>
inline ostream &operator<<(ostream &os,const pair<T,U> &p) {
	os<<p.first<<" "<<p.second;
	return os;
}
 
//pair cin
template<typename T, typename U>
inline istream &operator>>(istream &is,pair<T,U> &p) {
	is>>p.first>>p.second;
	return is;
}
 
//ソート
template<typename T>
inline void vsort(vector<T> &v){
    sort(v.begin(),v.end());
}
 
//逆順ソート
template<typename T>
inline void rvsort(vector<T> &v){
	sort(v.rbegin(),v.rend());
}

//1ビットの数を返す
inline int popcount(int x){
	return __builtin_popcount(x);
}
//1ビットの数を返す
inline int popcount(ll x){
	return __builtin_popcountll(x);
}
template<typename T>
inline void Compress(vector<T> &C){
    sort(C.begin(),C.end());
    C.erase(unique(C.begin(),C.end()),C.end());
}
template<typename T>
inline int lower_idx(const vector<T> &C,T value){
    return lower_bound(C.begin(),C.end(),value)-C.begin();
}
template<typename T>
inline int upper_idx(const vector<T> &C,T value){
    return upper_bound(C.begin(),C.end(),value)-C.begin();
}
//時計回りに90度回転
template<typename T>
inline void rotate90(vector<vector<T>> &C){
    vector<vector<T>> D(C[0].size(),vector<T>(C.size()));
    for(int h=0;h<C.size();h++){
        for(int w=0;w<C[h].size();w++){
            D[w][C.size()-1-h]=C[h][w];
        }
    }
    C=D;
}
//補グラフを返す
//i→iのような辺は加えない
Graph ComplementGraph(const Graph &g){
    size_t sz=g.size();
    bool used[sz][sz];
    fill(used[0],used[sz],false);
    for(size_t i=0;i<sz;i++){
        for(int to:g[i]){
            used[i][to]=true;
        }
    }
    Graph ret(sz);
    for(size_t i=0;i<sz;i++){
        for(size_t j=0;j<sz;j++){
            if(used[i][j]) continue;
            if(i==j) continue;
            ret[i].push_back(j);
        }
    }
    return ret;
}
//グラフの分解 secondはある頂点がどこに対応するか id[i]={2,3}のとき,頂点iはret[2][3]に対応
//無効グラフのみに対応
pair<vector<Graph>,vector<pair<int,int>>> GraphDecomposition(const Graph &g){
    vector<pair<int,int>> id(g.size(),pair<int,int>(-1,-1));
    vector<Graph> ret;
    vector<int> now;
    for(size_t i=0;i<g.size();i++){
        if(id[i].first!=-1) continue;
        id[i].first=ret.size();
        id[i].second=0;
        now.push_back(i);
        for(size_t j=0;j<now.size();j++){
            for(int to:g[now[j]]){
                if(id[to].first==-1){
                    id[to].first=ret.size();
                    id[to].second=now.size();
                    now.push_back(to);
                }
            }
        }
        Graph r(now.size());
        for(size_t j=0;j<now.size();j++){
            r[j]=g[now[j]];
            for(int &to:r[j]){
                to=id[to].second;
            }
        }
        ret.push_back(r);
        now.clear();
    }
    return make_pair(ret,id);
}
//0indexを想定
bool OutGrid(ll h,ll w,ll H,ll W){
    return (h>=H or w>=W or h<0 or w<0);
}

void NO(){
    cout<<"NO"<<"\n";
}
void YES(){
    cout<<"YES"<<"\n";
}
void No(){
    cout<<"No"<<"\n";
}
void Yes(){
    cout<<"Yes"<<"\n";
}
namespace overflow{
    template<typename T>
    T max(){
        return numeric_limits<T>::max();
    }
    template<typename T>
    T ADD(T a,T b){
        T res;
        return __builtin_add_overflow(a,b,&res)?max<T>():res;
    }
    template<typename T>
    T MUL(T a,T b){
        T res;
        return __builtin_mul_overflow(a,b,&res)?max<T>():res;
    }
};
using namespace overflow;
struct ModInt{
    using u64=uint_fast64_t;
    u64 a;
    constexpr ModInt() :a(0){}
    constexpr ModInt(ll x) :a((x>=0)?(x%MOD):(x%MOD+MOD) ) {}

    inline constexpr ModInt operator+(const ModInt rhs)const noexcept{
        return ModInt(*this)+=rhs;
    }
    inline constexpr ModInt operator-(const ModInt rhs)const noexcept{
        return ModInt(*this)-=rhs;
    }
    inline constexpr ModInt operator*(const ModInt rhs)const noexcept{
        return ModInt(*this)*=rhs;
    }
    inline constexpr ModInt operator/(const ModInt rhs)const noexcept{
        return ModInt(*this)/=rhs;
    }
    inline constexpr ModInt operator+(const ll rhs) const noexcept{
        return ModInt(*this)+=ModInt(rhs);
    }
    inline constexpr ModInt operator-(const ll rhs)const noexcept{
        return ModInt(*this)-=ModInt(rhs);
    }
    inline constexpr ModInt operator*(const ll rhs)const noexcept{
        return ModInt(*this)*=ModInt(rhs);
    }
    inline constexpr ModInt operator/(const ll rhs)const noexcept{
        return ModInt(*this)/=ModInt(rhs);
    }

    inline constexpr ModInt &operator+=(const ModInt rhs)noexcept{
        a+=rhs.a;
        if(a>=MOD) a-=MOD;
        return *this;
    }
    inline constexpr ModInt &operator-=(const ModInt rhs)noexcept{
        if(rhs.a>a) a+=MOD;
        a-=rhs.a;
        return *this;
    }
    inline constexpr ModInt &operator*=(const ModInt rhs)noexcept{
        a=(a*rhs.a)%MOD;
        return *this;
    }
    inline constexpr ModInt &operator/=(ModInt rhs)noexcept{
        a=(a*rhs.inverse().a)%MOD;
        return *this;
    }
    inline constexpr ModInt &operator+=(const ll rhs)noexcept{
        return *this+=ModInt(rhs);
    }
    inline constexpr ModInt &operator-=(const ll rhs)noexcept{
        return *this-=ModInt(rhs);
    }
    inline constexpr ModInt &operator*=(const ll rhs)noexcept{
        return *this*=ModInt(rhs);
    }
    inline constexpr ModInt &operator/=(const ll rhs)noexcept{
        return *this/=ModInt(rhs);
    }

    inline constexpr ModInt operator=(const ll x)noexcept{
        a=(x>=0)?(x%MOD):(x%MOD+MOD);
        return *this;
    }

    inline constexpr bool operator==(const ModInt p)const noexcept{
        return a==p.a;
    }

    inline constexpr bool operator!=(const ModInt p)const noexcept{
        return a!=p.a;
    }

    inline constexpr ModInt pow(ll N) const noexcept{
        ModInt ans(1LL),p(a);
        while(N>0){
            if(bitUP(N,0)){
                ans*=p;
            }
            p*=p;
            N>>=1;
        }
        return ans;
    }
    inline constexpr ModInt inverse() const noexcept{
        return pow(MOD-2);
    }

};
inline constexpr ModInt operator+(const ll &a,const ModInt &b)noexcept{
    return ModInt(a)+=b;
}
inline constexpr ModInt operator-(const ll &a,const ModInt &b)noexcept{
    return ModInt(a)-=b;
}
inline constexpr ModInt operator*(const ll &a,const ModInt &b)noexcept{
    return ModInt(a)*=b;
}
inline constexpr ModInt operator/(const ll &a,const ModInt &b)noexcept{
    return ModInt(a)/=b;
}
//cout
inline ostream &operator<<(ostream &os,const ModInt &p) {
    return os<<p.a;
}

//cin
inline istream &operator>>(istream &is,ModInt &p) {
    ll t;
    is>>t;
    p=t;
    return is;
}

struct Binominal{
    vector<ModInt> fac,finv,inv; //fac[n]:n! finv:(n!)の逆元
    int sz;
    Binominal(int n=10) :sz(1){
        if(n<=0) n=10;
        init(n);
    }
    inline void init(int n){
        fac.resize(n+1,1);
        finv.resize(n+1,1);
        inv.resize(n+1,1);
        for(int i=sz+1;i<=n;i++){
            fac[i]=fac[i-1]*i;
            inv[i]=MOD-inv[MOD%i]*(MOD/i);
            finv[i]=finv[i-1]*inv[i];
        }
        sz=n;
    }
    //nCk(n,k<=N) をO(1)で求める
    inline ModInt com(int n,int k){
        if(n<k) return ModInt(0);
        if(n<0 || k<0) return ModInt(0);
        if(n>sz) init(n);
        return fac[n]*finv[k]*finv[n-k];
    }
    //nCk(k<=N) をO(k)　で求める 
    inline ModInt rcom(ll n,int k){
        if(n<0 || k<0 || n<k) return ModInt(0);
        if(k>sz) init(k);
        ModInt ret(1);
        for(int i=0;i<k;i++){
            ret*=n-i;
        }
        ret*=finv[k];
        return ret;
    }

    //重複組み合わせ n種類のものから重複を許してk個を選ぶ
    //〇がn個,|がk個
    inline ModInt h(int n,int k){
        return com(n+k-1,k);
    }
};
vector<int> Subset(int S,bool zero=false,bool full=false){
    vector<int> ret;
    int now=(S-1)&S;
    if(full and S){
        ret.push_back(S);
    }
    do{
        ret.push_back(now);
        now=(now-1)&S;
    }while(now!=0);
    if(zero){
        ret.push_back(0);
    }
    return ret;
}
template<typename T>
T SUM(const vector<T> &v,int s,int t){
    chmax(s,0);
    chmin(t,int(v.size())-1);
    if(s>t) return 0;
    if(s==0) return v[t];
    else return v[t]-v[s-1];
}
template<typename T>
void buildSUM(vector<T> &v){
    for(size_t i=1;i<v.size();i++){
        v[i]+=v[i-1];
    }
    return;
}
 

void solve(){
while(true){
    int N,M,C;
    cin>>N>>M>>C;
    if(N==0) return;
    WeightGraph<int> G(N);
    for(int i=0;i<M;i++){
        int a,b,c; cin>>a>>b>>c;
        a--; b--;
        G[a].emplace_back(b,c);
    }
    auto dp=vmake(N,N+1,MAX);
    using T=tuple<int,int,int>;
    priority_queue<T,vector<T>,greater<T>> que;
    que.emplace(0,0,0);
    dp[0][0]=0;
    while(que.size()){
        int c,now,used;
        tie(c,now,used)=que.top(); que.pop();
        if(c>dp[now][used]) continue;

        for(auto e:G[now]){
            
            if(used<N and chmin(dp[e.to][used+1],c)){
                que.emplace(c,e.to,used+1);
            }
            if(chmin(dp[e.to][used],c+e.cost)){
                que.emplace(c+e.cost,e.to,used);
            }
        }
    }
    for(int used=0;used<=N;used++){
        if(dp[N-1][used]<=C){
            cout<<used<<endl;
            break;
        }
    }
}
}

int main(){
    bin101();
    int T=1;
    //cin>>T;
    while(T--) solve();
}
accuracy: 1
time_ms: 30
memory_kb: 3676
final_rank: 5

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
//using namespace atcoder;
#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
using namespace std;
 
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<int, int> pii;
typedef pair<long long, long long> PLL;
typedef pair<int, PII> TIII;
 
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
 
 
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define trav(a, x) for (auto &a : x)
#define all(x) x.begin(), x.end()
 
#define MOD 1000000007
 
template<class T1, class T2> inline bool chmax(T1 &a, T2 b) {if (a < b) {a = b; return true;} return false;}
template<class T1, class T2> inline bool chmin(T1 &a, T2 b) {if (a > b) {a = b; return true;} return false;}
const double EPS = 1e-8, PI = acos(-1);
const double pi = 3.141592653589793238462643383279;
//ここから編集    
typedef string::const_iterator State;
ll GCD(ll a, ll b){
  return (b==0)?a:GCD(b, a%b);
}
ll LCM(ll a, ll b){
  return a/GCD(a, b) * b;
}
template< int mod >
struct ModInt {
  int x;
 
  ModInt() : x(0) {}
 
  ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
 
  ModInt &operator+=(const ModInt &p) {
    if((x += p.x) >= mod) x -= mod;
    return *this;
  }
 
  ModInt &operator-=(const ModInt &p) {
    if((x += mod - p.x) >= mod) x -= mod;
    return *this;
  }
 
  ModInt &operator*=(const ModInt &p) {
    x = (int) (1LL * x * p.x % mod);
    return *this;
  }
 
  ModInt &operator/=(const ModInt &p) {
    *this *= p.inverse();
    return *this;
  }
 
  ModInt operator-() const { return ModInt(-x); }
 
  ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }
 
  ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }
 
  ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }
 
  ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }
 
  bool operator==(const ModInt &p) const { return x == p.x; }
 
  bool operator!=(const ModInt &p) const { return x != p.x; }
 
  ModInt inverse() const {
    int a = x, b = mod, u = 1, v = 0, t;
    while(b > 0) {
      t = a / b;
      swap(a -= t * b, b);
      swap(u -= t * v, v);
    }
    return ModInt(u);
  }
 
  ModInt pow(int64_t n) const {
    ModInt ret(1), mul(x);
    while(n > 0) {
      if(n & 1) ret *= mul;
      mul *= mul;
      n >>= 1;
    }
    return ret;
  }
 
  friend ostream &operator<<(ostream &os, const ModInt &p) {
    return os << p.x;
  }
 
  friend istream &operator>>(istream &is, ModInt &a) {
    int64_t t;
    is >> t;
    a = ModInt< mod >(t);
    return (is);
  }
 
  static int get_mod() { return mod; }
};
 
using modint = ModInt< 1000000007 >;
template< typename T >
struct Combination {
  vector< T > _fact, _rfact, _inv;
 
  Combination(int sz) : _fact(sz + 1), _rfact(sz + 1), _inv(sz + 1) {
    _fact[0] = _rfact[sz] = _inv[0] = 1;
    for(int i = 1; i <= sz; i++) _fact[i] = _fact[i - 1] * i;
    _rfact[sz] /= _fact[sz];
    for(int i = sz - 1; i >= 0; i--) _rfact[i] = _rfact[i + 1] * (i + 1);
    for(int i = 1; i <= sz; i++) _inv[i] = _rfact[i] * _fact[i - 1];
  }
 
  inline T fact(int k) const { return _fact[k]; }
 
  inline T rfact(int k) const { return _rfact[k]; }
 
  inline T inv(int k) const { return _inv[k]; }
 
  T P(int n, int r) const {
    if(r < 0 || n < r) return 0;
    return fact(n) * rfact(n - r);
  }
 
  T C(int p, int q) const {
    if(q < 0 || p < q) return 0;
    return fact(p) * rfact(q) * rfact(p - q);
  }
 
  T H(int n, int r) const {
    if(n < 0 || r < 0) return (0);
    return r == 0 ? 1 : C(n + r - 1, r);
  }
};
 
ll modpow(ll x, ll n, ll mod) {
  ll res = 1;
  x %= mod;
  if(x == 0) return 0;
  while(n) {
    if(n&1) res = (res * x) % mod;
    x = (x * x) % mod;
    n >>= 1;
  }
  return res;
} 
inline long long mod(long long a, long long m) {
    return (a % m + m) % m;
}
template<typename T> 
struct BIT{
  int N;
  std::vector<T> node;
  BIT(){}
  BIT(int n){
    N = n;
    node.resize(N+10);
  }
  void build(int n) {
    N = n;
    node.resize(N+10);
  }
  /* a: 1-indexed */
  void add(int a, T x){
    for(int i=a; i<(int)node.size(); i += i & -i) node[i] += x;
  }

  /* [1, a] */
  T sum(int a){
    T res = 0;
    for(int x=a; x>0; x -= x & -x) res += node[x];
    return res;
  }

  /* [l, r] */
  T rangesum(int l, int r){
    return sum(r) - sum(l-1);
  }

  /* 
    a1+a2+...+aw >= valとなるような最小のwを返す
    @verify https://codeforces.com/contest/992/problem/E
  */
  int lower_bound(T val) {
    if(val < 0) return 0;

    int res = 0;
    int n = 1; 
    while (n < N) n *= 2;

    T tv=0;
    for (int k = n; k > 0; k /= 2) {
      if(res + k < N && node[res + k] < val){
        val -= node[res+k];
        res += k;
      }
    }
    return res+1; 
  }
};
struct UnionFind{
  std::vector<int> par;
  std::vector<int> siz;

  UnionFind(int sz_): par(sz_), siz(sz_) {
    for(int i=0; i<sz_; ++i) par[i] = i, siz[i] = 1;
  }

  void init(int sz_){
    par.resize(sz_);
    siz.resize(sz_);
    for(int i=0; i<sz_; ++i) par[i] = i, siz[i] = 1;
  }

  int root(int x){
    if(x == par[x]) return x;
    return par[x] = root(par[x]);
  }

  bool merge(int x, int y){
    x = root(x), y = root(y);
    if(x == y) return false;
    if(siz[x] < siz[y]) std::swap(x, y);
    siz[x] += siz[y];
    par[y] = x;
    return true;
  }

  bool issame(int x, int y){
    return root(x) == root(y);
  }

  int size(int x){
    return siz[root(x)];
  }
};
struct RollingHash{

    using ull = unsigned long long;
    const ull mod = (1ULL << 61) - 1;
    const ull MASK30 = (1ULL << 30) - 1;
    const ull MASK31 = (1ULL << 31) - 1;

    const ull MASK61 = mod;

    ull base;
    int n;
    vector<ull> hash, pow;

    RollingHash(const string &s)
    {
        random_device rnd;
        mt19937_64 mt(rnd());
        base = 1001;
        
        n = (int)s.size();
        hash.assign(n+1, 0);
        pow.assign(n+1, 1);
        
        for(int i=0; i<n; i++){
            hash[i+1] = calc_mod(mul(hash[i], base) + s[i]);
            pow[i+1] = calc_mod(mul(pow[i], base));
        }
    }

    ull calc_mod(ull x){
        ull xu = x >> 61;
        ull xd = x & MASK61;
        ull res = xu + xd;
        if(res >= mod) res -= mod;
        return res;
    }

    ull mul(ull a, ull b){
        ull au = a >> 31;
        ull ad = a & MASK31;
        ull bu = b >> 31;
        ull bd = b & MASK31;
        ull mid = ad * bu + au * bd;
        ull midu = mid >> 30;
        ull midd = mid & MASK30;
        return calc_mod(au * bu * 2 + midu + (midd << 31) + ad * bd);
    }

    //[l,r)のハッシュ値
    inline ull get(int l, int r){
        ull res = calc_mod(hash[r] + mod*3-mul(hash[l], pow[r-l]));
        return res;
    }
    //string tのハッシュ値
    inline ull get(string t){
        ull res = 0;
        for(int i=0; i<t.size(); i++){
            res = calc_mod(mul(res, base)+t[i]);
        }
        return res;
    }
    //string s中のtの数をカウント
    inline int count(string t) {
        if(t.size() > n) return 0;
        auto hs = get(t);
        int res = 0;
        for(int i=0; i<n-t.size()+1; i++){
            if(get(i, i+t.size()) == hs) res++; 
        }
        return res;
    }

    /* 
        concat 
        @verify https://codeforces.com/problemset/problem/514/C
    */
    inline ull concat(ull h1, ull h2, int h2len){
      return calc_mod(h2 + mul(h1, pow[h2len]));
    }

    // LCPを求める S[a:] T[b:]
    inline int LCP(int a, int b){
        int len = min((int)hash.size()-a, (int)hash.size()-b);
        
        int lb = -1, ub = len;
        while(ub-lb>1){
            int mid = (lb+ub)/2;

            if(get(a, a+mid) == get(b, b+mid)) lb = mid;
            else ub = mid;
        }
        return lb;
    }
};
int dist[110][1010];

int main() {  
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(12);
  
  int n, m, c;
  while(cin >> n >> m >> c) {
    if(n == 0 && m == 0 && c == 0) break;
    vector<vector<pair<int, int>>> g(n);
    REP(i,m) {
      int a, b, d; cin >> a >> b >> d;
      a--; b--;
      g[a].push_back({b, d});
    }
    REP(i,n) REP(j,m+1) dist[i][j] = 1e9;
    // iにいて変更回数がj回, これまでのコストがkであるとき
    priority_queue<pair<ll,pair<ll,ll>>, vector<pair<ll,pair<ll,ll>>>, greater<pair<ll,pair<ll,ll>>>> pq;
    pq.push({0, {0,0}});
    dist[0][0] = 0;
    while(pq.size()) {
      auto[d, p] = pq.top(); pq.pop();
      auto[t, v] = p;
      if(dist[v][t] < d) continue;
      for(auto[u, cost]: g[v]) {
        if(dist[u][t] > dist[v][t] + cost) {
          dist[u][t] = dist[v][t] + cost;
          pq.push({dist[u][t], {t, u}});
        }
        if(dist[u][t+1] > dist[v][t]) {
          dist[u][t+1] = dist[v][t];
          pq.push({dist[u][t+1], {t+1, u}});
        }
      }

    }
    int ans = 1e9;
    REP(i,m+1) if(dist[n-1][i] <= c) {
      ans = i;
      break;
    }
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 3968
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using T = tuple<int, int, int>;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    while (true) {
        int n, m, c;
        cin >> n >> m >> c;
        if (n == 0 && m == 0 && c == 0) break;
        vector<vector<pair<int, int>>> G(n);
        for (int i = 0; i < m; ++i) {
            int f, t, ci;
            cin >> f >> t >> ci;
            --f, --t;
            G[f].push_back({t, ci});
        }
        vector<vector<int>> dist(n, vector<int>(n, 1e9));  // minimum dist to i after removing j edges
        dist[0][0] = 0;
        priority_queue<T, vector<T>, greater<>> pq;
        pq.push({0, 0, 0});
        while (!pq.empty()) {
            auto [d, v, k] = pq.top();
            pq.pop();
            if (d > dist[v][k]) continue;
            for (auto [u, w] : G[v]) {
                if (k + 1 < n && d < dist[u][k+1]) {
                    dist[u][k+1] = d;
                    pq.push({d, u, k + 1});
                }
                if (d + w < dist[u][k]) {
                    dist[u][k] = d + w;
                    pq.push({d + w, u, k});
                }
            }
        }
        for (int j = 0; j < n; ++j) {
            if (dist[n-1][j] <= c) {
                cout << j << "\n";
                break;
            }
        }
    }
}
accuracy: 1
time_ms: 30
memory_kb: 3472
final_rank: 3

code_snippet: #pragma GCC ta g("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//#include <atcoder/maxflow>
//using namespace atcoder;
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 5050000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-9;
const int mod = 1e9 + 7;
//const int mod = 998244353;

int main(){
    while(1){
        int n,m,C; cin >> n >> m >> C;
        if(!n) break;
        vector<vpl> G(n);
        rep(i,m){
            int u,v,c; cin >> u >> v >> c; u--; v--;
            G[u].emplace_back(v,c);
        }
        int ok = m, ng = 0;
        vvl d(n,vl(m+1,inf));
        while(ok-ng > 1){
            int mid = (ok+ng) / 2;
            rep(i,n) rep(j,m+1) d[i][j] = inf;
            d[0][0] = 0;
            priority_queue<tapu,vector<tapu>,greater<tapu>> pq;
            pq.emplace(0,0,0);
            while(!pq.empty()){
                int c,u,t;
                tie(c,u,t) = pq.top(); pq.pop();
                if(d[u][t] < c) continue;
                for(auto v : G[u]){
                    if(chmin(d[v.first][t], c + v.second)){
                        pq.emplace(d[v.first][t], v.first, t);
                    }
                    if(t < mid && chmin(d[v.first][t+1], c)){
                        pq.emplace(d[v.first][t+1], v.first, t+1);
                    }
                }
            }
            int res = *min_element(all(d[n-1]));
            if(res <= C) ok = mid;
            else ng = mid;
        }
        cout << ok << "\n";
    }
}
accuracy: 1
time_ms: 240
memory_kb: 6456
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define ALL(x) begin(x),end(x)
#define rep(i,n) for(int i=0;i<(n);i++)
#define debug(v) cout<<#v<<":";for(auto x:v){cout<<x<<' ';}cout<<endl;
#define mod 998244353
using ll=long long;
const int INF=1000000000;
const ll LINF=1001002003004005006ll;
int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
template<class T>bool chmax(T &a,const T &b){if(a<b){a=b;return true;}return false;}
template<class T>bool chmin(T &a,const T &b){if(b<a){a=b;return true;}return false;}

struct IOSetup{
    IOSetup(){
        cin.tie(0);
        ios::sync_with_stdio(0);
        cout<<fixed<<setprecision(12);
    }
} iosetup;
 
template<typename T>
ostream &operator<<(ostream &os,const vector<T>&v){
    for(int i=0;i<(int)v.size();i++) os<<v[i]<<(i+1==(int)v.size()?"":" ");
    return os;
}
template<typename T>
istream &operator>>(istream &is,vector<T>&v){
    for(T &x:v)is>>x;
    return is;
}

int N,M,C;

// graph template
// ref : https://ei1333.github.io/library/graph/graph-template.cpp
template<typename T=int>
struct Edge{
    int from,to;
    T w;
    int idx;
    Edge()=default;
    Edge(int from,int to,T w=1,int idx=-1):from(from),to(to),w(w),idx(idx){}
    operator int() const{return to;}
};

template<typename T=int>
struct Graph{
    vector<vector<Edge<T>>> g;
    int V,E;
    Graph()=default;
    Graph(int n):g(n),V(n),E(0){}

    size_t size(){
        return g.size();
    }
    void resize(int k){
        g.resize(k);
    }
    inline const vector<Edge<T>> &operator[](int k)const{
        return (g.at(k));
    }
    inline vector<Edge<T>> &operator[](int k){
        return (g.at(k));
    }
    void add_directed_edge(int from,int to,T cost=1){
        g[from].emplace_back(from,to,cost,E++);
    }
    void add_edge(int from,int to,T cost=1){
        g[from].emplace_back(from,to,cost,E);
        g[to].emplace_back(to,from,cost,E++);
    }
    void read(int m,int pad=-1,bool weighted=false,bool directed=false){
        for(int i=0;i<m;i++){
            int u,v;cin>>u>>v;
            u+=pad,v+=pad;
            T w=T(1);
            if(weighted) cin>>w;
            if(directed) add_directed_edge(u,v,w);
            else         add_edge(u,v,w);
        }
    }
};

void solve(){
    Graph<int> G(N);
    G.read(M,-1,true,true);

    vector<vector<int>> dp(N,vector<int>(N+1,INF));
    dp[0][0]=0;
    using P=pair<int,int>;

    priority_queue<pair<int,P>,vector<pair<int,P>>,greater<pair<int,P>>> que;
    que.emplace(0,P(0,0));

    while(!que.empty()){
        auto [d,p]=que.top();que.pop();

        if(dp[p.first][p.second]<d) continue;

        for(auto &e:G[p.first]){
            if(p.second<N)if(chmin(dp[e][p.second+1],d)) que.emplace(d,P(e,p.second+1));
            if(chmin(dp[e][p.second],d+e.w)) que.emplace(d+e.w,P(e,p.second));
        }
    }

    for(int k=0;k<=N;k++){
        if(dp[N-1][k]<=C){
            cout<<k<<endl;
            return ;
        }
    }
    cout<<-1<<endl;
    return ;
}

signed main(){
    while(cin>>N>>M>>C,N and M) solve();
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3628
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define ALL(x) begin(x),end(x)
#define rep(i,n) for(int i=0;i<(n);i++)
#define debug(v) cout<<#v<<":";for(auto x:v){cout<<x<<' ';}cout<<endl;
#define mod 998244353
using ll=long long;
const int INF=1000000000;
const ll LINF=1001002003004005006ll;
int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
template<class T>bool chmax(T &a,const T &b){if(a<b){a=b;return true;}return false;}
template<class T>bool chmin(T &a,const T &b){if(b<a){a=b;return true;}return false;}

struct IOSetup{
    IOSetup(){
        cin.tie(0);
        ios::sync_with_stdio(0);
        cout<<fixed<<setprecision(12);
    }
} iosetup;
 
template<typename T>
ostream &operator<<(ostream &os,const vector<T>&v){
    for(int i=0;i<(int)v.size();i++) os<<v[i]<<(i+1==(int)v.size()?"":" ");
    return os;
}
template<typename T>
istream &operator>>(istream &is,vector<T>&v){
    for(T &x:v)is>>x;
    return is;
}

int N,M,C;

// graph template
// ref : https://ei1333.github.io/library/graph/graph-template.cpp
template<typename T=int>
struct Edge{
    int from,to;
    T w;
    int idx;
    Edge()=default;
    Edge(int from,int to,T w=1,int idx=-1):from(from),to(to),w(w),idx(idx){}
    operator int() const{return to;}
};

template<typename T=int>
struct Graph{
    vector<vector<Edge<T>>> g;
    int V,E;
    Graph()=default;
    Graph(int n):g(n),V(n),E(0){}

    size_t size(){
        return g.size();
    }
    void resize(int k){
        g.resize(k);
    }
    inline const vector<Edge<T>> &operator[](int k)const{
        return (g.at(k));
    }
    inline vector<Edge<T>> &operator[](int k){
        return (g.at(k));
    }
    void add_directed_edge(int from,int to,T cost=1){
        g[from].emplace_back(from,to,cost,E++);
    }
    void add_edge(int from,int to,T cost=1){
        g[from].emplace_back(from,to,cost,E);
        g[to].emplace_back(to,from,cost,E++);
    }
    void read(int m,int pad=-1,bool weighted=false,bool directed=false){
        for(int i=0;i<m;i++){
            int u,v;cin>>u>>v;
            u+=pad,v+=pad;
            T w=T(1);
            if(weighted) cin>>w;
            if(directed) add_directed_edge(u,v,w);
            else         add_edge(u,v,w);
        }
    }
};

template<typename T>
vector<vector<T>> WarshallFloyd(vector<vector<T>> mat, T inf=1000000100){
    int n=(int)mat.size();
    for(int k=0;k<n;k++)for(int i=0;i<n;i++)for(int j=0;j<n;j++)
    if(mat[i][k]<inf and mat[k][j]<inf) mat[i][j]=min(mat[i][j],mat[i][k]+mat[k][j]);
    return mat;
}

void solve(){
    vector<Edge<int>> E;
    vector<vector<int>> W(N,vector<int>(N,INF));
    rep(i,M){
        int u,v,c;cin>>u>>v>>c;
        u--,v--;
        E.emplace_back(u,v,c,0);
        chmin(W[u][v],c);
    }

    sort(ALL(E),[](Edge<int> a,Edge<int> b){return a.w<b.w;});
    reverse(ALL(E));

    W=WarshallFloyd(W);


    for(auto &e:E){
        chmin(W[e.from][e.to],0);
        e.idx=1;

        for(int i=0;i<N;i++)for(int j=0;j<N;j++)
            chmin(W[i][j],W[i][e.from]+W[e.to][j]);

        if(W[0][N-1]<=C) break;
    }
    
    Graph<int> G(N);
    for(auto &e:E) G.g[e.from].push_back(e);
    

    vector<vector<int>> dp(N,vector<int>(N+1,INF));
    dp[0][0]=0;
    using P=pair<int,int>;

    priority_queue<pair<int,P>,vector<pair<int,P>>,greater<pair<int,P>>> que;
    que.emplace(0,P(0,0));

    while(!que.empty()){
        auto [d,p]=que.top();que.pop();

        if(dp[p.first][p.second]<d) continue;

        for(auto &e:G[p.first]){
            if(p.second<N)if(chmin(dp[e][p.second+1],d)) que.emplace(d,P(e,p.second+1));
            if(chmin(dp[e][p.second],d+e.w)) que.emplace(d+e.w,P(e,p.second));
        }
    }

    for(int k=0;k<=N;k++){
        if(dp[N-1][k]<=C){
            cout<<k<<endl;
            return ;
        }
    }
    cout<<-1<<endl;
    return ;
}

signed main(){
    while(cin>>N>>M>>C,N and M) solve();
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 3664
final_rank: 11

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define eps 1e-9
#define INF 2000000000              // 2e9
#define LLINF 2000000000000000000ll // 2e18 (llmax:9e18)
#define all(x) (x).begin(), (x).end()
#define sq(x) ((x) * (x))

#define rep(i, x) for (int i = 0; i < (int)(x); i++)
#define drep(i, x) for (int i = ((int)(x)-1); i >= 0; i--)

#define popcount __builtin_popcount
#define next __next
#define prev __prev

#ifndef LOCAL
#define dmp(...) ;
#else
#define dmp(...)                                                               \
  cerr << "[ " << #__VA_ARGS__ << " ] : " << dump_str(__VA_ARGS__) << endl
#endif

// ---------------- Utility ------------------

template <class T>
bool chmin(T &a, const T &b) {
  if (a <= b) return false;
  a = b;
  return true;
}
template <class T>
bool chmax(T &a, const T &b) {
  if (a >= b) return false;
  a = b;
  return true;
}

template <class T>
using MaxHeap = priority_queue<T>;
template <class T>
using MinHeap = priority_queue<T, vector<T>, greater<T>>;

template <class T>
vector<T> vect(int len, T elem) {
  return vector<T>(len, elem);
}

// ----------------- Input -------------------

template <class T, class U>
istream &operator>>(istream &is, pair<T, U> &p) {
  return is >> p.first >> p.second;
}

template <class T>
istream &operator>>(istream &is, vector<T> &vec) {
  for (int i = 0; i < vec.size(); i++) is >> vec[i];
  return is;
}

// ----------------- Output ------------------

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << p.first << ',' << p.second;
}

template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (const T &e : v) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const deque<T> &d) {
  for (const T &e : d) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const set<T> &s) {
  os << "{ ";
  for (const T &e : s) os << e << " ";
  return os << "}";
}

template <class T, class U>
ostream &operator<<(ostream &os, const map<T, U> &m) {
  os << "{ ";
  for (const auto &[key, val] : m) os << "( " << key << " -> " << val << " ) ";
  return os << "}";
}

template <class TupleTy, size_t... I>
void dump_tuple(ostream &os, const TupleTy t, std::index_sequence<I...>) {
  (..., (os << (I == 0 ? "" : ",") << std::get<I>(t)));
}

template <class... Args>
ostream &operator<<(ostream &os, const tuple<Args...> &t) {
  os << "(";
  dump_tuple(os, t, std::make_index_sequence<sizeof...(Args)>());
  return os << ")";
}

void dump_str_rec(ostringstream &) {}

template <class Head, class... Tail>
void dump_str_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << ", " << head;
  dump_str_rec(oss, forward<Tail>(tail)...);
}

template <class T, class... U>
string dump_str(T &&arg, U &&... args) {
  ostringstream oss;
  oss << arg;
  dump_str_rec(oss, forward<U>(args)...);
  return oss.str();
}

// --------------- Fast I/O ------------------

void fastio() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cout << fixed << setprecision(20);
}

// ------------------ ACL --------------------

// #include <atcoder/modint>
// constexpr int MOD = 998244353;
// constexpr int MOD = 1000000007;
// using mint = atcoder::static_modint<MOD>;
// ostream &operator<<(ostream &os, const mint &v) {
//   return os << v.val();
// }

// ------------ End of template --------------

#define endl "\n"
using ll = long long;
using pii = pair<int, int>;

template <class Cost = int>
struct edge {
  int from, to;
  Cost cost;
  edge() {}
  edge(int from, int to, Cost cost) : from(from), to(to), cost(cost) {}

  // for debug
  friend ostream &operator<<(ostream &os, const edge &e) {
    os << e.from << " -> " << e.to << " : " << e.cost << ", ";
    return os;
  }
};

template <class Cost = int>
struct Graph {
  int V;
  vector<vector<edge<Cost>>> G;
  Graph() {}
  Graph(int V) : V(V) { G.resize(V); }
  void add_edge(int a, int b, Cost cost = Cost(0)) {
    G[a].push_back(edge<Cost>(a, b, cost));
  }
  void add_edge_undirected(int a, int b, Cost cost = Cost(0)) {
    G[a].push_back(edge<Cost>(a, b, cost));
    G[b].push_back(edge<Cost>(b, a, cost));
  }
  size_t size() const { return G.size(); }
  const vector<edge<Cost>> &operator[](int id) const { return G[id]; }

  // for debug
  friend ostream &operator<<(ostream &os, const Graph g) {
    for (int i = 0; i < g.size(); i++) {
      os << g[i];
      if (i + 1 < g.size()) os << endl;
    }
    return os;
  }
};

// verified
// https://atcoder.jp/contests/dwacon6th-final-open/submissions/10023433
template <class Cost>
vector<Cost> dijkstra(Graph<Cost> &g, int s) {
  assert(0 <= s && s < g.size());
  vector<Cost> dist;
  dist.assign(g.size(), numeric_limits<Cost>::max());
  dist[s] = Cost(0);
  MinHeap<pair<Cost, int>> q;
  q.push(make_pair(Cost(0), s));
  while (!q.empty()) {
    auto a = q.top();
    q.pop();
    int v = a.second;
    if (dist[v] < a.first) continue;
    for (auto e : g[v]) {
      if (dist[e.to] > dist[v] + e.cost) {
        dist[e.to] = dist[v] + e.cost;
        q.push(make_pair(dist[e.to], e.to));
      }
    }
  }
  return dist;
}

bool solve() {
  int n, m, c;
  cin >> n >> m >> c;
  if (n + m + c == 0) return false;
  Graph<int> g(n * (m + 1));
  for (int i = 0; i < m; i++) {
    int a, b, cost;
    cin >> a >> b >> cost;
    a--;
    b--;
    for (int j = 0; j < m; j++) {
      g.add_edge(j * n + a, j * n + b, cost);
      g.add_edge(j * n + a, (j + 1) * n + b, 0);
    }
  }
  auto dist = dijkstra(g, 0);
  for (int i = 0; i <= m; i++) {
    if (dist[i * n + n - 1] <= c) {
      cout << i << endl;
      return true;
    }
  }
  assert(false);
  return true;
}

int main() {
  fastio();
  // solve();
  while (solve()) {}
  // int t; cin >> t; while(t--)solve();

  // int t; cin >> t;
  // for(int i=1;i<=t;i++){
  //   cout << "Case #" << i << ": ";
  //   solve();
  // }
  return 0;
}
accuracy: 1
time_ms: 680
memory_kb: 43084
final_rank: 18

code_snippet: //#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long ull;
 
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
	return (ull)rng() % B;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n,m,c;
    while(cin >> n >> m >> c,n+m+c){
        vector<vector<pair<int,int>>> g(n);
        for(int i=0;i<m;i++){
            int x,y,w; cin >> x >> y >> w;
            x--; y--;
            g[x].push_back({y,w});
        }
        vector<vector<int>> d(n,vector<int>(n+1,1e9));
        d[0][0]=0;
        priority_queue<pair<int,pair<int,int>>> pq;
        pq.push(make_pair(0,make_pair(0,0)));
        while(pq.size()){
            auto p=pq.top(); pq.pop();
            if(-p.first!=d[p.second.first][p.second.second])continue;
            for(auto to:g[p.second.first]){
                int t=to.first;
                if(d[t][p.second.second]>-p.first+to.second){
                    d[t][p.second.second]=-p.first+to.second;
                    pq.push(make_pair(-d[t][p.second.second],make_pair(t,p.second.second)));
                }
                if(p.second.second+1>n)continue;
                if(d[t][p.second.second+1]>-p.first){
                    d[t][p.second.second+1]=-p.first;
                    pq.push(make_pair(p.first,make_pair(t,p.second.second+1)));
                }
            }
        }
        for(int i=0;i<=n;i++){
            if(c>=d[n-1][i]){
                cout << i << endl;
                break;
            }
        }
    }    
}
accuracy: 1
time_ms: 60
memory_kb: 3272
final_rank: 8

code_snippet: #include<cstdio>
#include<vector>
#include<queue>
#include<map>
#include<algorithm>
using namespace std;
using P = pair<int, int>;
using Q = pair<int, P>;
constexpr int INF = 1000000000;

int n, m, c, x, y, z;
vector<P> e[100];
int mn[100][101];

int main() {
  while (scanf("%d%d%d", &n, &m, &c), n) {
    for (int i = 0; i < n; i++) {
      e[i].clear();
      for (int j = 0; j <= n; j++) mn[i][j] = INF;
    }
    for (int i = 0; i < m; i++) {
      scanf("%d%d%d", &x, &y, &z);
      x--; y--;
      e[x].push_back(P(y, z));
    }
    priority_queue<Q, vector<Q>, greater<Q>> pq; // (cost, P(num, minas))
    pq.push(Q(0, P(0, 0)));
    for (int i = 0; i <= n; i++) mn[0][i] = 0;
    while (!pq.empty()) {
      Q tmp = pq.top(); pq.pop();
      int num = tmp.second.first, minas = tmp.second.second;
      if (mn[num][minas] < tmp.first) continue;
      for (P p : e[num]) {
        if (mn[p.first][minas] > mn[num][minas] + p.second) {
          mn[p.first][minas] = mn[num][minas] + p.second;
          pq.push(Q(mn[p.first][minas], P(p.first, minas)));
        }
        if (minas < n && mn[p.first][minas+1] > mn[num][minas]) {
          if (mn[num][minas] >= mn[p.first][minas]) continue;
          mn[p.first][minas+1] = mn[num][minas];
          pq.push(Q(mn[p.first][minas+1], P(p.first, minas+1)));
        }
      }
    }
    int ans = 0;
    while (mn[n-1][ans] > c) ans++;
    printf("%d\n", ans);
  }
}
accuracy: 1
time_ms: 30
memory_kb: 2860
final_rank: 1