#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <iostream>

using namespace std;

typedef long long LL;

const int INF = 0x3fffffff;
const int maxN = 20010;
const int maxM = 2000000;

struct graph
{
    int v, next, op, c;
}edge[maxM];
 
int lv[maxN], vect[maxN];
int S, T, tot;
 
void add(int x, int y, int z)
{
	//printf("%d %d\n", x, y);
    edge[++tot].v = y;
    edge[tot].c = z;
    edge[tot].next = vect[x];
    vect[x] = tot;
    edge[tot].op = tot + 1;
    
    edge[++tot].v = x;
    edge[tot].c = 0;
    edge[tot].next = vect[y];
    vect[y] = tot;
    edge[tot].op = tot - 1;
}

bool build()
{
    memset(lv, 0, sizeof(lv));
    queue<int> Q;
    Q.push(S);
    lv[S] = 1;
    while (!Q.empty()){
            int u = Q.front();
            Q.pop();
            for (int tt = vect[u]; tt; tt = edge[tt].next){
                    int v = edge[tt].v; 
                    int c = edge[tt].c;
                    if (c > 0 && !lv[v]){
                            lv[v] = lv[u] + 1;
                            Q.push(v);
                            if (v == T) return true;
                    }
            }
    }
    return false;   
}
 
int dfs(int u, int flow)
{
    if (u == T || !flow) return flow;
    int tp, now = 0;
    for (int tt = vect[u]; tt; tt = edge[tt].next){
            int v = edge[tt].v;
            int c = edge[tt].c;
            int op = edge[tt].op;
            if (c > 0 && lv[u] + 1 == lv[v]){
                tp = dfs(v, min(flow, c));
                now = now + tp;
                flow = flow - tp;     
                edge[tt].c -= tp;
                edge[op].c += tp;
            }    
    }
    if (!now) lv[u] = 0; 
    return now;
}
 
int dinic()
{
    int ans = 0;
    while (build()) ans += dfs(S, INF);
    return ans;
}

int n, m;
int P, Q;
int row[110][110], col[110][110], g[110][110];

int main()
{
     int Case, x, y;
     scanf("%d", &Case);
     while(Case--){
     	scanf("%d%d", &n, &m);
		memset(row, 0, sizeof(row));
		memset(col, 0, sizeof(col));
		memset(g, 0, sizeof(g));
		tot = 0;
		memset(vect, 0, sizeof(vect));
		// *  1
		// #  2
		scanf("%d", &P);
		for (int i = 0; i < P; i++){
			scanf("%d%d", &x, &y);
			g[x][y] = 1;
		}
		scanf("%d", &Q);
		for (int i = 0; i < Q; i++){
			scanf("%d%d", &x, &y);
			g[x][y] = 2;
		}
		S = 1, T = 2;
		int cnt = 2;
		for (int i = 1; i <= n; i++){
			for (int j = 1; j <= m; j++){
				if (g[i][j] == 1){
					int tagR, tagC;
					x = i;
					y = j;	
					if (!row[x][y]){
						tagR = ++cnt;
						add(S, tagR, 1);
						while(y <= m && g[x][y] != 2){
							row[x][y] = cnt;
							y++;
						}
					}
					else
						tagR = row[x][y];
					x = i;
					y = j;
					if (!col[x][y]){
						tagC = ++cnt;
						add(tagC, T, 1);
						while(x <= n && g[x][y] != 2){
							col[x][y] = cnt;
							x++;
						}
					}
					else
						tagC = col[x][y];
					add(tagR, tagC, 1);
				}//if
			}
		}///
		printf("%d\n", dinic());
		/*
		for (int i = 1; i <= n; i++){
			for (int j = 1; j <= m; j++){
				printf("%d ", col[i][j]);
			}
			puts("");
		}
		*/
     }
     return 0;
}

