#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <cstring>
#include <string>
#include <queue>
#include <cmath>
#include <map>

#define rep(i,n) for(int i = 0; i < (n); i++)
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define all(v) (v).begin(), (v).end()
#define rev(v) (v).rbegin(), (v).rend()
#define MP make_pair
#define X first
#define Y second

using namespace std;

typedef vector<int> vi;
typedef pair<int, int> P;
typedef long long ll;

struct edge{
	int to;
	int money;
	int enemy;
	edge(int t, int m, int e):to(t),money(m),enemy(e){}
	bool operator<(const edge &r) const{
		return enemy > r.enemy;
	}
};

int main(){
	int n, m, l;
	while(cin >> n >> m >> l, n|m|l){
		vector<vector<edge> > G(n);
		rep(i, m){
			int a, b, d, e;
			cin >> a >> b >> d >> e;
			a--, b--;
			G[a].push_back(edge(b, d, e));
			G[b].push_back(edge(a, d, e));
		}

		priority_queue<edge> q;
		q.push(edge(0, l, 0));

		vector<vi> visit(n, vi(l+1, 0)); // visit[pos][money]

		while(!q.empty()){
			edge s = q.top();
			q.pop();

			//cout << "pos=" << s.to << ", money=" << s.money << ", enemy=" << s.enemy << endl;

			if(visit[s.to][s.money]) continue;
			visit[s.to][s.money] = 1;

			if(s.to == n-1){
				cout << s.enemy << endl;
				break;
			}

			rep(i, G[s.to].size()){
				if(G[s.to][i].money <= s.money){
					edge next = s;
					next.money -= G[s.to][i].money;
					next.to = G[s.to][i].to;
					if(!visit[next.to][next.money]){
						q.push(next);
					}
				}
				edge next = s;
				next.enemy += G[s.to][i].enemy;
				next.to = G[s.to][i].to;
				q.push(next);
			}
		}

	}

	return 0;
}