#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <cctype>
#include <numeric>
using namespace std;

#define rep(i,n) for(int (i)=0; (i)<(int)(n); ++(i))
#define foreach(c,i) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++)

struct edge {
  int to, d, e;
};

struct state {
  int cur, cost, remain;
  bool operator<(const state& o) const {
    return cost > o.cost;
  }
};

vector<edge> es[102];
int L, N, M, d[102][102];

int solve() {
  rep(i,102) rep(j,102) d[i][j] = 1 << 30;
  
  priority_queue<state> Q;
  Q.push((state){0, 0, L});
  
  while (!Q.empty()) {
    state s = Q.top(); Q.pop();
    int cur = s.cur, cost = s.cost, remain = s.remain;
    if (s.cost > d[s.cur][s.remain]) continue;
    if (cur == N-1) {
      return cost;
    }
    rep(i,es[s.cur].size()) {
      edge e = es[cur][i];
      // やとわない
      if (d[e.to][remain] > e.e + cost) {
        d[e.to][remain] = e.e + cost;
        Q.push((state){e.to, e.e + cost, remain});
      }
      // やとってみる
      if (remain >= e.d && d[e.to][remain - e.d] > cost) {
        d[e.to][remain - e.d] = cost;
        Q.push((state){e.to, cost, remain - e.d});
      }
    }
  }
  return -1;
}

int main() {
  while (scanf("%d%d%d", &N, &M, &L), N) {
    rep(i,102) es[i].clear();
    int a, b, d, e;
    rep(i,M) {
      scanf("%d%d%d%d", &a, &b, &d, &e);
      --a; --b;
      es[a].push_back((edge){b, d, e});
      es[b].push_back((edge){a, d, e});
    }
    // memset(visited, 0, sizeof visited);
    printf("%d\n", solve());
  }
  return 0;
}