// ~icebear love attt~
#include<bits/stdc++.h>
using namespace std;

template<class T>
    bool minimize(T &a, const T &b) {
        if (a > b) return a = b, true;
        return false;
    }

template<class T>
    bool maximize(T &a, const T &b) {
        if (a < b) return a = b, true;
        return false;
    }

typedef long long ll;
typedef pair<int, int> ii;
typedef pair<int, ii> iii;

#define FOR(i, a, b) for(int i = (a); i <= (b); i++)
#define FORR(i, a, b) for(int i = (a); i >= (b); i--)
#define REP(i, n) for(int i = 0; i < (n); i++)
#define RED(i, n) for(int i = (n) - 1; i >= 0; i--)
#define all(v) v.begin(), v.end()
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define MASK(i) (1LL << (i))
#define task "fakerfmvp"

const int MOD = 1e9 + 7;
const int inf = 1e9 + 27092008;
const ll INF = 1e18 + 27092008;
const int N = 2e5 + 5;
int numNode, numUndir, numDir;
vector<ii> G[N];
vector<int> revG[N];
int numState;
ii edge[3 * N];

void init() {
    cin >> numNode >> numUndir >> numDir;

    numState = 2 * numUndir + numDir;
    FOR(i, 1, numNode) {
        G[i].clear();
        revG[i].clear();
    }

    FOR(i, 1, numUndir) {
        int u, v;
        cin >> u >> v;
        G[u].pb(mp(v, i + numDir));
        G[v].pb(mp(u, i + numDir));
        edge[i + numDir] = mp(u, v);
        edge[i + numUndir + numDir] = mp(v, u);
    }
    FOR(i, 1, numDir) {
        int u, v;
        cin >> u >> v;
        edge[i] = mp(u, v);
        G[u].pb(mp(v, i));
        revG[v].pb(u);
    }
}

namespace Subtask123 {
    bool check() {
        return max({numNode, numDir, numUndir}) <= 1000;
    }

    int dist[N], countState[N];
    vector<int> adj[N];

    int fordBellman() {
        queue<int> q;
        FOR(i, 1, numState) {
            countState[i] = 0;
            dist[i] = -1;
            q.push(i);
        }

        while(!q.empty()) {
            int state = q.front(); q.pop();
            if (++countState[state] > numState) return -1;
            for(int nxt : adj[state])
                if (minimize(dist[nxt], dist[state] - 1))
                    q.push(nxt);
        }

        return -(*min_element(dist + 1, dist + numState + 1));
    }

    void solve() {
        FOR(i, 1, numState) adj[i].clear();
        FOR(i, 1, numState) FOR(j, 1, numState) if (edge[i].se == edge[j].fi) {
            if (i > numDir && j > numDir && abs(i - j) == numUndir) continue;
            adj[i].pb(j);
        }

        cout << fordBellman() << '\n';
    }
}

namespace Subtask4 {
    bool check() {
        return numUndir == 0;
    }

    bool haveCycle;
    int color[N];

    void checkCycle(int u) {
        if (haveCycle) return;
        color[u] = 1;
        for(ii e : G[u]) {
            int v = e.fi;
            if (color[v] == 1) {
                haveCycle = true;
                return;
            }
            if (!color[v])
                checkCycle(v);
        }
        color[u] = 2;
    }

    int dist[N];
    int revDFS(int u) {
        if (dist[u] != -1) return dist[u];
        dist[u] = 0;
        for(int v : revG[u]) maximize(dist[u], revDFS(v) + 1);
        return dist[u];
    }

    void solve() {
        FOR(i, 1, numNode) color[i] = 0;
        haveCycle = false;
        FOR(i, 1, numNode) if (!color[i]) {
            checkCycle(i);
        }

        if (haveCycle) {
            cout << "-1\n";
            return;
        }

        FOR(i, 1, numNode) dist[i] = -1;
        int ans = 0;
        FOR(i, 1, numNode) maximize(ans, revDFS(i));
        cout << ans << '\n';
    }
}

namespace Subtask5 {
    bool check() {
        return numDir == 0;
    }

    int lab[N];
    int root(int v) {
        return (lab[v] < 0 ? v : lab[v] = root(lab[v]));
    }

    bool unite(int u, int v) {
        u = root(u); v = root(v);
        if (u == v) return false;
        if (lab[u] > lab[v]) swap(u, v);
        lab[u] += lab[v];
        lab[v] = u;
        return true;
    }

    bool vis[N];
    int top, diameter;
    void dfs(int u, int par, int dist = 0) {
        if (dist > diameter) diameter = dist, top = u;
        vis[u] = true;
        for(ii e : G[u]) {
            int v = e.fi;
            if (v == par) continue;
            dfs(v, u, dist + 1);
        }
    }

    void solve() {
        FOR(i, 1, numNode) lab[i] = -1;
        bool haveCycle = false;
        FOR(i, 1, numUndir)
            if (!unite(edge[i].fi, edge[i].se)) haveCycle = true;

        if (haveCycle) {
            cout << "-1\n";
            return;
        }

        FOR(i, 1, numNode) vis[i] = false;
        int ans = 0;
        FOR(i, 1, numNode) if (!vis[i]) {
            diameter = 0;
            dfs(1, -1);
            dfs(top, -1);
            maximize(ans, diameter);
        }
        cout << ans << '\n';
    }
}

void process() {
    if (Subtask123 :: check()) Subtask123 :: solve();
    else if (Subtask4 :: check()) Subtask4 :: solve();
    else if (Subtask5 :: check()) Subtask5 :: solve();
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    if (fopen(task".inp", "r")) {
        freopen(task".inp", "r", stdin);
        freopen(task".out", "w", stdout);
    }
    int tc = 1;
    cin >> tc;
    while(tc--) {
        init();
        process();
    }
    return 0;
}
