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

struct Node{
  int num;

  vector<int> edge_to;
  vector<int> edge_cost;

  bool done;
  int cost;
};

int dijkstra (vector<Node> g,int start,int goal){
  int d;
  g[start].cost=0;

  while(1){
    d=-1;

    for(int i=1;i<=g.size();i++){
      if( g[i].done || g[i].cost < 0 ) continue;
      if( d==-1 || g[i].cost < g[d].cost ) d=i;
    }

    if(d==-1) break;
    g[d].done=true;

    for(int i=0; i< g[d].edge_to.size(); i++){
      int to = g[d].edge_to[i];
      int cost = g[d].cost + g[d].edge_cost[i];
      if(g[to].cost < 0 || cost < g[to].cost)
	g[to].cost = cost;
    }
  }

  return g[goal].cost;
}

int main(){
  for(;;){
    int n,m,a,b,c,t,p,q,r;
    cin>>n>>m;
    if(n==0&&m==0)break;

    vector<Node> time_graph,cost_graph;
    time_graph.reserve(m+1);
    time_graph.resize(m+1);
    cost_graph.reserve(m+1);
    cost_graph.resize(m+1);

    Node no;
    for(int i=1;i<=m;i++){
      no.num = i;
      no.done = false;
      no.cost = -1;
      no.edge_to.clear();
      no.edge_cost.clear();
      time_graph[i] = no;
      cost_graph[i] = no;
    }


    while(n--){
      cin>>a>>b>>c>>t;
      time_graph[a].edge_to.push_back(b);
      time_graph[b].edge_to.push_back(a);
      cost_graph[a].edge_to.push_back(b);
      cost_graph[b].edge_to.push_back(a);
      cost_graph[a].edge_cost.push_back(c);
      cost_graph[b].edge_cost.push_back(c);
      time_graph[a].edge_cost.push_back(t);
      time_graph[b].edge_cost.push_back(t);
    }

    cin>>n;
    while(n--){
      cin>>p>>q>>r;

      vector<Node> n;

      if(r==1){
	n.reserve(time_graph.size());
	n.resize(time_graph.size());
	n.assign(time_graph.begin(),time_graph.end());
      }else{
	n.reserve(cost_graph.size());
	n.resize(cost_graph.size());
	n.assign(cost_graph.begin(),cost_graph.end());
      }

      cout<<dijkstra(n,p,q)<<endl;

    }
  }
}