#include <iostream>
#include <vector>
#include <queue>

using namespace std;

struct edge {
    int to;
    int cost;
};

struct status {
    int cost;
    int v;

    bool operator<(const status &another) const { return cost < another.cost; };

    bool operator>(const status &another) const { return cost > another.cost; };
};


int n;

vector<int> dijkstra(vector<vector<edge>> &graph, int s) {
    priority_queue<status, vector<status>, greater<>> que;
    vector<int> dis(n, 1145141919);
    dis[s] = 0;
    que.push({0, s});

    while (!que.empty()) {
        status now = que.top();
        que.pop();

        if (dis[now.v] < now.cost)continue;

        for (auto next:graph[now.v]) {
            if (dis[next.to] > dis[now.v] + next.cost) {
                dis[next.to] = dis[now.v] + next.cost;
                que.push({dis[next.to], next.to});
            }
        }
    }
    
    return dis;
}

int main() {
    while (true) {
        int m;
        cin >> m >> n;
        if (m == 0)break;

        vector<vector<edge>> graphc(n);
        vector<vector<edge>> grapht(n);
        for (int i = 0; i < m; i++) {
            int from, to, cost, time;
            cin >> from >> to >> cost >> time;
            from--;
            to--;
            graphc[from].push_back({to, cost});
            graphc[to].push_back({from, cost});
            grapht[from].push_back({to, time});
            grapht[to].push_back({from, time});
        }

        int k;
        cin >> k;
        for (int i = 0; i < k; i++) {
            int start, end, r;
            cin >> start >> end >> r;
            start--;
            end--;
            auto dis = dijkstra((r == 0 ? graphc : grapht), start);
            cout << dis[end] << endl;
        }
    }
    return 0;
}
