#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();
}
}