Problem:
Problem C:
Brave Princess Revisited
ある貧乏な国のおてんばで勇敢なお姫様が，政略結婚のため別の国に嫁ぐことになった．ところがお姫様を亡き者としようとしている悪漢が嫁ぎ先への道の途中で刺客を放っている．
お姫様を無事に相手国に送り届けるため，あなたは安全な経路を既に決定していたのだが，お姫様の今までに通ったことのない道を通ってみたいという
わがままな
たっての願いで別の道を通ることとなった．そこであなたは地図を見ながらお姫様が通る道を決めなおすことにした．
全ての道は，宿場同士をつなぐ街道である．便宜上，出発地点及び目的地点も宿場とする．ところが，新しい道は治安の問題を抱えていた．盗賊やお姫様を亡き者にしようとする刺客が襲いかかってくる可能性が高いのである．
そのような危険な道を通るには護衛を雇うことが望ましい．護衛は宿場で雇うことができ，道単位で姫を守らせることができる．護衛が守っている間は盗賊や刺客に襲われることはないが，距離 1 につき金 1 がかかる．そのため，護衛を雇うためには所持金よりも次の宿場までの距離が長くないことが条件となる．
いま，与えられた予算
L
のもとで，姫が無事に目的地に着くまでに襲いかかってくる盗賊や刺客の人数を最小化することを考える．あなたの仕事は，その最小化された人数を求めることである．なお，宿場にいる間に襲われることはないものとする．
Input
入力は複数のデータセットからなる．各データセットは次の形式をしている．
N
M
L
A
1
B
1
D
1
E
1
A
2
B
2
D
2
E
2
...
A
M
B
M
D
M
E
M
最初の行には 3 つの非負の整数
N
(2 ≤
N
≤ 100)，
M
，
L
(0 ≤
L
≤ 100) が与えられる．これらの整数は，宿場の数，道の数，護衛を雇うための予算を表す．宿場には 1 から
N
までの番号が割り振られており，出発地には 1 ，目的地には
N
の番号がそれぞれ割り振られている．
続く
M
行では道の情報が各行に 1 つずつ与えられる．道の情報は 4 つの整数
A
i
，
B
i
(1 ≤
A
i
<
B
i
≤ N)，
D
i
(1 ≤
D
i
≤ 100)
E
i
(0 ≤
E
i
≤ 10000) で与えられる．これらはそれぞれ，道の始点と終点の宿場の番号，道の距離，盗賊や刺客に襲われる人数を表す．
道は双方向に通行可能であり，かつある宿場の組に対しては高々 1 つの道しか存在しない．また，出発地から目的地には必ず移動可能であることが保証されている．
入力の終わりは，空白で区切られた 3 つの 0 を含む 1 行で示される．
Output
各データセットについて，盗賊や刺客に襲われる人数の最小値を各行に出力せよ．出力に余計な空白や改行を含めてはならない．
Sample Input
3 2 10
1 2 8 6
2 3 10 3
3 2 10
1 2 3 8
2 3 7 7
3 3 10
1 3 17 6
1 2 2 4
2 3 9 13
4 4 5
1 3 9 3
1 4 7 25
2 3 8 2
2 4 9 3
0 0 0
Output for the Sample Input
3
0
4
8

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
      
#define FOR(i,a,b) for( ll i = (a); i < (ll)(b); i++ )
#define REP(i,n) FOR(i,0,n)
#define YYS(x,arr) for(auto& x:arr)
#define ALL(x) (x).begin(),(x).end()
#define SORT(x) sort( (x).begin(),(x).end() )
#define REVERSE(x) reverse( (x).begin(),(x).end() )
#define UNIQUE(x) (x).erase( unique( ALL( (x) ) ) , (x).end() )
#define PW(x) (1LL<<(x))
#define SZ(x) ((ll)(x).size())
#define SHOW(x) cout << #x << " = " << x << endl
#define SHOWA(x,n) for( int yui = 0; yui < n; yui++ ){ cout << x[yui] << " "; } cout << endl

#define pb emplace_back
#define fi first
#define se second

using namespace std;

typedef long double ld;
typedef long long int ll;
typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<bool> vb;
typedef vector<ld> vd;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<vpl> gr;
typedef vector<vl> ml;
typedef vector<vd> md;
typedef vector<vi> mi;
     
const ll INF = (ll)1e9 + 10;
const ll INFLL = (ll)1e18 + 10;
const ld EPS = 1e-12;
const ll MOD = 1e9+7;
     
template<class T> T &chmin( T &a , const T &b ){ return a = min(a,b); }
template<class T> T &chmax( T &a , const T &b ){ return a = max(a,b); }
template<class T> inline T sq( T a ){ return a * a; }

ll in(){ long long int x; scanf( "%lld" , &x ); return x; }
char yuyushiki[1000010]; string stin(){ scanf( "%s" , yuyushiki ); return yuyushiki; }

// head


template<typename T>
struct Dijkstra{
  typedef pair<int,T> pit;
  typedef pair<T,int> pti;  
  const T INFT;
  vector<vector<pit> > G;
  vector<T> dist;
  int n;
  Dijkstra( T INFT ) : INFT(INFT) {}
  void init( int arg_n ){
    n = arg_n;
    G = vector<vector<pit> >( n , vector<pit>(0) );
  }
  void add_biedge( int fr , int to , T co ){
    G[fr].pb( to , co );
    G[to].pb( fr , co );
  }
  void add_edge( int fr , int to , T co ){
    G[fr].pb( to , co );
  }
  T dijkstra( int s , int t = -1 ){
    dist = vector<T>( n , INFT );
    dist[s] = 0;
    priority_queue<pti,vector<pti>,greater<pti> > que;
    que.emplace( 0 , s );
    while( !que.empty() ){
      T d = que.top().fi;
      int p = que.top().se;
      que.pop();
      if( d > dist[p] ){
	continue;
      }
      if( p == t ){
	return d;
      }
      YYS( w , G[p] ){
	int to = w.fi;
	T co = w.se;
	if( d + co < dist[to] ){
	  dist[to] = d + co;
	  que.emplace( dist[to] , to );
	}
      }
    }
    return INFT;
  }
};

Dijkstra<int> dij(INF);

int n, m, l;

int p( int pos , int mon ){
  assert( 0 <= mon && mon <= l );
  return pos * ( l + 1 ) + mon;
}

int main(){

  while( 1 ){
    n = in();
    m = in();
    l = in();
    if( n == 0 && m == 0 && l == 0 ){
      break;
    }
    dij.init( n * ( l + 1 ) );
    REP( cnt , m ){
      int a = in() - 1;
      int b = in() - 1;
      int d = in();
      int e = in();
      REP( i , l+1 ){
        dij.add_edge( p( a , i ) , p( b , i ) , e );
        dij.add_edge( p( b , i ) , p( a , i ) , e );
        if( i - d >= 0 ){
          dij.add_edge( p( a , i ) , p( b , i-d ) , 0 );
          dij.add_edge( p( b , i ) , p( a , i-d ) , 0 );
        }
      }
    }
    REP( i , n ){
      REP( j , l ){
        dij.add_edge( p( i , j+1 ) , p( i , j ) , 0 );
      }
    }
    printf( "%d\n" , dij.dijkstra( p( 0 , l ) , p( n-1 , 0 ) ) );
  }
  
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 8572
final_rank: 11

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

constexpr long long INF = 2e18;

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

    while (true) {
        int N, M, L;
        cin >> N >> M >> L;

        if (N == 0)
            return 0;

        // N * l + v
        auto enc = [&](int v, int l) -> int { return N * l + v; };

        vector<vector<array<int, 2>>> G(N * (L + 1));
        for (int i = 0; i < M; i++) {
            int a, b, d, e;
            cin >> a >> b >> d >> e;
            a--;
            b--;
            for (int j = 0; j <= L; j++) {
                G[enc(a, j)].push_back({enc(b, j), e});
                G[enc(b, j)].push_back({enc(a, j), e});
                if (j - d >= 0) {
                    G[enc(a, j)].push_back({enc(b, j - d), 0});
                    G[enc(b, j)].push_back({enc(a, j - d), 0});
                }
            }
        }

        vector<long long> dist(N * (L + 1), INF);
        dist[enc(0, L)] = 0;
        priority_queue<array<long long, 2>> pq;
        pq.push({0, enc(0, L)});

        while (pq.size()) {
            auto [d, v] = pq.top();
            pq.pop();
            d *= -1;
            if (d > dist[v])
                continue;
            for (auto [nv, c] : G[v]) {
                if (dist[nv] <= dist[v] + c)
                    continue;
                dist[nv] = dist[v] + c;
                pq.push({-dist[nv], nv});
            }
        }

        long long ans = INF;
        for (int i = 0; i <= L; i++) {
            ans = min(ans, dist[enc(N - 1, i)]);
        }

        cout << ans << "\n";
    }

    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 9584
final_rank: 12

code_snippet: #include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;
using namespace atcoder;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define rrep(i,start,end) for (ll i = start;i >= (ll)(end);i--)
#define repn(i,end) for(ll i = 0; i <= (ll)(end); i++)
#define reps(i,start,end) for(ll i = start; i < (ll)(end); i++)
#define repsn(i,start,end) for(ll i = start; i <= (ll)(end); i++)
#define each(p,a) for(auto &p:a)
typedef vector<ll> vll;
typedef vector<pair<ll ,ll>> vpll;
typedef vector<vector<ll>> vvll;
typedef set<ll> sll;
typedef map<ll , ll> mpll;
typedef pair<ll ,ll> pll;
typedef tuple<ll , ll , ll> tpl3;
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define Str(...) string __VA_ARGS__; input(__VA_ARGS__)
#define Ch(...) char __VA_ARGS__; input(__VA_ARGS__)
#define all(a)  (a).begin(),(a).end()
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define sz(x) (ll)x.size()
// << std::fixed << std::setprecision(10)
const ll INF = 1LL << 60;
const ld EPS = 1e-9;
 
ll lceil(ll a,ll b){if(a%b==0){return a/b;}if(a>=0){return (a/b)+1;}else{return -((-a)/b);}}
ll lfloor(ll a,ll b){if(a%b==0){return a/b;}if(a>=0){return (a/b);}else{return -((-a)/b)-1;}}
inline ll positive_mod(ll a,ll m){return (a % m + m)%m;}
inline ll popcnt(ull a){ return __builtin_popcountll(a);}
//0indexed
inline ll topbit(ll a){assert(a != 0);return 63 - __builtin_clzll(a);}
inline ll smlbit(ll a){assert(a != 0);return __builtin_ctzll(a);}
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<typename T> std::istream &operator>>(std::istream&is,std::vector<T>&v){for(T &in:v){is>>in;}return is;}
template<typename T> std::ostream &operator<<(std::ostream&os,const std::vector<T>&v){for(auto it=std::begin(v);it!=std::end(v);){os<<*it<<((++it)!=std::end(v)?" ":"");}return os;}
template<typename T1, typename T2>std::ostream &operator<< (std::ostream &os, std::pair<T1,T2> p){os << "{" << p.first << "," << p.second << "}";return os;}
template<class... T>void input(T&... a){(cin >> ... >> a);}
void print(){cout << endl;}
template<class T, class... Ts>void print(const T& a, const Ts&... b){cout << a;((cout << ' ' << b), ...);cout << endl;}
template<class T> void pspace(const T& a){ cout << a << ' ';}
void perr(){cerr << endl;}
template<class T, class... Ts>void perr(const T& a, const Ts&... b){cerr << a;((cerr << ' ' << b), ...);cerr << endl;}
void yes(bool i = true){ return print(i?"yes":"no"); }
void Yes(bool i = true){ return print(i?"Yes":"No"); }
void YES(bool i = true){ return print(i?"YES":"NO"); }
template <class T> vector<T> &operator++(vector<T> &v) {for(auto &e : v) e++;return v;}
template <class T> vector<T> operator++(vector<T> &v, signed) {auto res = v;for(auto &e : v) e++;return res;}
template <class T> vector<T> &operator--(vector<T> &v) {for(auto &e : v) e--;return v;}
template <class T> vector<T> operator--(vector<T> &v, signed) {auto res = v;for(auto &e : v) e--;return res;}
//grid探索用
vector<ll> _ta = {0,0,1,-1,1,1,-1,-1};
vector<ll> _yo = {1,-1,0,0,1,-1,1,-1};
bool isin(ll now_i,ll now_j,ll h,ll w){return (0<=now_i && now_i < h && 0 <= now_j && now_j < w);}
  
ll lpow(ll x,ll n){ll ans = 1;while(n >0){if(n & 1)ans *= x;x *= x;n >>= 1;}return ans;}
ll Modlpow(ll x,ll n,ll m){ll ans = 1;ll a = x%m;while(n >0){if(n & 1){ans *= a;ans%= m;}a *= a;a %= m;n >>= 1;}return ans;} 
const ll MOD9 = 998244353LL;
const ll MOD10 = 1000000007LL;
 
int main(){
  ios::sync_with_stdio(false);cin.tie(nullptr);
  while(true){
    LL(n,m,l);
    if(n == 0 && m == 0 && l == 0)break;
    vector<vector<tpl3>> g(n);
    rep(i,m){
      LL(a,b,d,e);
      a--;b--;
      g[a].emplace_back(b,d,e);
      g[b].emplace_back(a,d,e);
    }
    vector<vector<ll>> dist(n,vll(l+1,INF));
    priority_queue<tpl3,vector<tpl3>,greater<tpl3>> pq;
    //0からの距離が入る
    //01BFSのときは更新の判定のところを変更する
    dist[0][l] = 0;
    pq.emplace(dist[0][l],0,l);
    while(!pq.empty()){
      auto [num,v,rem] = pq.top();
      pq.pop();
      if(dist[v][rem] > num)continue;

      for(auto &[to,d,e]:g[v]){
        //sonomama
        if(chmin(dist[to][rem],num + e)){
          pq.push({dist[to][rem],to,rem});
        }
        if(d <= rem){
          if(chmin(dist[to][rem-d],num)){
            pq.push({dist[to][rem-d],to,rem-d});
          }
        }
      }
    }
    cout << *min_element(all(dist[n-1])) << endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 4948
final_rank: 2

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

bool solve() {
    int N, M, L;
    cin >> N >> M >> L;
    if (N == 0 && M == 0 && L == 0) return false;
    vector<vector<tuple<int, int, int>>> G(N);
    for (int a, b, d, e; M--; ) {
        cin >> a >> b >> d >> e;
        a--, b--;
        G[a].emplace_back(b, d, e);
        G[b].emplace_back(a, d, e);
    }
    vector<vector<int>> D(N, vector<int>(L + 1, 1 << 30));
    D[0][L] = 0;
    using T = tuple<int, int, int>;
    priority_queue<T, vector<T>, greater<T>> q;
    q.emplace(0, 0, L);
    while (q.size()) {
        auto [d, u, l] = q.top();
        q.pop();
        for (auto [v, w, e] : G[u]) {
            if (D[v][l] > d + e) {
                D[v][l] = d + e;
                q.emplace(d + e, v, l);
            }
            if (l >= w && D[v][l - w] > d) {
                D[v][l - w] = d;
                q.emplace(d, v, l - w);
            }
        }
    }
    // for (int i = 0; i < N; i++) {
    //     for (int l = 0; l <= L; l++) {
    //         cout << D[i][l] << " \n"[l == L];
    //     }
    // }
    cout << *min_element(D.back().begin(), D.back().end()) << '\n';
    return true;
}

int main() {
    while (solve()) {}
}
accuracy: 1
time_ms: 20
memory_kb: 4096
final_rank: 7

code_snippet: //#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i,n) for (ll i=0;i<(ll)n;i++)
#define rrep(i,n) for (ll i=n-1;i>=(ll)0;i--)
#define loop(i,m,n) for(ll i=m;i<=(ll)n;i++)
#define rloop(i,m,n) for(ll i=m;i>=(ll)n;i--)
#define vl vector<long long>
#define vvl vector<vector<long long>>
#define vdbg(a) rep(ii,a.size()){cout<<a[ii]<<" ";}cout<<endl;
#define vvdbg(a) rep(ii,a.size()){rep(jj,a[ii].size()){cout<<a[ii][jj]<<" ";}cout<<endl;}
#define setdbg(a) for(const auto & ii:a){cout<<ii<<" ";}cout<<endl;
#define inf 4000000000000000000LL
#define mod 998244353LL
#define eps 0.000000001
//#define mod 1000000007LL
random_device rnd;// 非決定的な乱数生成器
mt19937 mt(rnd());// メルセンヌ・ツイスタの32ビット版、引数は初期シード

//#include<boost/multiprecision/cpp_int.hpp>
//#define bbi boost::multiprecision::cpp_int

//#include<atcoder/lazysegtree>

//√の値が整数かを調べる
bool isSqrt(ll n) {
	if (n < 0) return false;
	ll sqrtN = static_cast<ll>(sqrt(n));
	return sqrtN * sqrtN == n;
}

//整数同士の累乗の計算をする。
ll power(ll A, ll B) {
	ll result = 1;
	for (ll i=0;i<B;i++){
		result *= A;
	}
	return result;
}

//素因数分解
vector<ll> makePrime(ll n){
	vector<ll> factors;
	while (n % 2 == 0) {
		factors.push_back(2);
		n /= 2;
	}
	for (ll i=3; i*i<=n;i+=2) {
		while (n%i == 0) {
			factors.push_back(i);
			n /= i;
		}
	}
	if (n > 2) {
		factors.push_back(n);
	}
	return factors;
}

//map形式で、nを素因数分解した値を返す
map<ll,ll> makeMapPrime(ll n){
	map<ll,ll> factors;
	while (n % 2 == 0) {
		factors[2]++;
		n /= 2;
	}
	for (ll i=3; i*i<=n;i+=2) {
		while (n%i == 0) {
			factors[i]++;
			n /= i;
		}
	}
	if (n > 2) {
		factors[n]++;
	}
	return factors;
}

// nのk乗をmodで割った余りを計算
ll power_mod(ll n, ll k){
	long long result = 1;
	while (k > 0){
		if ((k&1) ==1)result=(result*n)%mod;
		n=n*n%mod;
		k >>= 1;
	}
	return result;
}

//mod mにおけるaの逆元を計算
ll modinv(ll a, ll m) {
	ll b = m, u = 1, v = 0;
	while (b) {
		ll t = a / b;
		a -= t * b; swap(a, b);
		u -= t * v; swap(u, v);
	}
	u %= m; 
	if (u < 0) u += m;
	return u;
}

//場合の数 nCr を求める
ll ncr(ll n,ll r) {
	if(n<r)return 0;
	vvl dp(n+1,vl(r+1));
	rep (i,n+1)dp[i][0] = 1;
	rep (i,r+1)dp[i][i] = 1;
	loop (i,1,n){
		loop (j,1,min((ll)i-1,r)) {
			//nCr= n-1Cr-1 + n-1Cr
			dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
		}
	}
	return dp[n][r];
}

//受け取った文字列を、第2引数が0なら全て小文字に、1なら大文字に変換する関数
string cnvString(const string &str, int mode) {
	string result = str;
	if (mode == 0) {
		// 小文字に変換
		for (char &c : result) {
			c = tolower(c);
		}
	} else if (mode == 1) {
		// 大文字に変換
		for (char &c : result) {
			c = toupper(c);
		}
	}
	return result;
}

//第一引数で受け取った数を、第二引数で受け取った数の進数と見做して、第三引数の進数へ変換する。
string cnvBase(const string &str, ll from_base, ll to_base) {
	ll num = 0;
	//小文字があったら大文字に変換
	string num_str=cnvString(str,1);
	// 数値を10進数に変換
	for (char digit : num_str) {
		num = num * from_base + (isdigit(digit) ? digit - '0' : digit - 'A' + 10);
	}
	string result;
	// 数値を目的の基数に変換
	while (num > 0) {
		ll remainder = num % to_base;
		result.push_back(remainder < 10 ? remainder + '0' : remainder - 10 + 'A');
		num /= to_base;
	}
	// 結果を逆順にして返す
	reverse(result.begin(), result.end());
	return result.empty() ? "0" : result;
}

//底がaの対数xを計算。ただし小数点は繰り上げ。
ll logax(ll a, ll x){
	if(x<=1)return 0;
	ll result = 1;
	ll power = 1;
	while (power < (x+a-1) / a){
		power *= a;
		result++;
	}
	return result;
}

//第一引数を第二引数で割った余りを計算、割る数はint範囲
ll bigmd(const string &num, int md) {
	ll ans = 0;
	ll SIZ = 9; //9桁のチャンク
	ll base = 1000000000;//SIZ個の0
	rep(i,(num.size()-1)/SIZ+1){
		ll chunk = 0;
		ll l = i*SIZ;
		ll r = min((ll)num.size(),l+SIZ);
		if(r!=num.size()){
			ans = (ans*base+stoll(num.substr(l,r-l)))%md;
		}else{
			rep(i,r-l)ans*=10;
			ans=(ans+stoll(num.substr(l,r-l)))%md;
		}
	}
	return ans;
}

//受け取った2次元文字の外側に、文字pをコーティングする。
vector<string> pad(vector<string> &s,char p){
	ll h=s.size();
	ll w=s[0].size();
	vector<string> res(h+2,string(w+2,p));
	rep(i,h)rep(j,w)res[i+1][j+1]=s[i][j];
	return res;
}

//ax+by=cの整数解を得る ただし、cはgcd(a,b)の倍数でない場合、0,0になる
pair<ll,ll> ex_euclid(ll a,ll b,ll c){
	if(a<0||b<0||c<0){
		pair<ll,ll>ans=ex_euclid(abs(a),abs(b),abs(c));
		if(a<0)ans.first*=-1;
		if(b<0)ans.second*=-1;
		if(c<0)ans.first*=-1,ans.second*=-1;
		return ans;
	}
	if(c!=1){
		ll d=gcd(a,b);
		if(c%d!=0)return make_pair(0,0);
		pair<ll,ll>ans = ex_euclid(a/d,b/d,1);
		ans.first*=c/d;
		ans.second*=c/d;
		return ans;
	}
	if(a<b){
		pair<ll,ll>ans=ex_euclid(b,a,c);
		swap(ans.first,ans.second);
		return ans;
	}
	if(a==1&&b==0)return make_pair(1,0);
	else if(b==0) return make_pair(0,0);
	ll x,y;
	tie(x,y)=ex_euclid(b,a%b,c);
	pair<ll,ll> ans=make_pair(y,x-(a/b)*y);
	return ans;
}

//オイラーのトーシェント関数。N以下のNと互いに素な物の数を返す。
ll euler(ll n){
	unordered_map<ll,ll> factors;
	ll tmp=n;
	while (tmp % 2 == 0) {
		factors[2]++;
		tmp /= 2;
	}
	for (ll i=3; i*i<=tmp;i+=2) {
		while (tmp%i == 0) {
			factors[i]++;
			tmp/= i;
		}
	}
	if (tmp > 2)factors[tmp]++;
	ll ans=1;
	for(const auto & val:factors){
		ans*=power(val.first,val.second-1)*(val.first-1);
	}
	return ans;
}

// Union-Find
struct UnionFind {
	vector<int> par, siz;
	UnionFind(int n) : par(n, -1) , siz(n, 1) { }
	// 根を求める
	int root(int x) {
		if (par[x] == -1) return x;
		else return par[x] = root(par[x]);
	}
	// x と y が同じグループに属するかどうか (根が一致するかどうか)
	bool issame(int x, int y) {
		return root(x) == root(y);
	}
	// x を含むグループと y を含むグループとを併合する
	bool unite(int x, int y) {
		x = root(x), y = root(y);
		if (x == y) return false; 
		if (siz[x] < siz[y]) swap(x, y);
		par[y] = x;
		siz[x] += siz[y];
		return true;
	}
	// x を含むグループのサイズ
	int size(int x) {
		return siz[root(x)];
	}
};

//重み付きUF
struct PotentialUnionFind {
	ll n;
	vl par, siz, pot;
	PotentialUnionFind(ll N) : par(N,-1) , siz(N,1) , pot(N,0){n=N;}
	// 根を求める
	ll root(ll x) {
		if (par[x] == -1) return x;
		ll tmp = root(par[x]);
		pot[x] += pot[par[x]];
		par[x] = tmp;
		return par[x];
	}
	// x と y が同じグループに属するかどうか (根が一致するかどうか)
	bool issame(ll x, ll y) {
		return root(x) == root(y);
	}
	//x よりいくつ大きい所に y があるか。根が一致しない場合は"0"
	ll potential(ll x,ll y){
		if(root(x) != root(y)) return 0;
		else return pot[y]-pot[x];
	}
	//x より w だけ大きい状態として y を併合。
	bool unite(ll x, ll y, ll w) {
		ll rx = root(x),ry = root(y);
		if (rx == ry) return false;
		w += pot[x]-pot[y];
		if (siz[rx] < siz[ry]) swap(rx, ry),w*=-1;
		par[ry] = rx;
		siz[rx] += siz[ry];
		siz[ry] = 0;
		pot[ry] = w;
		return true;
	}
	// x を含むグループのサイズ
	ll size(ll x) {
		return siz[root(x)];
	}
	//小さい順にUnionFindグラフを調整、O(n log n)
	void regulation(){
		vvl r(n);
		rep(i,n)r[root(i)].push_back(i);
		rep(i,n){
			if(r[i].size()==0)continue;
			ll mn = i;
			rep(j,r[i].size())if(pot[mn]>pot[r[i][j]])mn=r[i][j];
			siz[mn]=siz[i];
			siz[i]=0;
			ll tmp = pot[mn];
			rep(j,r[i].size()){
				pot[r[i][j]]-=tmp;
				par[r[i][j]] = mn;
			}
			par[mn]=-1;
		}
	}
	void debug(){
		rep(i,n)cout<<setw(4)<<left<<par[i]<<" ";
		cout<<endl;
		rep(i,n)cout<<setw(4)<<left<<pot[i]<<" ";
		cout<<endl;
	}
};

//分離可能UnionFind、経路圧縮をしない。
struct CuttingFind{
	vector<int> par, siz;
	CuttingFind(int n) : par(n, -1) , siz(n, 1) { }
	// 根を求める
	int root(int x) {
		if (par[x] == -1) return x;
		else return root(par[x]);
	}
	// x と y が同じグループに属するかどうか (根が一致するかどうか)
	bool issame(int x, int y) {
		return root(x) == root(y);
	}
	//根x と 根y のグループを併合する(お互い根ではない時、falseで何もしない)
	bool unite(int x, int y) {
		if (issame(x,y) || par[x] != -1 || par[y] != -1) {
			cout<<"error"<<endl;
			return false;
		}
		if (siz[x] < siz[y]) swap(x, y);
		par[y] = x;
		siz[x] += siz[y];
		return true;
	}
	//根の側から、その直系の子供を分離する。片方が根でもう片方が直系の子でなければならない。
	bool separate(int x,int y){
		if(par[y]==-1)swap(x,y);
		if(par[y]!=x||par[x]!=-1){
			cout<<"error2"<<endl;
			return false;
		}
		siz[x] -= siz[y];
		par[y]=-1;
		return true;
	}
	// x を含むグループのサイズを求める
	int size(int x) {
		return siz[root(x)];
	}
};
//セグ木,乗せる値の型が必要
template<typename T>
struct SegTree{
	ll size;
	ll tall;
	vector<T> data;
	function<T(T,T)> p;
	//セグ木に乗せる値の初期値をa配列にし、putの関数をセグ木に乗せる、dをデフォルト値に。
	SegTree(vector<T> a,function<T(T,T)> put,T d) : data(power(2,logax(2,a.size())+1)) {
		size = data.size()/2;
		tall=logax(2,size)+1;
		p=put;
		ll tmp=size;
		data = vector<T>(size*2,d);
		while(tmp!=0){
			if(tmp==size)rep(i,a.size())data[tmp+i]=a[i];
			else rep(i,tmp) data[tmp+i]=p(data[2*(tmp+i)],data[2*(tmp+i)+1]);
			tmp/=2;
		}
	}
	//更新、t番目の値をxにする。
	void update(ll t,T x){
		t+=size;
		while(t!=0){
			if(t>=size)data[t]=x;
			else data[t]=p(data[2*t],data[2*t+1]);
			t/=2;
		}
	}
	//取得、l~r区間内の評価値を取得する。
	T get(ll l,ll r){
		//lとrが範囲外なら範囲内に正す
		l=max(0LL,l);
		r=min(r,size-1);
		r++;
		T ans=data[0];
		ll pos=l+size;
		ll wid=1;
		//出来る限り上に上げきる。
		while(l+(wid*2)<=r){
			while(l%(wid*2)==0&&l+(wid*2)<=r)pos/=2,wid*=2;
			ans=p(ans,data[pos]);
			pos++;
			l+=wid;
		}
		//上げ終わったので今度は下げる
		while(l!=r){
			while(l+wid>r)pos*=2,wid/=2;
			ans=p(ans,data[pos]);
			pos++;
			l+=wid;
		}
		return ans;
	}
	//セグ木デバッグ用、丸ごと出力
	void print(){
		rep(i,size)cout<<setw(7)<<left<<i;
		cout<<endl;
		ll pos=size;
		rep(i,tall){
			rep(j,size){
				if(j%power(2,i)==0)cout<<setw(7)<<left<<data[pos],pos++;
				else cout<<"       ";
			}
			pos/=4;
			cout<<endl;
		}
	}
};

//グリッド問題等用
vl dx={1,0,-1,0};
vl dy={0,1,0,-1};

struct node{
	ll to,money,enemy;
};


ll solve(){
	ll n,m,l;
	cin>>n>>m>>l;
	if(n==0&&m==0&&l==0){return 1;}

	vector<vector<node>> g(n);
	rep(i,m){
		ll a,b,d,e;
		cin>>a>>b>>d>>e;
		a--,b--;
		g[a].push_back({b,d,e});
		g[b].push_back({a,d,e});
	}

	vvl dj(l+1,vl(n,inf));
	dj[l][0]=0;
	
	priority_queue<pair<ll,pair<ll,ll>>> pq;
	pq.push({0,{l,0}});

	while(!pq.empty()){
		ll nowcost=-pq.top().first;
		ll i=pq.top().second.first;
		ll j=pq.top().second.second;
		pq.pop();
		if(dj[i][j]!=nowcost)continue;

		rep(k,g[j].size()){
			//護衛を付けない時
			if(dj[i][g[j][k].to]>dj[i][j]+g[j][k].enemy){
				dj[i][g[j][k].to]=dj[i][j]+g[j][k].enemy;
				pq.push({-dj[i][g[j][k].to],{i,g[j][k].to}});
			}

			//護衛を付ける時
			if(i<g[j][k].money)continue;
			if(dj[i-g[j][k].money][g[j][k].to]>dj[i][j]){
				dj[i-g[j][k].money][g[j][k].to]=dj[i][j];
				pq.push({-dj[i-g[j][k].money][g[j][k].to],{i-g[j][k].money,g[j][k].to}});
			}
		}
	}

	ll ans=inf;
	rep(i,l+1){
		ans=min(ans,dj[i][n-1]);
	}
	//vvdbg(dj);
	cout<<ans<<endl;
	return 0;
}

//メイン
int main(){
	while(solve()==0);
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4896
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(...) std::begin(__VA_ARGS__), std::end(__VA_ARGS__)
#define rall(...) std::rbegin(__VA_ARGS__), std::rend(__VA_ARGS__)
#define OVERLOAD_REP(_1, _2, _3, _4, name, ...) name
#define REP1(n) for(ll i=0;i<(n);i++)
#define REP2(i, n) for (ll i=0;i<(n);i++)
#define REP3(i, a, n) for (ll i=a;i<(n);i++)
#define REP4(i, a, b, n) for(ll i=a;i<(n);i+=b)
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__)
#define OVERLOAD_RREP(_1, _2, _3, _4, name, ...) name
#define RREP1(n) for(ll i=(n)-1;i>=0;i--)
#define RREP2(i, n) for(ll i=(n)-1;i>=0;i--)
#define RREP3(i, a, n) for(ll i=(n)-1;i>=(a);i--)
#define RREP4(i, a, b, n) for(ll i=(n)-1;i>=(a);i-=(b))
#define rrep(...) OVERLOAD_RREP(__VA_ARGS__, RREP4, RREP3, RREP2, RREP1)(__VA_ARGS__)
#define uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define len(n) (long long)(n).size()
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vs = vector<string>;
using vvs = vector<vs>;
using vvvs = vector<vvs>;
using vld = vector<ld>;
using vvld = vector<vld>;
using vvvld = vector<vvld>;
using vc = vector<char>;
using vvc = vector<vc>;
using vvvc = vector<vvc>;
using pll = pair<ll,ll>;
using vpll = vector<pll>;
using vvpll = vector<vpll>;

ll intpow(ll a,ll b){
    ll ans = 1;
    while (b){
        if (b & 1){
            ans *= a;
        }
        a *= a;
        b /= 2;
    }
    return ans;
}
ll modpow(ll a,ll b,ll c){
    ll ans = 1;
    while (b){
        if (b & 1){
            ans *= a;
            ans %= c;
        }
        a *= a;
        a %= c;
        b /= 2;
    }
    return ans;
}

template<class... T>
void input(T&... a){
    (cin >> ... >> a);
}

#define INT(...) int __VA_ARGS__; input(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define STR(...) string __VA_ARGS__; input(__VA_ARGS__)
#define CHA(...) char __VA_ARGS__; input(__VA_ARGS__)
#define VLL(name,length) vll name(length);rep(i,length){cin >> name[i];}
#define VVLL(name,h,w) vvll name(h,vll(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLL(name,a,b,c) vvvll name(a,vvll(b,vll(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VI(name,length) vi name(length);rep(i,length){cin >> name[i];}
#define VVI(name,h,w) vvi name(h,vi(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVI(name,a,b,c) vvvi name(a,vvll(b,vi(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VLD(name,length) vld name(length);rep(i,length){cin >> name[i];}
#define VVLD(name,h,w) vvld name(h,vld(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLD(name,a,b,c) vvvld name(a,vvld(b,vld(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VC(name,length) vc name(length);rep(i,length){cin >> name[i];}
#define VVC(name,h,w) vvc name(h,vc(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVC(name,a,b,c) vvvc name(a,vvc(b,vc(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VS(name,length) vs name(length);rep(i,length){cin >> name[i];}
#define VVS(name,h,w) vvs name(h,vs(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVS(name,a,b,c) vvvs name(a,vvs(b,vs(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define PLL(name) pll name;cin>>name.first>>name.second;
#define VPLL(name,length) vpll name(length);rep(i,length){cin>>name[i].first>>name[i].second;}

void print(){cout << "\n";}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::pair<T1, T2>& p) {
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) {
    os << "[";
    for (size_t i = 0; i < vec.size(); ++i) {
        os << vec[i];
        if (i + 1 < vec.size()) os << ", ";
    }
    os << "]";
    return os;
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::vector<std::pair<T1, T2>>& a) {
    os << "[";
    for (size_t j = 0; j < a.size(); ++j) {
        os << "(" << a[j].first << ", " << a[j].second << ")";
		if (j + 1 < a.size()) os << ", ";
    }
	os << "]";
    return os;
}

template <typename T1, typename T2>
std::ostream& operator<<(std::ostream& os, const std::vector<std::vector<std::pair<T1, T2>>>& mat) {
	os << "[";
    for (size_t i = 0; i < mat.size(); ++i) {
		os << "[";
        for (size_t j = 0; j < mat[i].size(); ++j) {
            os << "(" << mat[i][j].first << ", " << mat[i][j].second << ")";
			if (j + 1 < mat[i].size()) os << ", ";
        }
		os << "]";
		if (i + 1 < mat.size()) os << ", ";
    }
	os << "]";
    return os;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::set<T>& s) {
    os << "{";
    bool first = true;
    for (const auto& x : s) {
        if (!first) os << ", ";
        os << x;
        first = false;
    }
    os << "}";
    return os;
}

template <typename K, typename V>
std::ostream& operator<<(std::ostream& os, const std::map<K, V>& m) {
    os << "{";
    bool first = true;
    for (const auto& [key, val] : m) {
        if (!first) os << ", ";
        os << key << ": " << val;
        first = false;
    }
    os << "}";
    return os;
}

template<class T, class... Ts>
void print(const T& a, const Ts&... b){cout << a;(cout << ... << (cout << ' ', b));cout << '\n';}

void write(){cout << "\n";}
template<class T, class... Ts>
void write(const T& a, const Ts&... b){cout << a;(cout << ... << (cout << ' ', b));cout << '\n';}
void write(vll x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void write(vvll x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void write(vi x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void write(vvi x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void write(vvvi x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}}
void write(vld x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void write(vvld x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void write(vvvld x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}}
void write(vc x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void write(vvc x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void write(vvvc x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}}
void write(vs x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void write(vvs x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}
void write(vvvs x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}}
void write(pll x){cout << x.first << ' ' << x.second << '\n';}
void write(vpll x){rep(i,len(x)){cout << x[i].first << ' ' << x[i].second << '\n';}}
void write(vvpll x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j].first << ' ' << x[i][j].second;if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}

template <typename T>
T sum(const std::vector<T>& v) {
    return std::accumulate(v.begin(), v.end(), T(0));
}

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; }
template<class T, class U> bool chmin(T& a, const U& b){ if(a > T(b)){ a = b; return 1; } return 0; }
template<class T, class U> bool chmax(T& a, const U& b){ if(a < T(b)){ a = b; return 1; } return 0; }


using S = tuple<ll,ll,ll>;
int main(){
	ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
    ll oo = 0;
    while(1){
        LL(n,m,l);
        if(n + m + l == 0){break;}
        vector<vector<S>> edge(n);
        rep(i,m){
            LL(x,y,d,e);
            x--;
            y--;
            edge[x].push_back({y,d,e});
            edge[y].push_back({x,d,e});
        }
        vvll dist(n,vll(l+1,1LL<<60));
        priority_queue<S,vector<S>,greater<S>> q;
        dist[0][l] = 0;
        q.push({0,0,l});
        while(!q.empty()){
            auto [c,now,bug] = q.top();
            q.pop();
            if(c > dist[now][bug]){continue;}
            for(auto [to,l,e]:edge[now]){
                if(dist[to][bug] > dist[now][bug] + e){
                    dist[to][bug] = dist[now][bug] + e;
                    q.push({dist[to][bug],to,bug});
                }
                if(0 <= bug - l && dist[to][bug - l] > dist[now][bug]){
                    dist[to][bug - l] = dist[now][bug];
                    q.push({dist[to][bug-l],to,bug-l});
                }
            }
        }
        print(*min_element(all(dist.back())));
    }
    
}
accuracy: 1
time_ms: 10
memory_kb: 4956
final_rank: 3

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...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

struct Edge {
    int To;
    int Dist;
    int Cost;
};

typedef pair<int,pair<int,int>> PP;

int main() {
while(1) {
    int N, M, L;
    cin >> N >> M >> L;
    if (N == 0) return 0;
    vector<vector<Edge>> G(N);
    rep(i,0,M) {
        int A, B, D, E;
        cin >> A >> B >> D >> E;
        A--, B--;
        G[A].push_back({B,E,D});
        G[B].push_back({A,E,D});
    }
    vector<vector<int>> DP(N,vector<int>(L+1,inf));
    priority_queue<PP, vector<PP>, greater<PP>> PQ;
    DP[0][0] = 0;
    PQ.push({0,{0,0}});
    while(!PQ.empty()) {
        PP P = PQ.top();
        PQ.pop();
        if (P.first > DP[P.second.first][P.second.second]) continue;
        for (Edge E : G[P.second.first]) {
            if (chmin(DP[E.To][P.second.second], DP[P.second.first][P.second.second] + E.Dist)) {
                PQ.push({DP[E.To][P.second.second], {E.To, P.second.second}});
            }
            if (P.second.second + E.Cost <= L) {
                if (chmin(DP[E.To][P.second.second + E.Cost], DP[P.second.first][P.second.second])) {
                    PQ.push({DP[E.To][P.second.second + E.Cost], {E.To, P.second.second + E.Cost}});
                }
            }
        }
    }
    int ANS = inf;
    rep(i,0,L+1) chmin(ANS, DP[N-1][i]);
    cout << ANS << endl;
}
}
accuracy: 1
time_ms: 20
memory_kb: 3888
final_rank: 6

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

#define all(v) v.begin(),v.end()
using ll = long long;
using ull = unsigned long long;
using vll=vector<ll>;
using vvll = vector<vector<ll>>;
using P = pair<ll,ll>;
using PP = pair<ll,P>;
using vp=vector<pair<ll, ll>>;
//using mint=modint1000000007;
//using mint=modint998244353;

const ll INF=1ll<<60;
ll mod10=1e9+7;
ll mod99=998244353;
const double PI = acos(-1);

#define rep(i,n) for (ll i=0;i<n;++i)
#define per(i,n) for(ll i=n-1;i>=0;--i)
#define rep2(i,a,n) for (ll i=a;i<n;++i)
#define per2(i,a,n) for (ll i=a;i>=n;--i)

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; }

bool solve(){
    ll N,M,L;cin>>N>>M>>L;
    if(N==0) return 0;
    vector<ll> A(M),B(M),D(M),E(M);
    vector<vp> ab(N);
    rep(i,M){
        cin>>A[i]>>B[i]>>D[i]>>E[i];
        A[i]--;B[i]--;
        ab[A[i]].push_back({B[i],i});
        ab[B[i]].push_back({A[i],i});
    }

    vvll dist(N,vll(L+1,INF));
    priority_queue<PP,vector<PP>,greater<PP>> pq;
    pq.push({0,{0,L}});
    while(pq.size()){
        auto [c,now1]=pq.top();pq.pop();
        auto [now,l]=now1;
        if(dist[now][l]!=INF) continue;
        dist[now][l]=c;
        for(auto [to,i]:ab[now]){
            pq.push({c+E[i],{to,l}});
            if(D[i]<=l) pq.push({c,{to,l-D[i]}});
        }
    }
    
    ll ans=INF;
    rep(i,L+1) chmin(ans,dist[N-1][i]);
    cout << ans << endl;
    

    return 1;
}


int main(){
   cin.tie(0);
   ios::sync_with_stdio(false);
   while(solve());
}
accuracy: 1
time_ms: 160
memory_kb: 22788
final_rank: 20

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(1) {
        int n, m, l;
        cin >> n >> m >> l;
        if(n == 0) break;
        Graph<int> g(n * (l + 1));
        rep(i, 0, m) {
            int a, b, d, e;
            cin >> a >> b >> d >> e;
            a--;
            b--;
            rep(j, 0, l + 1) {
                g.add_directed_edge(a * (l + 1) + j, b * (l + 1) + j, e);
                g.add_directed_edge(b * (l + 1) + j, a * (l + 1) + j, e);
                if(j - d >= 0) {
                    g.add_directed_edge(a * (l + 1) + j, b * (l + 1) + j - d, 0);
                    g.add_directed_edge(b * (l + 1) + j, a * (l + 1) + j - d, 0);
                }
            }
        }
        auto dist = dijkstra(g, l);
        int ans = 1e9;
        rep(i, 0, l + 1) {
            ans = min(ans, dist[(n - 1) * (l + 1) + i].first);
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 40
memory_kb: 14308
final_rank: 14

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

using namespace std;

// graph template
// ref : https://ei1333.github.io/library/graph/graph-template.hpp
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){}

    int size(){
        return (int)g.size();
    }
    void resize(int k){
        g.resize(k);
        V=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>
struct Dijkstra{
    const T inf;
    Graph<T> g;
    vector<T> d;
    vector<int> prev,eid;
    
    Dijkstra(Graph<T> g):inf(numeric_limits<T>::max()/4),g(g){}

    vector<T> build(int st){
        d.assign(g.V,inf);
        prev.assign(g.V,-1);
        eid.assign(g.V,-1);
        d[st]=0;
        priority_queue<pair<T,int>,vector<pair<T,int>>,greater<pair<T,int>>> que;
        que.emplace(d[st],st);
        while(!que.empty()){
            auto p=que.top();que.pop();
            int cur=p.second;
            if(d[cur]<p.first) continue;
            for(auto &e:g[cur]){
                if(d[e]>d[cur]+e.w){
                    d[e]=d[cur]+e.w;
                    prev[e]=cur;
                    que.emplace(d[e],e);
                }
            }
        }
        return d;
    }

    // vertex = false :-> edge idx
    vector<int> get_path(int gl,bool vertex=true){
        vector<int> ret;
        if(d[gl]==inf) return ret;
        for(;gl!=-1;gl=prev[gl]){
            ret.push_back(vertex?gl:eid[gl]);
        }
        reverse(ret.begin(),ret.end());
        return ret;
    }
};

void solve(const int N, const int M, const int L)
{
    vector<int> A(M), B(M), D(M), E(M);
    for (int i = 0; i < M; i++)
    {
        cin >> A[i] >> B[i] >> D[i] >> E[i];
        A[i]--, B[i]--;
    }

    // Dijkstra on Extended Graph
    auto getVertexOnExtendedGraph = [&](int v, int cost)
    {
        return v * (L + 1) + cost;
    };
    auto getVertexAndCostFromExtendedGraph = [&](int V)
    {
        return make_pair(V / (L + 1), V % (L + 1));
    };

    Graph<int> G(N * (L + 1));
    
    for (int i = 0; i < M; i++)
    {
        const int a = A[i];
        const int b = B[i];

        for (int c = 0; c <= L; c++)
        {
            // hire
            if (c + D[i] <= L) {
                {
                    const auto ea = getVertexOnExtendedGraph(a, c);
                    const auto eb = getVertexOnExtendedGraph(b, c + D[i]);
                    G.add_directed_edge(ea, eb, 0);
                }
                {
                    const auto eb = getVertexOnExtendedGraph(b, c);
                    const auto ea = getVertexOnExtendedGraph(a, c + D[i]);
                    G.add_directed_edge(eb, ea, 0);
                }
            }
            // date with princess
            {
                const auto ea = getVertexOnExtendedGraph(a, c);
                const auto eb = getVertexOnExtendedGraph(b, c);
                G.add_edge(eb, ea, E[i]);
            }
        }
    }

    Dijkstra<int> dist(G);
    const auto minDist = dist.build(getVertexOnExtendedGraph(0, 0));

    int ans = 100000000;
    for (int cost = 0; cost <= L; cost++)
    {
        const auto eg = getVertexOnExtendedGraph(N - 1, cost);
        ans = min(ans, minDist[eg]);
    }

    cout << ans << endl;
}

int main()
{
    int N, M, L;
    while(cin >> N >> M >> L, N || M || L)
    {
        solve(N, M, L);
    }
}
accuracy: 1
time_ms: 60
memory_kb: 30136
final_rank: 18

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = 3.141592653589793;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}
template<typename T> void view(const vv<T>& vv){ for(const auto& v : vv){ view(v); } }

tuple<vc<int>, vi> dijkstra(int s, int N, vv<pair<int, int>> &g){
    using P = pair<int, int>;
    vc<int> dist(N, inf);
    vi bef(N);
    priority_queue<P, vc<P>, greater<P>> q;
    dist[s] = 0;
    q.push({0, s});
    while (!q.empty()){
        auto [c, now] = q.top();q.pop();
        if (dist[now] < c) continue;
        for (auto&& [nxt, nc]: g[now]) if (dist[nxt] > c + nc){
            dist[nxt] = c + nc;
            bef[nxt] = now;
            q.push({dist[nxt], nxt}); 
        }
    }
    return {dist, bef};
}

int solve(int N, int M, int L){
    int K = 101;
    vv<pair<int, int>> g(N * K);
    rep(i, M){
        int a, b, d, e; cin >> a >> b >> d >> e; a--; b--;
        rep(j, K){
            g[a * K + j].push_back({b * K + j, e});
            g[b * K + j].push_back({a * K + j, e});
        }
        for (int j = d; j < K; j++){
            g[a * K + j].push_back({b * K + j - d, 0});
            g[b * K + j].push_back({a * K + j - d, 0});
        }
    }
    auto [dist, bef] = dijkstra(L, N * K, g);
    int ans = inf;
    rep(j, K) ans = min(ans, dist[(N - 1) * K + j]);
    return ans;
}

int main(){
    vc<int> ans;
    while (true){
        int N, M, L; cin >> N >> M >> L;
        if (N == 0) break;
        ans.push_back(solve(N, M, L));
    }
    for (auto x : ans) cout << x << endl;
}
accuracy: 1
time_ms: 60
memory_kb: 18512
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> pi;
typedef pair<pi, int> ppi;
const int INF = 1<<29;
int main(){
    int n, m, l, a, b, d, e;
    while(cin >> n >> m >> l, n){
        vector<ppi> road[101];
        for(int i=0;i<m;i++){
            cin >> a >> b >> d >> e;
            pi info = pi(e, d);
            road[a].push_back(ppi(info, b));
            road[b].push_back(ppi(info, a));
        }
        priority_queue<ppi, vector<ppi>, greater<ppi> > pq;
        pq.push(ppi(pi(0, 0), 1));
        int mcost[101][101];
        fill_n(*mcost, 101*101, INF);
        mcost[1][0] = 0;
        while(!pq.empty()){
            ppi pp = pq.top();
            pq.pop();
            pi p = pp.first;
            for(int i=0;i<road[pp.second].size();i++){
                ppi npp = road[pp.second][i];
                pi np = npp.first;
                int sum = p.first;
                int cost = p.second + np.second;
                int to = npp.second;
                if(cost<=l && mcost[to][cost]>sum){
                    mcost[to][cost] = sum;
                    pq.push(ppi(pi(sum, cost), to));
                }
                sum = p.first + np.first;
                cost = p.second;
                if(mcost[to][cost]>sum){
                    mcost[to][cost] = sum;
                    pq.push(ppi(pi(sum, cost), to));
                }
            }
        }
        int ans = INF;
        for(int i=0;i<=l;i++) ans = min(ans, mcost[n][i]);
        cout << ans << endl;
    }
    return(0);
}
accuracy: 1
time_ms: 30
memory_kb: 3484
final_rank: 9

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

int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int N,M,L;
  while(cin>>N>>M>>L,N){
    vector<vector<array<int,3>>>G(N);
    for(int i=0;i<M;i++){
      int A,B,D,E;
      cin>>A>>B>>D>>E;
      --A,--B;
      G[A].push_back({B,D,E});
      G[B].push_back({A,D,E});
    }
    vector<vector<int>>dist(N,vector<int>(L+1,1e9));
    dist[0][L]=0;
    priority_queue<array<int,3>,vector<array<int,3>>,greater<array<int,3>>>pq;
    pq.push({0,0,L});
    while(pq.size()){
      int d=pq.top()[0],v=pq.top()[1],m=pq.top()[2];
      pq.pop();
      if(dist[v][m]<d)continue;

      for(auto i:G[v]){
        if(i[1]<=m){
          if(dist[i[0]][m-i[1]]>dist[v][m]){
            dist[i[0]][m-i[1]]=dist[v][m];
            pq.push({dist[i[0]][m-i[1]],i[0],m-i[1]});
          }
        }
        if(dist[i[0]][m]>dist[v][m]+i[2]){
          dist[i[0]][m]=dist[v][m]+i[2];
          pq.push({dist[i[0]][m],i[0],m});
        }
      }
    }

    int ans=1e9;
    for(int i=0;i<=L;i++){
      ans=min(ans,dist[N-1][i]);
    }
    cout<<ans<<'\n';
  } 
}
accuracy: 1
time_ms: 20
memory_kb: 3668
final_rank: 5

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

const int inf=1<<30;

bool solve(){
    int N,M,L;
    cin>>N>>M>>L;
    if(N==0)return false;
    vector<vector<tuple<int,int,int>>>G(N);
    for(int i=0;i<M;i++){
        int a,b,d,e;
        cin>>a>>b>>d>>e;
        a--;
        b--;
        G[a].push_back(make_tuple(b,d,e));
        G[b].push_back(make_tuple(a,d,e));
    }
    vector dp(N,vector<int>(L+1,inf));
    dp[0][0]=0;
    priority_queue<tuple<int,int,int>,vector<tuple<int,int,int>>,greater<tuple<int,int,int>>>pq;
    pq.push(make_tuple(0,0,0));
    while(pq.size()){
        auto[c,x,l]=pq.top();
        pq.pop();
        for(auto[i,d,e]:G[x]){
            if(dp[i][l]>c+e){
                dp[i][l]=c+e;
                pq.push(make_tuple(dp[i][l],i,l));
            }
            if(l+d<=L&&dp[i][l+d]>c){
                dp[i][l+d]=c;
                pq.push(make_tuple(dp[i][l+d],i,l+d));
            }
        }
    }
    int ans=inf;
    for(int i=0;i<=L;i++){
        ans=min(ans,dp[N-1][i]);
    }
    cout<<ans<<"\n";
    return true;
}

int main(){
    while(1){
        if(!solve()){
            return 0;
        }
    }
}
accuracy: 1
time_ms: 30
memory_kb: 3736
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
using ull = unsigned long long;
typedef pair<ll,ll> pll;
typedef vector<ll> vll;
typedef vector<pll> vpll;
template<class T> using pqmin = priority_queue<T, vector<T>, greater<T>>;
template<class T> using pqmax = priority_queue<T>;
const ll inf=LLONG_MAX/3;
const ll dx[] = {0, 1, 0, -1, 1, -1, 1, -1};
const ll dy[] = {1, 0, -1, 0, 1, 1, -1, -1};
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define fi first
#define se secondf
#define all(x) x.begin(),x.end()
#define si(x) ll(x.size())
#define rep(i,n) for(ll i=0;i<n;i++)
#define per(i,n) for(ll i=n-1;i>=0;i--)
#define rng(i,l,r) for(ll i=l;i<r;i++)
#define gnr(i,l,r) for(ll i=r-1;i>=l;i--)
#define fore(i, a) for(auto &&i : a)
#define fore2(a, b, v) for(auto &&[a, b] : v)
#define fore3(a, b, c, v) for(auto &&[a, b, c] : v)
template<class T> bool chmin(T& a, const T& b){ if(a <= b) return 0; a = b; return 1; }
template<class T> bool chmax(T& a, const T& b){ if(a >= b) return 0; a = b; return 1; }
template<class T, class U> bool chmin(T& a, const U& b){ return chmin(a, (T)b); }
template<class T, class U> bool chmax(T& a, const U& b){ return chmax(a, (T)b); }
#define LL(...) ll __VA_ARGS__;in(__VA_ARGS__)
#define STR(...) string __VA_ARGS__;in(__VA_ARGS__)
#define CHR(...) char __VA_ARGS__;in(__VA_ARGS__)
#define vec(type,name,...) vector<type>name(__VA_ARGS__)
#define VEC(type,name,size) vector<type>name(size);in(name)
#define VLL(name,size) vector<ll>name(size);in(name)
#define vv(type,name,h,...) vector<vector<type>> name(h,vector<type>(__VA_ARGS__))
#define VV(type,name,h,w) vector<vector<type>> name(h,vector<type>(w));in(name)
#define vvv(type,name,h,w,...) vector<vector<vector<type>>> name(h,vector<vector<type>>(w,vector<type>(__VA_ARGS__)))
#define SUM(...) accumulate(all(__VA_ARGS__),0LL)
template<class T> auto min(const T& a){ return *min_element(all(a)); }
template<class T> auto max(const T& a){ return *max_element(all(a)); }
template<class T, class F = less<>> void sor(T& a, F b = F{}){ sort(all(a), b); }
template<class T> void uniq(T& a){ sor(a); a.erase(unique(all(a)), end(a)); }
void outb(bool x){cout<<(x?"Yes":"No")<<"\n";}
ll max(int x, ll y) { return max((ll)x, y); }
ll max(ll x, int y) { return max(x, (ll)y); }
int min(int x, ll y) { return min((ll)x, y); }
int min(ll x, int y) { return min(x, (ll)y); }
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define lbg(c, x) distance((c).begin(), lower_bound(all(c), (x), greater{}))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define ubg(c, x) distance((c).begin(), upper_bound(all(c), (x), greater{}))
ll gcd(ll a,ll b){return (b?gcd(b,a%b):a);}
vector<pll> factor(ull x){ vector<pll> ans; for(ull i = 2; i * i <= x; i++) if(x % i == 0){ ans.push_back({i, 1}); while((x /= i) % i == 0) ans.back().second++; } if(x != 1) ans.push_back({x, 1}); return ans; }
vector<ll> divisor(ull x){ vector<ll> ans; for(ull i = 1; i * i <= x; i++) if(x % i == 0) ans.push_back(i); per(i,ans.size() - (ans.back() * ans.back() == x)) ans.push_back(x / ans[i]); return ans; }
vll prime_table(ll n){vec(ll,isp,n+1,1);vll res;rng(i,2,n+1)if(isp[i]){res.pb(i);for(ll j=i*i;j<=n;j+=i)isp[j]=0;}return res;}

template <class T, class S> pair<T, S> operator-(const pair<T, S> &x) { return pair<T, S>(-x.first, -x.second); }
template <class T, class S> pair<T, S> operator-(const pair<T, S> &x, const pair<T, S> &y) { return pair<T, S>(x.fi - y.fi, x.se - y.se); }
template <class T, class S> pair<T, S> operator+(const pair<T, S> &x, const pair<T, S> &y) { return pair<T, S>(x.fi + y.fi, x.se + y.se); }
template <class T> pair<T, T> operator&(const pair<T, T> &l, const pair<T, T> &r) { return pair<T, T>(max(l.fi, r.fi), min(l.se, r.se)); }
template <class T, class S> pair<T, S> operator+=(pair<T, S> &l, const pair<T, S> &r) { return l = l + r; }
template <class T, class S> pair<T, S> operator-=(pair<T, S> &l, const pair<T, S> &r) { return l = l - r; }
template <class T> bool intersect(const pair<T, T> &l, const pair<T, T> &r) { return (l.se < r.se ? r.fi < l.se : l.fi < r.se); }

template <class T> vector<T> &operator++(vector<T> &v) {
		fore(e, v) e++;
		return v;
}
template <class T> vector<T> operator++(vector<T> &v, int) {
		auto res = v;
		fore(e, v) e++;
		return res;
}
template <class T> vector<T> &operator--(vector<T> &v) {
		fore(e, v) e--;
		return v;
}
template <class T> vector<T> operator--(vector<T> &v, int) {
		auto res = v;
		fore(e, v) e--;
		return res;
}
template <class T> vector<T> &operator+=(vector<T> &l, const vector<T> &r) {
		fore(e, r) l.eb(e);
		return l;
}

template<class... Ts> void in(Ts&... t);
[[maybe_unused]] void print(){}
template<class T, class... Ts> void print(const T& t, const Ts&... ts);
template<class... Ts> void out(const Ts&... ts){ print(ts...); cout << '\n'; }
namespace IO{
#define VOID(a) decltype(void(a))
struct S{ S(){ cin.tie(nullptr)->sync_with_stdio(0); fixed(cout).precision(12); } }S;
template<int I> struct P : P<I-1>{};
template<> struct P<0>{};
template<class T> void i(T& t){ i(t, P<3>{}); }
void i(vector<bool>::reference t, P<3>){ int a; i(a); t = a; }
template<class T> auto i(T& t, P<2>) -> VOID(cin >> t){ cin >> t; }
template<class T> auto i(T& t, P<1>) -> VOID(begin(t)){ for(auto&& x : t) i(x); }
template<class T, size_t... idx> void ituple(T& t, index_sequence<idx...>){ in(get<idx>(t)...); }
template<class T> auto i(T& t, P<0>) -> VOID(tuple_size<T>{}){ ituple(t, make_index_sequence<tuple_size<T>::value>{}); }
template<class T> void o(const T& t){ o(t, P<4>{}); }
template<size_t N> void o(const char (&t)[N], P<4>){ cout << t; }
template<class T, size_t N> void o(const T (&t)[N], P<3>){ o(t[0]); for(size_t i = 1; i < N; i++){ o(' '); o(t[i]); } }
template<class T> auto o(const T& t, P<2>) -> VOID(cout << t){ cout << t; }
template<class T> auto o(const T& t, P<1>) -> VOID(begin(t)){ bool first = 1; for(auto&& x : t) { if(first) first = 0; else o(' '); o(x); } }
template<class T, size_t... idx> void otuple(const T& t, index_sequence<idx...>){ print(get<idx>(t)...); }
template<class T> auto o(T& t, P<0>) -> VOID(tuple_size<T>{}){ otuple(t, make_index_sequence<tuple_size<T>::value>{}); }
#undef VOID
}
#define unpack(a) (void)initializer_list<int>{(a, 0)...}
template<class... Ts> void in(Ts&... t){ unpack(IO::i(t)); }
template<class T, class... Ts> void print(const T& t, const Ts&... ts){ IO::o(t); unpack(IO::o((cout << ' ', ts))); }
#undef unpack

int main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	while(1){
		LL(n,m,l);
		if(n==0)break;
		struct edge{
			ll to,d,e;
		};
		vv(edge,g,n);
		rep(i,m){
			LL(a,b,d,e);
			a--,b--;
			g[a].pb({b,d,e});
			g[b].pb({a,d,e});
		}
		vv(ll,di,n,l+1,inf);
		struct st{
			ll v,r,es;
			// bool operator>(const st&key)const{
			// 	return this->es<key.es;
			// }
			bool operator<(const st&key)const{
				return this->es>key.es;
			}
		};
		pqmax<st> que;
		que.push({0,l,0});
		while(!que.empty()){
			auto [v,r,es]=que.top();
			que.pop();
			if(di[v][r]<=es)continue;
			di[v][r]=es;
			fore(eg,g[v]){
				auto [u,d,e]=eg;
				que.push({u,r,es+e});
				if(r>=d)que.push({u,r-d,es});
			}
		}
		ll ans=inf;
		rep(r,l+1)chmin(ans,di[n-1][r]);
		out(ans);
	}
}
accuracy: 1
time_ms: 120
memory_kb: 22504
final_rank: 19

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

const long long inf = 1e18;
using P = std::pair<long long, int>;
using Graph = std::vector<std::vector<P>>;

std::vector<long long> djikstra(const Graph& g, int start) {
    int n = g.size();
    std::vector<long long> dist(n, inf);
    dist[start] = 0;
    std::priority_queue<P, std::vector<P>, std::greater<P>> hp;
    hp.emplace(0, start);
    while (!hp.empty()) {
        auto [d, u] = hp.top();
        hp.pop();
        if (dist[u] != d) continue;
        for (auto [cost, v]: g[u]) {
            if (dist[v] > dist[u] + cost) {
                dist[v] = dist[u] + cost;
                hp.emplace(dist[v], v);
            }
        }
    }
    return dist;
}

bool solve() {
    int n, m, l;
    std::cin >> n >> m >> l;
    if (n == 0 && m == 0 && l == 0) return false;
    Graph graph((l + 1) * n);
    for (int i = 0; i < m; i++) {
        int a, b, d, e;
        std::cin >> a >> b >> d >> e;
        a--; b--;
        a = (l + 1) * a;
        b = (l + 1) * b;
        for (int j = l; j >= 0; j--) {
            if (j - d >= 0) {
                graph[a + j].emplace_back(0, b + j - d);
                graph[b + j].emplace_back(0, a + j - d);
            }
        }
        for (int j = l; j >= 0; j--) {
            graph[a + j].emplace_back(e, b + j);
            graph[b + j].emplace_back(e, a + j);
        }
    }
    auto dist = djikstra(graph, l);
    long long ans = inf;
    for (int i = 0; i <= l; i++) {
        ans = std::min(ans, dist[(n - 1) * (l + 1) + i]);
    }
    std::cout << ans << '\n';
    return true;
}

int main() {
    while (solve()) ;
}
accuracy: 1
time_ms: 40
memory_kb: 14388
final_rank: 15

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <queue>

void solve(int n, int m, int l) {
  struct Edge {
    short to, price;
    int cost;

    Edge() {}
    Edge(short to, short price, int cost) :
      to(to), price(price), cost(cost) {}
  };

  auto g = std::vector(n, std::vector(0, Edge()));
  for (short i = 0; i < m; i++) {
    short a, b;
    int d, e;
    std::cin >> a >> b >> d >> e;

    a--;
    b--;
    g[a].emplace_back(b, d, e);
    g[b].emplace_back(a, d, e);
  }

  constexpr int inf = 10000000;
  auto ds = std::vector(n, std::vector(l + 1, inf));

  using pq_type = std::pair< int, std::pair< short, short > >;
  std::priority_queue< pq_type, std::vector< pq_type >, std::greater< pq_type > > pq;

  ds[0][l] = 0;
  pq.emplace(ds[0][l], std::make_pair(0, l));

  while (not pq.empty()) {
    auto [dist, vertex] = pq.top();
    pq.pop();

    auto &[v, rem] = vertex;

    if (dist > ds[v][rem]) continue;

    for (auto &&e: g[v]) {
      if (rem - e.price >= 0 and ds[e.to][rem - e.price] > dist) {
        ds[e.to][rem - e.price] = dist;
        pq.emplace(dist, std::make_pair(e.to, rem - e.price));
      }

      if (ds[e.to][rem] > dist + e.cost) {
        ds[e.to][rem] = dist + e.cost;
        pq.emplace(dist + e.cost, std::make_pair(e.to, rem));
      }
    }
  }

  int ans = *std::min_element(ds.back().begin(), ds.back().end());
  std::cout << ans << std::endl;
}

int main() {
  int n, m, l;

  while (std::cin >> n >> m >> l, n) {
    solve(n, m, l);
  }
}
accuracy: 1
time_ms: 20
memory_kb: 3612
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
using Tpl = tuple<ll, ll, ll>;
using Pair = pair<ll, ll>;
template<class T> using min_heap = priority_queue<T, vector<T>, greater<T>>;

const ll LINF = 1e18;
#define rep(i, N) for(int i = 0; i < N; i++)
#define mktpl make_tuple
#define mkpr make_pair
#define fi first
#define se second

int main(){
	cin.tie(nullptr);
	ios_base::sync_with_stdio(false);
	while(1){
		int N, M, L; cin >> N >> M >> L;
		if(N == 0) break;

		vector<vector<vector<Tpl>>> G(N, vector<vector<Tpl>>(L + 1));	
		for(int i = 0; i < M; i++){
			ll a, b, d, e; cin >> a >> b >> d >> e;
			a--, b--;
			for(int j = L; j >= 0; j--){
				if(j >= d){
					G[a][j].emplace_back(mktpl(b, j - d, 0));
					G[b][j].emplace_back(mktpl(a, j - d, 0));
				}
				G[a][j].emplace_back(mktpl(b, j, e));
				G[b][j].emplace_back(mktpl(a, j, e));
			}
		}

		vector<vector<ll>> dist(N, vector<ll>(L + 1, LINF)), used(N, vector<ll>(L + 1, 0));
		min_heap<Tpl> heap;
		heap.push(mktpl(0, 0, L));
		dist[0][L] = 0;
		while(!heap.empty()){
			auto p = heap.top();
			heap.pop();
			ll cst = get<0>(p), u = get<1>(p), l = get<2>(p);
			if(used[u][l]) continue;
			used[u][l] = 1;

			for(auto v : G[u][l]){
				ll vn = get<0>(v), vl = get<1>(v), vcst = get<2>(v);
				if(dist[vn][vl] > dist[u][l] + vcst){
					dist[vn][vl] = dist[u][l] + vcst;
					heap.push(mktpl(dist[vn][vl], vn, vl));
				}
			}
		}

		ll ans = LINF;
		rep(i, L + 1){
			if(ans > dist[N - 1][i]) ans = dist[N - 1][i];
		}
		cout << ans << '\n';
	}
	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 20308
final_rank: 17

code_snippet: #include<bits/stdc++.h>
#define rep(i,n) for(int i=0; i< (n); i++)
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int mod = 998244353;
const int inf = (1<<30);

/*struct st{
	ll where,many,damege;
	st(ll a, ll b, ll c){
		where = a;
		many = b;
		damege = c;
	}
	bool operator<(const st& a){
		return this->damege < a.damege;
	}
	bool operator>(const st& a){
		return this->damege > a.damege;
	}
};*/
 
int main(){

	while(1){
		int n,m,l; cin>>n>>m>>l;
		if(n == 0) break;

		vector<vector<int>> D(n,vector<int>(n,inf));
		vector<vector<int>> E(n,vector<int>(n,inf));
		vector<vector<int>> g(n);

		rep(i,m){
			int a,b;
			cin>>a>>b; a--; b--;
			cin>>D[a][b]; D[b][a] = D[a][b];
			cin>>E[a][b]; E[b][a] = E[a][b];
			g[a].push_back(b);
			g[b].push_back(a);
		}

		vector<vector<ll>> ans(n,vector<ll>(l+1,(1ull<<60)));
		priority_queue<pair<ll,P>,vector<pair<ll,P>>,greater<pair<ll,P>>> q;
		q.push({0,{0,l}});
		ans[0][l] = 0;

		while(q.size()){
			auto now = q.top();
			q.pop();

			ll dame = now.first;
			ll many = now.second.second;
			ll where = now.second.first;

			if(ans[where][many] < dame) continue;
			
			for(int next : g[where]){

				ll t = ans[where][many] + E[where][next];
				if(t < ans[next][many]){
					ans[next][many] = t;
					q.push({t,{next,many}});
				}
				ll pay = many - D[where][next];
				if(pay >= 0 && ans[next][pay] > ans[where][many]){
					ans[next][pay] = ans[where][many];
					q.push({ans[next][pay],{next,pay}});
				}
			}
		}
		ll res = (1ull<<60);
		rep(i,l+1){
			res = min(ans[n-1][i],res);
		}
		cout<<res<<endl;

	}
}
accuracy: 1
time_ms: 20
memory_kb: 4160
final_rank: 8

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

int solve(int N, int M, int L) {
    vector G(N * (L + 1), vector(0, pair(0, 0)));
    for (int _ =  0 ; _ < M ; _++) {
        int A, B, D, E; cin >> A >> B >> D >> E;
        A--; B--;
        // 警備を張る
        for (int i = L ; i - D >= 0 ; i--) {
            G.at(i * N + A).emplace_back((i - D) * N + B, 0);
            G.at(i * N + B).emplace_back((i - D) * N + A, 0);
        }
        // 警備をしない -> 敵コスト
        for (int i = 0 ; i <= L ; i++) {
            G.at(i * N + A).emplace_back(i * N + B, E);
            G.at(i * N + B).emplace_back(i * N + A, E);
        }
    }

    const int sup = 1e9;
    vector<int> dist(G.size(), sup);
    dist[L * N] = 0;
    using pii = pair<int, int>;
    priority_queue<pii, vector<pii>, greater<pii>> que{};
    que.emplace(0, L * N);

    while (que.size()) {
        auto [d, v] = que.top();
        que.pop();
        if (dist.at(v) < d) continue;
        for (auto [x, w] : G[v]) {
            if (dist[x] > d + w) {
                dist[x] = d + w;
                que.emplace(dist[x], x);
            }
        }
    }

    int ans = sup;
    for (int i = 0 ; i <= L ; i++) ans = min(ans, dist[i * N + (N - 1)]);

    return ans;
}

int main() {
    while (1) {
        int N, M, L; cin >> N >> M >> L;
        if (!N) break;
        int ans = solve(N, M, L);
        cout << ans << endl;
    } 
}
accuracy: 1
time_ms: 40
memory_kb: 9088
final_rank: 13