#include <bits/stdc++.h>
#define fst first
#define snd second
#define fore(i,a,b) for(int i=a,ThxDem=b;i<ThxDem;++i)
#define pb push_back
#define ALL(s) s.begin(),s.end()
#define FIN ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define SZ(s) int(s.size())
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;

const int MAXN=10010;
int can[MAXN];

struct UnionFind {
	int n,comp;
	vector<int> uf,si,c;
	UnionFind(int n=0):n(n),comp(n),uf(n),si(n,1){
		fore(i,0,n)uf[i]=i;}
	int find(int x){return x==uf[x]?x:find(uf[x]);}
	bool join(int x, int y){
		if((x=find(x))==(y=find(y)))return false;
		if(si[x]<si[y])swap(x,y);
		si[x]+=si[y];uf[y]=x;comp--;c.pb(y);
		return true;
	}
	int snap(){return c.size();}
	void rollback(int snap){
		while(c.size()>snap){
			int x=c.back();c.pop_back();
			si[uf[x]]-=si[x];uf[x]=x;comp++;
		}
	}
};
enum {ADD,DEL,QUERY};
struct Query {int type,x,y,id;};
struct DynCon {
	vector<Query> q;
	UnionFind dsu;
	vector<int> mt;
	map<pair<int,int>,int> last;
	DynCon(int n):dsu(n){}
	void add(int x, int y){
		if(x>y)swap(x,y);
		q.pb((Query){ADD,x,y,-1});mt.pb(-1);last[{x,y}]=q.size()-1;
	}
	void remove(int x, int y){
		if(x>y)swap(x,y);
		q.pb((Query){DEL,x,y,-1});
		int pr=last[{x,y}];mt[pr]=q.size()-1;mt.pb(pr);
	}
	void query(int x, int y,int id){q.pb((Query){QUERY,x,y,id});mt.pb(-1);}
	void process(){ // answers all queries in order
		if(!q.size())return;
		fore(i,0,q.size())if(q[i].type==ADD&&mt[i]<0)mt[i]=q.size();
		go(0,q.size());
	}
	void go(int s, int e){
		if(s+1==e){
			if(q[s].type==QUERY){
				can[q[s].id]|=dsu.find(q[s].x)==dsu.find(q[s].y);
			}
			return;
		}
		int k=dsu.snap(),m=(s+e)/2;
		for(int i=e-1;i>=m;--i)if(mt[i]>=0&&mt[i]<s)dsu.join(q[i].x,q[i].y);
		go(s,m);dsu.rollback(k);
		for(int i=m-1;i>=s;--i)if(mt[i]>=e)dsu.join(q[i].x,q[i].y);
		go(m,e);dsu.rollback(k);
	}
};

int p[MAXN];
int find(int x){return p[x]=p[x]==x?x:find(p[x]);}
void join(int x, int y){p[find(x)]=find(y);}

vector<pair<ii,int>> eds[MAXN],qss[MAXN];
vector<int> cols[MAXN],wh[MAXN];
vector<ii> g[MAXN];
int rep[MAXN],repcol[MAXN];

void doit(int id){
	vector<pair<ii,int>> ed=eds[id], qs=qss[id];
	fore(i,0,SZ(wh[id])) rep[wh[id][i]]=i;
	fore(i,0,SZ(cols[id])) repcol[cols[id][i]]=i;
	
	for(auto &e:ed){
		e.fst.fst=rep[e.fst.fst];
		e.fst.snd=rep[e.fst.snd];
		e.snd=repcol[e.snd];
	}
	for(auto &q:qs) q.fst.fst=rep[q.fst.fst], q.fst.snd=rep[q.fst.snd];
	
	int n=SZ(wh[id]),k=SZ(cols[id]);
	
	vector<vector<ii>> v(k);
	for(auto e:ed) v[e.snd].pb(e.fst);
	
	DynCon dc(n);
	
	fore(i,0,k) for(auto x:v[i]) dc.add(x.fst,x.snd);
	
	fore(i,0,k){
		for(auto x:v[i]) dc.remove(x.fst,x.snd);
		for(auto q:qs) dc.query(q.fst.fst, q.fst.snd, q.snd);
		for(auto x:v[i]) dc.add(x.fst,x.snd);
	}
	
	dc.process();
	
	for(auto q:qs) can[q.snd]|=k%2;
}

int main(){FIN;
	int t,tt=1; cin>>t;
	while(t--){
		int n,m,q; cin>>n>>m>>q;
		
		fore(i,0,n){
			g[i].clear();
			cols[i].clear();
			wh[i].clear();
			eds[i].clear();
			p[i]=i;
		}
		
		fore(i,0,q){
			qss[i].clear();
		}
		
		fore(i,0,q) can[i]=0;
		
		vector<pair<ii,int>> ed;
		
		fore(i,0,m){
			int x,y,w; cin>>x>>y>>w; x--; y--;
			ed.pb({{x,y},w});
			join(x,y);
		}
		
		for(auto e:ed) eds[find(e.fst.fst)].pb(e), cols[find(e.fst.fst)].pb(e.snd);
		
		fore(i,0,n){
			sort(ALL(cols[i]));
			cols[i].erase(unique(ALL(cols[i])),cols[i].end());
		}
		fore(i,0,n) wh[find(i)].pb(i);
		
		fore(i,0,n) sort(ALL(wh[i]));
		
		fore(i,0,q){
			int x,y; cin>>x>>y; x--; y--;
			if(find(x)==find(y)) qss[find(x)].pb({{x,y},i});
		}
		
		
		fore(i,0,n) if(find(i)==i) doit(i);
		
		int res=0;
		fore(i,0,q) res+=can[i];
		
		cout<<"Case #"<<tt++<<": "<<res<<"\n";
	}
}