#include <iostream>
#include <vector>
#include <queue>

using namespace std;

struct Edge {
	int to, cost, time;
	Edge(int _t, int _c, int _ti) : to(_t), cost(_c), time(_ti) {}
};

bool operator > (const Edge& e1, const Edge& e2) {
	if (e1.cost > e2.cost) return true;
	if (e1.cost == e2.cost) {
		if (e1.time > e2.time) return true;
		if (e1.to > e2.to) return true;
	}
	return false;
}

int n, m, k;
vector< vector<Edge> > G;

int INF = (int)1e9;
int dist[110];

int dks(int s, int t, int r) {
	fill(dist, dist + 110, INF);
	
	priority_queue<Edge, vector<Edge>, greater<Edge> > que;
	que.push(Edge(s, 0, 0));
	
	while (!que.empty()) {
		Edge e1 = que.top(); que.pop();
		
		for (int i = 0; i < (int)G[e1.to].size(); i++) {
			Edge e2 = G[e1.to][i];
			
			if (r%2) {
				if (dist[e2.to] > e1.time + e2.time) {
					dist[e2.to] = e1.time + e2.time;
					que.push(Edge(e2.to, 0, e1.time + e2.time));
				}
			} else {
				if (dist[e2.to] > e1.cost + e2.cost) {
					dist[e2.to] = e1.cost + e2.cost;
					que.push(Edge(e2.to, e1.cost + e2.cost, 0));
				}
			}
		}
	}
	
	return dist[t];
}

int main() {
	while (1) {
		cin >> n >> m; if (n==0 && m==0) break;
		
		G.assign(n, vector<Edge>());
		
		for (int i = 0; i < n; i++) {
			int a, b, c, t; cin >> a >> b >> c >> t;
			a--; b--;
			G[a].push_back(Edge(b, c, t));
			G[b].push_back(Edge(a, c, t));
		}
		
		cin >> k;
		
		for (int i = 0; i < k; i++) {
			int p, q, r; cin >> p >> q >> r;
			p--; q--;
			cout << dks(p, q, r) << endl;
		}
	}
	
	return 0;
}