#include <assert.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_N 100
#define MAX_M 3000
#define NUMBER_OF_NODES 10000

#define SWAP(type, a, b) do {type _tmp; _tmp = a; a = b; b = _tmp;} while(0)

typedef struct {
	int v;
	int dist;
} state;

bool greater(state a, state b) {
	return a.dist > b.dist;
}

// priority_queue
typedef state value_type;

typedef struct skew_heap{
	struct skew_heap *left, *right;
	value_type value;
} skew_heap;

skew_heap *meld(skew_heap *a, skew_heap *b) {
	if(a == NULL) return b;
	if(b == NULL) return a;
	if(greater(a->value, b->value)) SWAP(skew_heap *, a, b);
	a->right = meld(a->right, b);
	SWAP(skew_heap *, a->left, a->right);
}

int next_index = 0;
skew_heap nodes[NUMBER_OF_NODES];
skew_heap *root = NULL;

bool empty() {
	return root == NULL;
}

void enqueue(value_type value) {
	skew_heap *new_node = (nodes + next_index);
	next_index = (next_index + 1) % NUMBER_OF_NODES;
	new_node->left = NULL;
	new_node->right = NULL;
	new_node->value = value;
	root = meld(root, new_node);
}

value_type dequeue() {
	if(root == NULL) return (value_type){-1, -1};
	value_type res = root->value;
	root = meld(root->left, root->right);
	return res;
}

void clear() {
	root = NULL;
}

// graph
int n, m;
int num;
int head[MAX_N], next[MAX_M * 2], to[MAX_M * 2];
int costs[MAX_M * 2], times[MAX_M * 2];
int dist[MAX_N];

void init() {
	num = 0;
	memset(head, -1, sizeof(head));
}

void add_edge(int u, int v, int c, int t) {
	next[num] = head[u];
	head[u] = num;
	to[num] = v;
	costs[num] = c;
	times[num] = t;
	++num;
}

// calc dist
int dijkstra(int start, int goal, int r) {
	int i, e;
	const int *weight = (r ? times : costs);

	for(i = 0; i < n; ++i) dist[i] = INT_MAX;
	dist[start] = 0;
	clear();
	enqueue((state){start, 0});

	while(!empty()) {
		state current = dequeue();
		if(dist[current.v] < current.dist)
			continue;

		if(current.v == goal)
			return dist[goal];

		for(e = head[current.v]; e != -1; e = next[e]) {
			int next_dist = current.dist + weight[e];
			if(dist[to[e]] > next_dist) {
				dist[to[e]] = next_dist;
				enqueue((state){to[e], next_dist});
			}
		}
	}
	assert(false);
}

int main(void) {
	int i;
	while(scanf("%d%d", &m, &n) == 2 && n) {
		init();
		for(i = 0; i < m; ++i) {
			int u, v, c, t;
			scanf("%d%d%d%d", &u, &v, &c, &t);
			--u; --v;
			add_edge(u, v, c, t);
			add_edge(v, u, c, t);
		}

		int query;
		scanf("%d", &query);

		while(query--) {
			int start, goal, r;
			scanf("%d%d%d", &start, &goal, &r);
			printf("%d\n", dijkstra(start - 1, goal - 1, r));
		}
	}
	return EXIT_SUCCESS;
}