Buggy python submission (verdict: Time Limit Exceeded):
import math


class WeightedEdge:
    """Weighted edge."""

    def __init__(self, a, b, weight):
        self.a = a
        self.b = b
        self.weight = weight

    def __repr__(self):
        return "(%d - %d: %d)" % (self.a, self.b, self.weight)

    def __lt__(self, other):
        return self.a < other.b


class EdgeWeightedGraph:
    """Undirected Edge-weighted graph (1-n indexed)."""

    def __init__(self, V):
        self.__adj = [[] for _ in range(V + 1)]

    def add_edge(self, a, b, weight):
        self.__adj[a].append(WeightedEdge(a, b, weight))
        self.__adj[b].append(WeightedEdge(b, a, weight))

    def adj(self, a):
        return self.__adj[a]

    def num_nodes(self):
        return len(self.__adj) - 1


class FloydWarshall:
    """u a.k.a. WarshallFloyd.

    Find shortest paths between each combination of vertices in a graph.
    ???3????????????a, b, c???????????§???a???b???c??¨????????????a???c??¨??????????????????????????°a???c????????¢?????´??°?????????
    ????????????for???????????±?????????????????????????????¨.
    O(V^3)
    """

    # graph has nodes [1, n]
    def __init__(self, graph):
        n = graph.num_nodes()
        nodes = range(1, n + 1)
        self.__mat = [[math.inf for _ in range(n + 1)] for _ in range(n + 1)]
        self.__init_mat(graph, nodes)
        self.__compute(nodes)

    def __init_mat(self, graph, nodes):
        for i in nodes:
            self.__mat[i][i] = 0

        for i in nodes:
            for edge in graph.adj(i):
                self.__mat[edge.a][edge.b] = edge.weight

    def __compute(self, nodes):
        for i in nodes:  # via
            for j in nodes:  # from
                for k in nodes:  # to
                    val = self.__mat[j][i] + self.__mat[i][k]
                    if self.__mat[j][k] > val:
                        self.__mat[j][k] = val

    def distance(self, a, b):
        return self.__mat[a][b]


if __name__ == '__main__':
    while True:
        n, m = map(int, input().split())
        if n == 0 and m == 0:
            break

        g_cost = EdgeWeightedGraph(m)
        g_time = EdgeWeightedGraph(m)
        for _ in range(n):
            a, b, cost, time = map(int, input().split())
            g_cost.add_edge(a, b, cost)
            g_time.add_edge(a, b, time)

        fw_cost = FloydWarshall(g_cost)
        fw_time = FloydWarshall(g_time)
        k = int(input())
        for _ in range(k):
            p, q, r = map(int, input().split())
            if r == 0:
                ans = fw_cost.distance(p, q)
            else:
                ans = fw_time.distance(p, q)
            print(ans)

Fixed submission:
from heapq import heappop, heappush


class WeightedEdge:
    """Weighted edge."""

    def __init__(self, a, b, weight):
        self.a = a
        self.b = b
        self.weight = weight

    def __repr__(self):
        return "(%d - %d: %d)" % (self.a, self.b, self.weight)

    def __lt__(self, other):
        return self.a < other.b


class EdgeWeightedGraph:
    """Undirected Edge-weighted graph (1-n indexed)."""

    def __init__(self, V):
        self.__adj = [[] for _ in range(V + 1)]

    def add_edge(self, a, b, weight):
        self.__adj[a].append(WeightedEdge(a, b, weight))
        self.__adj[b].append(WeightedEdge(b, a, weight))

    def adj(self, a):
        return self.__adj[a]

    def num_nodes(self):
        return len(self.__adj) - 1


class Dijkstra:
    """Single root shortest path by Dijkstra."""

    def __init__(self, graph, s, t):
        self.dist_to = [float('inf') for _ in range(graph.num_nodes() + 1)]
        self.dist_to[s] = 0
        pq = []
        heappush(pq, (0, s))
        while pq:
            w, a = heappop(pq)
            if a == t:
                return
            if self.dist_to[a] < w:
                continue
            for edge in graph.adj(a):
                if self.dist_to[edge.b] > self.dist_to[a] + edge.weight:
                    self.dist_to[edge.b] = self.dist_to[a] + edge.weight
                    heappush(pq, (self.dist_to[edge.b], edge.b))


if __name__ == '__main__':
    while True:
        n, m = map(int, input().split())
        if n == 0 and m == 0:
            break

        g_cost = EdgeWeightedGraph(m)
        g_time = EdgeWeightedGraph(m)
        for _ in range(n):
            a, b, cost, time = map(int, input().split())
            g_cost.add_edge(a, b, cost)
            g_time.add_edge(a, b, time)

        k = int(input())
        for _ in range(k):
            p, q, r = map(int, input().split())
            if r == 0:
                fw_cost = Dijkstra(g_cost, p, q)
                ans = fw_cost.dist_to[q]
            else:
                fw_time = Dijkstra(g_time, p, q)
                ans = fw_time.dist_to[q]
            print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
from heapq import heappop, heappush


class WeightedEdge:
    """Weighted edge."""

    def __init__(self, a, b, weight):
        self.a = a
        self.b = b
        self.weight = weight

    def __repr__(self):
        return "(%d - %d: %d)" % (self.a, self.b, self.weight)

    def __lt__(self, other):
        return self.a < other.b


class EdgeWeightedGraph:
    """Undirected Edge-weighted graph (1-n indexed)."""

    def __init__(self, V):
        self.__adj = [[] for _ in range(V + 1)]

    def add_edge(self, a, b, weight):
        self.__adj[a].append(WeightedEdge(a, b, weight))
        self.__adj[b].append(WeightedEdge(b, a, weight))

    def adj(self, a):
        return self.__adj[a]

    def num_nodes(self):
        return len(self.__adj) - 1


class Dijkstra:
    """Single root shortest path by Dijkstra."""

    def __init__(self, graph, s):
        self.dist_to = [float('inf') for _ in range(graph.num_nodes() + 1)]
        self.dist_to[s] = 0
        pq = []
        heappush(pq, (0, s))
        while pq:
            w, a = heappop(pq)
            if self.dist_to[a] < w:
                continue
            for edge in graph.adj(a):
                if self.dist_to[edge.b] > self.dist_to[edge.a] + edge.weight:
                    self.dist_to[edge.b] = self.dist_to[edge.a] + edge.weight
                    heappush(pq, (self.dist_to[edge.b], edge.b))


if __name__ == '__main__':
    while True:
        n, m = map(int, input().split())
        if n == 0 and m == 0:
            break

        g_cost = EdgeWeightedGraph(m)
        g_time = EdgeWeightedGraph(m)
        for _ in range(n):
            a, b, cost, time = map(int, input().split())
            g_cost.add_edge(a, b, cost)
            g_time.add_edge(a, b, time)

        k = int(input())
        for _ in range(k):
            p, q, r = map(int, input().split())
            if r == 0:
                fw_cost = Dijkstra(g_cost, p)
                ans = fw_cost.dist_to[q]
            else:
                fw_time = Dijkstra(g_time, p)
                ans = fw_time.dist_to[q]
            print(ans)

Fixed submission:
from heapq import heappop, heappush


class WeightedEdge:
    """Weighted edge."""

    def __init__(self, a, b, weight):
        self.a = a
        self.b = b
        self.weight = weight

    def __repr__(self):
        return "(%d - %d: %d)" % (self.a, self.b, self.weight)

    def __lt__(self, other):
        return self.a < other.b


class EdgeWeightedGraph:
    """Undirected Edge-weighted graph (1-n indexed)."""

    def __init__(self, V):
        self.__adj = [[] for _ in range(V + 1)]

    def add_edge(self, a, b, weight):
        self.__adj[a].append(WeightedEdge(a, b, weight))
        self.__adj[b].append(WeightedEdge(b, a, weight))

    def adj(self, a):
        return self.__adj[a]

    def num_nodes(self):
        return len(self.__adj) - 1


class Dijkstra:
    """Single root shortest path by Dijkstra."""

    def __init__(self, graph, s, t):
        self.dist_to = [float('inf') for _ in range(graph.num_nodes() + 1)]
        self.dist_to[s] = 0
        pq = []
        heappush(pq, (0, s))
        while pq:
            w, a = heappop(pq)
            if a == t:
                return
            if self.dist_to[a] < w:
                continue
            for edge in graph.adj(a):
                if self.dist_to[edge.b] > self.dist_to[a] + edge.weight:
                    self.dist_to[edge.b] = self.dist_to[a] + edge.weight
                    heappush(pq, (self.dist_to[edge.b], edge.b))


if __name__ == '__main__':
    while True:
        n, m = map(int, input().split())
        if n == 0 and m == 0:
            break

        g_cost = EdgeWeightedGraph(m)
        g_time = EdgeWeightedGraph(m)
        for _ in range(n):
            a, b, cost, time = map(int, input().split())
            g_cost.add_edge(a, b, cost)
            g_time.add_edge(a, b, time)

        k = int(input())
        for _ in range(k):
            p, q, r = map(int, input().split())
            if r == 0:
                fw_cost = Dijkstra(g_cost, p, q)
                ans = fw_cost.dist_to[q]
            else:
                fw_time = Dijkstra(g_time, p, q)
                ans = fw_time.dist_to[q]
            print(ans)