#include<iostream>
#include<vector>
#include<queue>
using namespace std;

#define INF 100000000

struct edge {
	int to;
	int c, t;
};

int main() {
	int n, m, f, temp, s, k, p, q, r;
	vector<edge> g[101];
	queue<int> search;
	int mc[101][101], mt[101][101];
	edge e;
	cin >> n >> m;
	for(int i=0; i<=m; ++i) for(int j=0; j<=m; ++j) {
		mc[i][j] = mt[i][j] = INF;
	}
	for(int i=0; i<n; ++i) {
		cin >> f >> e.to >> e.c >> e.t;
		g[f].push_back(e);
		temp = e.to; e.to = f; f = temp;
		g[f].push_back(e);
	}
	for(int i=1; i<=m; ++i) {
		search.push(i); mc[i][i] = 0;
		while(!search.empty()) {
			s = search.front(); search.pop();
			for(vector<edge>::iterator it=g[s].begin(); it!=g[s].end(); ++it) {
				if(mc[i][s]+(*it).c<mc[i][(*it).to]) {
					mc[i][(*it).to] = mc[i][s]+(*it).c;
					search.push((*it).to);
					cout << i << " : " << s << " -> " << (*it).to << " = " << mc[i][(*it).to] << endl;
				}
			}
		}
		search.push(i); mt[i][i] = 0;
		while(!search.empty()) {
			s = search.front(); search.pop();
			for(vector<edge>::iterator it=g[s].begin(); it!=g[s].end(); ++it) {
				if(mt[i][s]+(*it).t<mt[i][(*it).to]) {
					mt[i][(*it).to] = mt[i][s]+(*it).t;
					search.push((*it).to);
				}
			}
		}
	}
	cin >> k;
	for(int i=0; i<k+1; ++i) {
		cin >> p >> q;
		if(!p&&!q) break;
		cin >> r;
		cout << (!r?mc[p][q]:mt[p][q]) << endl;
	}
	
	return 0;
}