#include <bits/stdc++.h>
#define endl '\n'
#pragma GCC optimize("O3", "Ofast", "unroll-loops")
#pragma GCC target("avx2")
const int MAXN = 100000;
const int MAXM = 200000;
const int BLOCK = 140;
struct Item {
int dist;
int node;
};
static int n, m, q, x, y;
static int dp[MAXN + 5], mx[MAXN + 5];
static int head[MAXN + 5], to[MAXM + 5], nxt[MAXM + 5], edgeCnt;
static int rhead[MAXN + 5], rto[MAXM + 5], rnxt[MAXM + 5], redgeCnt;
static int valCnt[MAXN + 5];
static int valDist[MAXN + 5][BLOCK + 5];
static int valNode[MAXN + 5][BLOCK + 5];
static int touched[MAXN + 5];
static Item tmp[MAXN + 5];
static bool used[MAXN + 5], banned[MAXN + 5], canReach[MAXN + 5], vis[MAXN + 5];
inline bool cmpItem(const Item &a, const Item &b)
{
if(a.dist != b.dist) return a.dist > b.dist;
return a.node > b.node;
}
inline void addEdge(int u, int v)
{
to[++edgeCnt] = v;
nxt[edgeCnt] = head[u];
head[u] = edgeCnt;
rto[++redgeCnt] = u;
rnxt[redgeCnt] = rhead[v];
rhead[v] = redgeCnt;
}
inline void dfss(int node)
{
used[node] = true;
for(int e = head[node]; e; e = nxt[e])
{
int nxtNode = to[e];
if(!used[nxtNode]) dfss(nxtNode);
if(canReach[nxtNode])
{
canReach[node] = true;
dp[node] = std::max(dp[node], dp[nxtNode] + 1);
}
}
}
inline void solve1()
{
for(int i = 1; i <= n; i++)
{
used[i] = false;
banned[i] = false;
dp[i] = 0;
canReach[i] = false;
}
for(int i = 1; i <= y; i++)
{
int a;
std::cin >> a;
banned[a] = true;
}
canReach[x] = true;
for(int i = 1; i <= n; i++)
{
if(!used[i] && i != x)
{
dfss(i);
}
}
int ans = -1;
for(int i = 1; i <= n; i++)
{
if(canReach[i] && !banned[i])
{
ans = std::max(ans, dp[i]);
}
}
std::cout << ans << endl;
}
inline void dfs(int node)
{
vis[node] = true;
int touchedCnt = 0;
touched[++touchedCnt] = node;
mx[node] = 0;
for(int e = rhead[node]; e; e = rnxt[e])
{
int prev = rto[e];
if(!vis[prev]) dfs(prev);
for(int j = 1; j <= valCnt[prev]; j++)
{
int id = valNode[prev][j];
int dist = valDist[prev][j] + 1;
if(mx[id] == -1)
{
mx[id] = dist;
touched[++touchedCnt] = id;
}
else if(mx[id] < dist)
{
mx[id] = dist;
}
}
}
for(int i = 1; i <= touchedCnt; i++)
{
int id = touched[i];
tmp[i] = {mx[id], id};
mx[id] = -1;
}
std::sort(tmp + 1, tmp + touchedCnt + 1, cmpItem);
valCnt[node] = std::min(BLOCK, touchedCnt);
for(int i = 1; i <= valCnt[node]; i++)
{
valDist[node][i] = tmp[i].dist;
valNode[node][i] = tmp[i].node;
}
}
inline void solve2()
{
for(int i = 1; i <= n; i++)
{
banned[i] = false;
}
for(int i = 1; i <= y; i++)
{
int a;
std::cin >> a;
banned[a] = true;
}
int ptr = 1;
while(ptr <= valCnt[x] && banned[valNode[x][ptr]])
{
ptr++;
}
if(ptr > valCnt[x]) std::cout << -1 << endl;
else std::cout << valDist[x][ptr] << endl;
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin >> n >> m >> q;
for(int i = 1; i <= m; i++)
{
int u, v;
std::cin >> u >> v;
addEdge(u, v);
}
std::memset(mx, -1, sizeof(mx));
for(int i = 1; i <= n; i++)
{
if(!vis[i]) dfs(i);
}
while(q--)
{
std::cin >> x >> y;
if(y >= BLOCK) solve1();
else solve2();
}
return 0;
}