Go: // Warshall–Floyd Algorithm

package main

import (
	"bufio"
	"os"
	"strings"
	"strconv"
	"fmt"
)

var scanner = bufio.NewScanner(os.Stdin)

const INF = 0x7FFFFFFF

func main() {
	for scanner.Scan() {
		buf := strings.Split(scanner.Text(), " ")
		n, _ := strconv.Atoi(buf[0])
		m, _ := strconv.Atoi(buf[1])
		if n == 0 && m == 0 {
			break
		}
		c_matrix := make([][]int, m)
		for i := range c_matrix {
			c_matrix[i] = make([]int, m)
		}
		t_matrix := make([][]int, m)
		for i := range t_matrix {
			t_matrix[i] = make([]int, m)
		}
		for i := 0; i < n; i++ {
			scanner.Scan()
			buf_ := strings.Split(scanner.Text(), " ")
			a, _ := strconv.Atoi(buf_[0])
			b, _ := strconv.Atoi(buf_[1])
			c, _ := strconv.Atoi(buf_[2])
			t, _ := strconv.Atoi(buf_[3])
			c_matrix[a-1][b-1] = c
			t_matrix[a-1][b-1] = t
		}
		c_dist := make([][]int, m)
		c_prev := make([][]int, m)
		t_dist := make([][]int, m)
		t_prev := make([][]int, m)
		for i := 0; i < m; i++ {
			c_dist[i] = make([]int, m)
			c_prev[i] = make([]int, m)
			t_dist[i] = make([]int, m)
			t_prev[i] = make([]int, m)
		}
		for i := 0; i < m; i++ {
			for j := 0; j < m; j++ {
				if c_matrix[i][j] == 0{
					c_dist[i][j] = INF
				} else {
					c_dist[i][j] = c_matrix[i][j]
				}
				if c_matrix[i][j] == 0{
					c_prev[i][j] = -1
				} else {
					c_prev[i][j] = i
				}
				if t_matrix[i][j] == 0{
					t_dist[i][j] = INF
				} else {
					t_dist[i][j] = t_matrix[i][j]
				}
				if t_matrix[i][j] == 0{
					t_prev[i][j] = -1
				} else {
					t_prev[i][j] = i
				}
			}
			c_dist[i][i] = 0
			t_dist[i][i] = 0
		}
		for k := 0; k < m; k++ {
			for i := 0; i < m; i++ {
				for j := 0; j < m; j++ {
					c_newlen := c_dist[i][k] + c_dist[k][j]
					if c_newlen < c_dist[i][j] {
						c_dist[i][j] = c_newlen
						c_prev[i][j] = c_prev[k][j]
					}
				}
			}
		}
		for k := 0; k < m; k++ {
			for i := 0; i < m; i++ {
				for j := 0; j < m; j++ {
					t_newlen := t_dist[i][k] + t_dist[k][j]
					if t_newlen < t_dist[i][j] {
						t_dist[i][j] = t_newlen
						t_prev[i][j] = t_prev[k][j]
					}

				}
			}
		}
		scanner.Scan()
		k, _ := strconv.Atoi(scanner.Text())
		for i := 0; i < k; i++ {
			scanner.Scan()
			buf_ := strings.Split(scanner.Text(), " ")
			p, _ := strconv.Atoi(buf_[0])
			q, _ := strconv.Atoi(buf_[1])
			r, _ := strconv.Atoi(buf_[2])
			switch r {
			case 0: fmt.Println(c_dist[p-1][q-1])
			case 1: fmt.Println(t_dist[p-1][q-1])
			}
		}
	}
}

C++: #include<iostream>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<string>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<bitset>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> i_i;

#define PI 3.141592653589793238462643383279
#define mod 1000000007LL
#define rep(i, n) for(i = 0;i < n;++i)
#define rep1(i, n) for(i = 1;i < n;++i)
#define per(i, n) for(i = n - 1;i > -1;--i)
#define int(x) int x; scanf("%d",&x)
#define int2(x, y) int x, y; scanf("%d%d",&x, &y)
#define int3(x, y, z) int x, y, z; scanf("%d%d%d",&x, &y, &z)
#define int4(v, x, y, z) int v, x, y, z; scanf("%d%d%d%d", &v, &x, &y, &z)
#define int5(v, w, x, y, z) int v, w, x, y, z; scanf("%d%d%d%d%d", &v, &w, &x, &y, &z)
#define ll2(x, y) ll x, y; cin >> x >> y;
#define scn(n, a) rep(i, n)cin >> a[i]
#define sc2n(n, a, b) rep(i, n)cin >> a[i] >> b[i]
#define pri(x) cout << (x) << "\n"
#define pri2(x, y) cout << (x) << " " << (y) << "\n"
#define pri3(x, y, z) cout << (x) << " " << (y) << " " << (z) << "\n"
#define pb push_back
#define mp make_pair
#define all(a) (a).begin(),(a).end()
#define endl "\n"
#define kabe puts("---------------------------")
#define kara puts("")
#define debug(x) cout << " --- " << (x) << "\n"
#define debug2(x, y) cout << " --- " << (x) << " " << (y) << "\n"
#define debug3(x, y, z) cout << " --- " << (x) << " " << (y) << " " << (z) << "\n"
#define X first
#define Y second
#define eps 0.0001
#define prid(x) printf("%.15lf\n", x)

#define ma 12345678
int G[100][100][2] = {0};

signed main(void){
  int i, j, k;
  for(int testcase = 0;testcase >= 0;testcase++){
    int2(n, m);
    if(n == 0 && m == 0)break;

    rep(i, 100)rep(j, 100)rep(k, 2)G[i][j][k] = ma;
    rep(i, n){
      int a, b, c, t;
      scanf("%d%d%d%d", &a, &b, &c, &t);
      --a; --b;
      G[a][b][0] = c; G[b][a][0] = c;
      G[a][b][1] = t; G[b][a][1] = t;
    }

    int l;
    rep(l, 2)rep(k, m)rep(i, m)rep(j, m){
      G[i][j][l] = min(G[i][k][l] + G[k][j][l], G[i][j][l]);
    }
    
    int(k);
    for(;k--;){
      int3(p, q, r);
      --p; --q;
      printf("%d\n", G[p][q][r]);
    }


//*/

//*/ break;
  }
  return 0;
}

C++: #include <iostream>
#include <vector>
using namespace std;
#define REP(i,n) for (int i=0; i<(n); ++i)

struct edge {
    int from, to, cost, time;
};

int main() {
    int n, m;
    while (cin >> n >> m, n || m) {
        vector<edge> edges;
        int a, b, v, u;
        REP(i,n) {
            cin >> a >> b >> v >> u;
            edges.push_back((edge){ a, b, v, u });
        }
        int d[2][101][101];
        REP(i,2) REP(j,101) REP(k,101) {
            d[i][j][k] = (j == k ? 0 : 1e8);
        }
        REP(i,101) REP(j,101) for (auto &e : edges) {
            d[0][j][e.to] = min(d[0][j][e.to], d[0][j][e.from] + e.cost);
            d[1][j][e.to] = min(d[1][j][e.to], d[1][j][e.from] + e.time);
        }
        int k, p, q, r;
        cin >> k;
        REP(i,k) {
            cin >> p >> q >> r;
            cout << d[r][p][q] << endl;
        }
    }
    return 0;
}

C++: #include<queue>
#include<cstdio>
#include<algorithm>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

template<class T>
class d_heap{
	static const int N_MAX=3000; // !!
	int n,d;
	T a[N_MAX];
public:
	d_heap(int d):n(0),d(d){}
	const T &find_min()const{ return a[0]; }
	void insert(const T &x){
		int u=n++;
		a[u]=x;
		while(u!=0 && a[(u-1)/d]>a[u]) swap(a[(u-1)/d],a[u]), u=(u-1)/d;
	}
	void delete_min(){
		a[0]=a[--n];
		for(int u=0;;){
			int v=u;
			for(int w=d*u+1;w<=d*u+d;w++) if(w<n && a[v]>a[w]) v=w;
			if(v==u) break;
			swap(a[v],a[u]);
			u=v;
		}
	}
	bool empty()const{ return n==0; }
	int size()const{ return n; }
};

#define define_heap d_heap< pair<int,int> > H(2);

const int INF=1<<29;

struct edge{ int v,cost1,cost2; };

int main(){
	for(int m,n;scanf("%d%d",&m,&n),n;){
		vector<edge> G[100];
		rep(i,m){
			int u,v,cost1,cost2; scanf("%d%d%d%d",&u,&v,&cost1,&cost2); u--; v--;
			G[u].push_back((edge){v,cost1,cost2});
			G[v].push_back((edge){u,cost1,cost2});
		}

		int q; scanf("%d",&q);
		while(q--){
			int s,t,type; scanf("%d%d%d",&s,&t,&type); s--; t--;

			int d[100];
			rep(u,n) d[u]=(u==s?0:INF);
			define_heap;
			H.insert(make_pair(0,s));
			while(!H.empty()){
				int d_now=H.find_min().first,u=H.find_min().second;
				H.delete_min();

				if(d[u]<d_now) continue;

				rep(i,G[u].size()){
					const edge &e=G[u][i];
					int d2=d_now+(type==0?e.cost1:e.cost2);
					if(d[e.v]>d2){
						d[e.v]=d2;
						H.insert(make_pair(d2,e.v));
					}
				}
			}

			printf("%d\n",d[t]);
		}
	}

	return 0;
}

C++: #include <bits/stdc++.h>
#define INF 114514810
#define FOR(i, r, n) for(int i=(r); i<(n); i++) 
#define REP(i, n) FOR(i, (0), n)

using namespace std;

int n, a, b, c, d, t = 0, sum = INF, ans, nodes = 0, p, q, r, w;
int x[102][102], y[102][102];

int main(){
	while (true){
		cin >> n >> nodes;
		if (n == 0 && nodes == 0) break;
		REP(i, 101)
			REP(j, 101){
			x[i][j] = (i == j ? 0 : INF);
			y[i][j] = (i == j ? 0 : INF);
		}
		REP(i, n){
			cin >> a >> b >> c >> d;
			x[a-1][b-1] = x[b-1][a-1] = c;
			y[a-1][b-1] = y[b-1][a-1] = d;
		}
		REP(k, nodes)
			REP(i, nodes)
			REP(j, nodes){
			x[i][j] = min(x[i][j], x[i][k] + x[k][j]);
			y[i][j] = min(y[i][j], y[i][k] + y[k][j]);
		}
		cin >> w;
		REP(k, w){
			cin >> p >> q >> r;
			if (r) cout << y[p-1][q-1] << endl;
			else cout << x[p-1][q-1] << endl;
		}
	}
}