#include "bits/stdc++.h"
using namespace std;
#define dbg(var) cout<<#var<<"="<<var<<" "
#define nl cout<<"\n"
#define fr(i,n) for(int i=0;i<n;i++)
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define vi vector<int>
#define vvi vector<vi>
#define pb push_back
#define fa(v) for(auto &i:v)
#define all(v) v.begin(),v.end()
#define sz(v) (int)(v.size())
//#define int long long
struct DSU
{
	int connected;
	vector<int> par, sz;

	void init(int n) 
	{
		par = sz = vector<int> (n + 1, 0);
		for(int i = 1; i <= n; i++)
			par[i] = i, sz[i] = 1;
		connected = n;
	}

	int getPar(int u)
	{
		while(u != par[u])
		{
			par[u] = par[par[u]];
			u = par[u];
		}
		return u;
	}

	int getSize(int u)
	{
		return sz[getPar(u)];
	}

	void unite(int u, int v)
	{
		int par1 = getPar(u), par2 = getPar(v);

		if(par1 == par2)
			return;

		connected--;

		if(sz[par1] > sz[par2])
			swap(par1, par2);

		sz[par2] += sz[par1];
		sz[par1] = 0;
		par[par1] = par[par2];
	}
};

struct  edge
{
	int x,y,id,wt;
	bool operator < (const edge &other) const{
		return wt < other.wt;
	};
};

struct query{
	int x,y,wt,id;
	bool operator < (const query &other) const{
		return wt < other.wt;
	};

};
void solve(){
    int n,m,q; cin >> n >> m >> q;
    DSU dsu; dsu.init(n); //// dsu
    edge Edges[m]; query Qry[q];
    int ans[q];
    fr(i,m) cin >> Edges[i].x >> Edges[i].y >> Edges[i].wt, Edges[i].id = i;
    fr(i,q) cin >> Qry[i].x >> Qry[i].y >> Qry[i].wt,Qry[i].id = i;
    sort(Edges, Edges + m);
    sort(Qry, Qry + q);
    int Edgeptr = 0;
    fr(i,q){
    	while(Edgeptr < m and Edges[ Edgeptr ].wt <= Qry[i].wt){
    		dsu.unite(Edges[ Edgeptr ].x , Edges[ Edgeptr ].y);
    		Edgeptr++;
    	}
    	ans[Qry[i].id] = (dsu.getPar(Qry[i].x) == dsu.getPar(Qry[i].y)) ;
    }

    fr(i,q) cout << ans[i] << "\n";
}
int32_t main()
{
   ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
   int tst; cin >> tst; while(tst--){
   	solve();
   }
}