#include<iostream>
#include<vector>
#include<map>
#include<queue>
#include<functional>
#define pb push_back
#define MAX_V 2000//場合によって変更
#define INF 1000000000
using namespace std;
typedef pair<int,int> P;//firstは最短距離,secondは頂点番号
struct edge{
	int to,cost;
};
int V;//頂点の数
vector<vector<edge> > G;
//-----------
vector<vector<edge> > G2;
//-----------
int dijkstra(int s,int g){
	priority_queue<P,vector<P> , greater<P> > que;
	vector<int> d(V,INF);
	d[s]=0;
	que.push(P(0,0));
	while(!que.empty()){
		P p=que.top();
		que.pop();
		int v=p.second;
		if(d[v]<p.first)
			continue;
		for(int i=0;i<G[v].size();i++){
			edge e=G[v][i];
			if(d[e.to]>d[v]+e.cost){
				d[e.to]=d[v]+e.cost;
				que.push(P(d[e.to],e.to));
			}
		}
	}
	
	return d[g];
}
//-----------
int dijkstra2(int s,int g){
	priority_queue<P,vector<P> , greater<P> > que;
	vector<int> d(V,INF);
	d[s]=0;
	que.push(P(0,0));
	while(!que.empty()){
		P p=que.top();
		que.pop();
		int v=p.second;
		if(d[v]<p.first)
			continue;
		for(int i=0;i<G2[v].size();i++){
			edge e=G2[v][i];
			if(d[e.to]>d[v]+e.cost){
				d[e.to]=d[v]+e.cost;
				que.push(P(d[e.to],e.to));
			}
		}
	}
	
	return d[g];
}
//--------------
int main(){
	int E;
	while(cin>>E>>V,E){
		G.clear();
		G.resize(V);
		//------------
		G2.clear();
		G2.resize(V);
		//---------------
		for(int i=0;i<E;i++){
			int x,y,c,t;
			cin>>x>>y>>c>>t;x--;y--;
			edge e;
			e.cost=c;
			e.to=y;
			G[x].pb(e);
			e.to=x;
			G[y].pb(e);
			//--------------
			e.cost=t;
			e.to=y;
			G2[x].pb(e);
			e.to=x;
			G2[y].pb(e);
			//---------------
		}
		int n;
		cin>>n;
		for(int i=0;i<n;i++){
			int s,t,q;
			cin>>s>>t>>q;
			if(q==0)
			cout<<dijkstra(s-1,t-1)<<endl;
			else
			cout<<dijkstra2(s-1,t-1)<<endl;
		}
	}
	
	return 0;
}