#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

const int INFTY=1<<29;

struct Edge{
	int src,dst,weight;
	Edge(){}
	Edge(int s,int d,int w):src(s),dst(d),weight(w){}
	bool operator<(const Edge& e)const{return weight<e.weight;}
	bool operator>(const Edge& e)const{return weight>e.weight;}
};
typedef vector<vector<Edge> > Graph;

void dijkstra(const Graph& g,int start,vector<int>& dist)
{
	priority_queue<Edge,vector<Edge>,greater<Edge> > pq;
	pq.push(Edge(-1,start,0));
	while(pq.size()){
		Edge cur=pq.top(); pq.pop();
		if(dist[cur.dst]<=cur.weight) continue;
		dist[cur.dst]=cur.weight;
		for(int i=0;i<g[cur.dst].size();i++){
			const Edge& e=g[cur.dst][i];
			if(dist[e.dst]<=e.weight) continue;
			pq.push(Edge(e.src,e.dst,cur.weight+e.weight));
		}
	}
}

int main()
{
	for(int n,m;scanf("%d%d",&n,&m),n|m;){
		Graph g1(m),g2(m);
		for(int i=0;i<n;i++){
			int a,b,cost,time; scanf("%d%d%d%d",&a,&b,&cost,&time);
			a--; b--;
			g1[a].push_back(Edge(a,b,cost));
			g1[b].push_back(Edge(b,a,cost));
			g2[a].push_back(Edge(a,b,time));
			g2[b].push_back(Edge(b,a,time));
		}
		vector<vector<int> > w1(m,vector<int>(m,INFTY)),w2=w1;
		for(int i=0;i<m;i++){
			dijkstra(g1,i,w1[i]);
			dijkstra(g2,i,w2[i]);
		}
		int k; scanf("%d",&k);
		for(int i=0;i<k;i++){
			int p,q,r; scanf("%d%d%d",&p,&q,&r);
			if(r==0)
				printf("%d\n",w1[p-1][q-1]);
			else
				printf("%d\n",w2[p-1][q-1]);
		}
	}
	
	return 0;
}