//Done by: K Ashwin

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

#define REP(i, a, b) \
for (int i = int(a); i <= int(b); i++) // a to b, and variable i is local!
#define TR(c, it) \
for (auto it = (c).begin(); it != (c).end(); it++)

#define s(x) scanf("%d", &x)
#define sl(x) scanf("%lld", &x)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define set0(a) memset(a, 0, sizeof(a))
#define setdp(a) memset(a, -1, sizeof(a))
#define INF 2000000000
#define MOD 1000000007

struct edge
{
    int a, b, cap, flow;
};

vector <edge> e;
vector <int> g[2005];
vector <pii> p1, p2;
int L[2005], ptr[2005], S, T, n, m;

void add_edge(int a, int b, int cap)
{
    edge e1 = {a, b, cap, 0};
    edge e2 = {b, a, 0, 0};
    g[a].pb((int)e.size());
    e.pb(e1);
    g[b].pb((int)e.size());
    e.pb(e2);

    //cout << "edge " << a << " " << b << " " << cap << endl;
}

bool bfs()
{
    queue <int> q;
    int cur;

    set0(L);

    q.push(S);
    L[S] = 1;

    while (!q.empty()) {
        cur = q.front();
        q.pop();

        //cout << "qu " << cur << endl;

        for (int i = 0; i < g[cur].size(); i++) {
            int id = g[cur][i], to = e[id].b;

            if (!L[to] && e[id].flow < e[id].cap) {
                L[to] = L[cur] + 1;
                q.push(to);
            }
        }
    }

    //cout << "bfs " << L[T] << endl;

    return L[T];
}

int dfs(int cur, int flow)
{
    if (!flow)
        return 0;

    if (cur == T)
        return flow;

    for (; ptr[cur] < g[cur].size(); ptr[cur]++) {
        int id = g[cur][ptr[cur]], to = e[id].b;

        if (L[to] != L[cur] + 1)
            continue ;

        int pushed = dfs(to, min(flow, e[id].cap - e[id].flow));
        if (pushed) {
            e[id].flow += pushed;
            e[id^1].flow -= pushed;

            return pushed;
        }
    }

    return 0;
}

int dinic()
{
    int flow = 0, t1;

    while (bfs()) {
        set0(ptr);

        while (t1 = dfs(S, INF))
            flow += t1;
    }

    //cout << "flow " << flow << endl;

    return flow;
}

void mems()
{
    e.clear();
    p1.clear();
    p2.clear();
    REP (i, 0, 2002) {
        g[i].clear();
    }
}

int main()
{
    int t, x, y;

    cin >> t;

    while (t--) {
        mems();

        cin >> n >> m;

        S = 0;
        T = 2002;
        REP (i, 1, n) {
            s(x);
            s(y);

            p1.pb(mp(x, y));
        }

        REP (i, 1, m) {
            s(x);
            s(y);

            p2.pb(mp(x, y));
        }

        REP (i, 1, n)
            add_edge(S, i, 1);

        REP (i, 0, n - 1) {
            REP (j, 0, m - 1) {
                if (p1[i].fi == p2[j].fi || p1[i].se == p2[j].se || abs(p1[i].fi - p2[j].fi) == abs(p1[i].se - p2[j].se))
                    add_edge(i + 1, n + j + 1, 1);
            }
        }

        REP (i, 1, m)
            add_edge(n + i, T, 1);

        cout << dinic() << endl;
    }

    return 0;
}
