#include <iostream>
#include <cstring>
#include <queue>

using namespace std;

int N, M, L;

struct Edge {
	int to, dist, enemy;
	Edge(int _t, int _d, int _e) : to(_t), dist(_d), enemy(_e) {}
};
bool operator > (const Edge& e1, const Edge& e2) {
	if (e1.enemy < e2.enemy) return true;
	else if (e1.to < e2.to) return true;
	return e1.dist < e2.dist;
}
bool operator == (const Edge& e1, const Edge& e2) {
	if (e1.enemy == e2.enemy && e1.to==e2.to && e1.dist == e2.dist) return true;
	return false;
}
bool operator != (const Edge& e1, const Edge& e2) { return !(e1 == e2); }
bool operator < (const Edge& e1, const Edge& e2) { return !(e1 > e2) && (e1 != e2); }
bool operator >= (const Edge& e1, const Edge& e2) { return (e1 > e2) && (e1 == e2); }
bool operator <= (const Edge& e1, const Edge& e2) { return (e1 < e2) && (e1 == e2); }

const int INF = 1e9;
int d[110][110];

int main() {
	while (1) {
		cin >> N >> M >> L; if (N==0 && M==0 && L==0) break;
		vector< vector<Edge> > G(N+1, vector<Edge>());
		
		for (int i=0; i<M; i++) {
			int a, b, d, e; cin >> a >> b >> d >> e;
			G[a].push_back(Edge(b, d, e));
			G[b].push_back(Edge(a, d, e));
		}
		
		for (int i=0; i<=N; i++) fill(d[i], d[i] + L + 1, INF);
		
		d[1][0] = 0;
		
		priority_queue<Edge, vector<Edge>, greater<Edge> > q;
		q.push( Edge(1, 0, 0) );
		
		while (!q.empty()) {
			Edge e = q.top(); q.pop();
			
			for (int i=0; i<(int)G[e.to].size(); i++) {
				Edge ne = G[e.to][i];
				
				if (e.dist + ne.dist <= L) {
					if (d[ne.to][e.dist + ne.dist] > e.enemy) {
						d[ne.to][e.dist + ne.dist] = e.enemy;
						q.push(Edge(ne.to, e.dist + ne.dist, e.enemy));
					}
				}
				
				if (d[ne.to][e.dist] > e.enemy + ne.enemy) {
					d[ne.to][e.dist] = e.enemy + ne.enemy;
					q.push(Edge(ne.to, e.dist, e.enemy + ne.enemy));
				}
			}
		}
		
		int ans = INF;
		for (int i=0; i<=L; i++) ans = min(ans, d[N][i]);
		cout << ans << endl;
	}
	
	return 0;
}