rt.
#include<bits/stdc++.h>
using namespace std;
const int N=4e5+10;
int T,n,m1,m2;
int he1[N],t1=1,he2[N],t2=1,ans;
struct
{
int to,nex;
} G1[N],G2[N];
void add1(int u,int v)
{
G1[++t1]={v,he1[u]};
he1[u]=t1;
G1[++t1]={u,he1[v]};
he1[v]=t1;
}
void add2(int u,int v)
{
G2[++t2]={v,he2[u]};
he2[u]=t2;
G2[++t2]={u,he2[v]};
he2[v]=t2;
}
bool vise[N],vis[N],vis1[N],vis2[N];
vector<int> fill2(int x)
{
queue<int> q; q.push(x);
vector<int> ans;
while(!q.empty())
{
int u=q.front();q.pop();
if(vis[u]) continue;
vis[u]=1; ans.push_back(u);
for(int i=he2[u];i;i=G2[i].nex){
int v=G1[i].to;
if(!vis[v]) q.push(v);
}
}
return ans;
}
int fill1(vector<int> x)
{
for(int u:x) vis1[u]=1;
int tot=0,cut=0;
for(int u:x)
{
if(vis2[u]) continue;
++tot;
queue<int> q; q.push(u);
while(!q.empty())
{
int u=q.front();q.pop();
if(vis2[u]) continue;
vis2[u]=1;
for(int i=he1[u];i;i=G1[i].nex)
if(!vise[i>>1]) {
int v=G2[i].to;
if(vis1[v]){if(!vis2[v]) q.push(v);}
else ++cut,vise[i>>1]=1;
}
}
}
for(int u:x) vis1[u]=0;
return tot-1+cut;
}
void _solve()
{
for(int i=1;i<=n;++i)
vis[i]=vis2[i]=vis1[i]=he1[i]=he2[i]=0;
for(int i=1;i<=m2;++i) vise[i]=0;
t1=t2=1,ans=0;
cin>>n>>m1>>m2;
for(int i=1,u,v;i<=m1;++i)
cin>>u>>v,add1(u,v);
for(int i=1,u,v;i<=m2;++i)
cin>>u>>v,add2(u,v);
for(int i=1;i<=n;++i)
if(!vis[i]) ans+=fill1(fill2(i));
cout<<ans<<endl;
}
main()
{
int T;
for(cin>>T;T--;) _solve();
}