#include <iostream>
#include <limits.h>

using namespace std;

int m;

int dijkstra( const int data[101][101], int start, int end )
{
	int i,j,next,min;
	bool visited[101];
	int distance[101];

	for( i = 1;i <= 100;i++ ){
		visited[i] = false;
		distance[i] = INT_MAX;
	}

	distance[start] = 0; next = start;

	do{
		i = next; visited[i] = true; min = INT_MAX;
		for(j = 1;j <= m;j++){
			if(visited[j]) continue;
			if(data[i][j] < INT_MAX && distance[i] + data[i][j] < distance[j]) {
				distance[j] = distance[i] + data[i][j];
			}
			if( distance[j] < min ){
				min = distance[j]; next = j;
			}
		}
	} while( min < INT_MAX );

	return distance[end];
}


int main(int argc, char const* argv[])
{
	int n,weight[101][101][2];

	while( cin >> n >> m && n != 0 && m != 0 ){
		int a,b,c,d;
		for( int i = 0;i < 101;i++ ){
			for( int j = 0;j < 101;j++ ){
				weight[i][j][0] = INT_MAX;
				weight[i][j][1] = INT_MAX;
			}
		}

		for( int i = 0;i < n;i++ ){
			cin >> a >> b >> c >> d;
			weight[a][b][0] = c;
			weight[b][a][0] = c;
			weight[a][b][1] = d;
			weight[b][a][1] = d;
		}

		cin >> n;

		for( int i = 0;i < n;i++ ){
			int data[101][101];
			int p,q,r;
			cin >> p >> q >> r;
			for( int j = 1;j < 101;j++ ){
				for( int k = 1;k <101;k++ ) data[j][k] = weight[j][k][r];
			}
			cout << dijkstra( data, p, q ) << endl;
		}
	}


	return 0;

		
}
#include <bits/stdc++.h>
using namespace std;

#define iota(i,n,b,s) for(int i=int(b);i!=int((b)+(s)*(n));i+=(s))
#define range(i,n,m) iota(i,(((n)>(m))?((n)-(m)+1):((m)-(n)+1)),(n),((n)>(m)?-1:1))
#define rep(i,n) iota(i,(n),0,1)

#define INF (1e9)
#define EPS (1e-9)
#define cons(a,b) (make_pair(a,b))
#define car(a) (a.first)
#define cdr(a) (a.second)
#define cadr(a) (car(cdr(a)))
#define cddr(a) (cdr(cdr(a)))
#define all(a) a.begin(), a.end()
#define trace(var) cerr<<">>> "<<#var<<" = "<<var<<endl;

typedef long long INTEGER;
typedef double FLOAT;

template<class S, class T>
ostream& operator<<(ostream& os, pair<S,T> p) {
  os << '(' << car(p) << ", " << cdr(p) << ')';
  return os;
}

template<class T>
ostream& operator<<(ostream& os, vector<T> v) {
  os << v[0];
  for (int i=1, len=v.size(); i<len; ++i) os << ' ' << v[i];
  return os;
}

const int MM = 100;
int cost[MM][MM];
int toki[MM][MM];

int main() {

entry:;
  int n, m; cin >> m >> n;
  if (n + m == 0) return 0;

  rep (i, n) {
    rep (j, n) {
      cost[i][j] = INF;
      toki[i][j] = INF;
    }
    cost[i][i] = 0;
    toki[i][i] = 0;
  }

  rep (i, m) {
    int a, b, c, t;
    cin >> a >> b >> c >> t;
    --a; --b;
    cost[a][b] = cost[b][a] = c;
    toki[a][b] = toki[b][a] = t;
  }

  rep (k, n) {
    rep (i, n) {
      rep (j, n) {
        cost[i][j] = min(cost[i][j], cost[i][k] + cost[k][j]);
        toki[i][j] = min(toki[i][j], toki[i][k] + toki[k][j]);
      }
    }
  }

  //rep (i,n) { rep(j,n) { cout << cost[i][j] << ' '; } cout << endl; }

  int k; cin >> k;
  rep (i, k) {
    int a, b, t;
    cin >> a >> b >> t;
    --a; --b;
    if (t) {
      cout << toki[a][b] << endl;
    } else {
      cout << cost[a][b] << endl;
    }
  }

  goto entry;

  return 0;
}