// version1
#include <bits/stdc++.h>
using namespace std;
int n, m, q;
int p1, p2, p3, p4;
vector < pair <int,int> > graph[1000007];
int l;
int pre[1000007];
int low[1000007];
vector <int> vec;
int bic[1000007];
int b;
vector <int> bgraph[1000007];
int bpre[1000007];
int bpost[1000007];
int c;
int conn[1000007];
int dis[1000007];
vector <int> jump[1000007];
vector <int> subset;
vector < pair <int,int> > edges;
int trans[1000007];
vector <int> sta;
vector < pair <int,int> > ngraph[1000007];
int bic2[1000007];
int res;
void dfs1(int v, int p)
{
l++;
pre[v]=l;
low[v]=l;
sta.push_back(v);
for (int i=0; i<graph[v].size(); i++)
{
if (graph[v][i].second==p)
continue;
if (pre[graph[v][i].first])
{
low[v]=min(low[v], pre[graph[v][i].first]);
}
else
{
dfs1(graph[v][i].first, graph[v][i].second);
low[v]=min(low[v], low[graph[v][i].first]);
}
}
if (pre[v]==low[v])
{
b++;
while(sta.back()!=v)
{
bic[sta.back()]=b;
sta.pop_back();
}
bic[sta.back()]=b;
sta.pop_back();
}
}
void dfs2(int v, int p)
{
l++;
bpre[v]=l;
conn[v]=c;
jump[v].push_back(p);
while(jump[v].back())
{
p1=jump[v].size()-1;
p2=jump[v].back();
jump[v].push_back(jump[p2][min(p1, (int)jump[p2].size()-1)]);
}
for (int i=0; i<bgraph[v].size(); i++)
{
if (bgraph[v][i]!=p)
{
dis[bgraph[v][i]]=dis[v]+1;
dfs2(bgraph[v][i], v);
}
}
l++;
bpost[v]=l;
}
int lca(int v, int u)
{
if (conn[v]!=conn[u])
return 0;
for (int i=jump[v].size()-1; i>=0; i--)
{
if (i<jump[v].size() && dis[jump[v][i]]>=dis[u])
{
v=jump[v][i];
}
}
for (int i=jump[u].size()-1; i>=0; i--)
{
if (i<jump[u].size() && dis[jump[u][i]]>=dis[v])
{
u=jump[u][i];
}
}
for (int i=jump[v].size()-1; i>=0; i--)
{
if (i<jump[v].size() && i<jump[u].size() && jump[v][i]!=jump[u][i])
{
v=jump[v][i];
u=jump[u][i];
}
}
if (v!=u)
v=jump[v][0];
return v;
}
bool comp(int v, int u)
{
return bpre[v]<bpre[u];
}
void filtr()
{
vector <int> vec2=vec;
vec.clear();
sort(vec2.begin(), vec2.end(), comp);
for (int i=0; i<vec2.size(); i++)
{
if (!vec2[i])
continue;
if (!i || vec2[i]!=vec2[i-1])
{
vec.push_back(vec2[i]);
}
}
}
void dfs3(int v, int p)
{
l++;
pre[v]=l;
low[v]=l;
sta.push_back(v);
for (int i=0; i<ngraph[v].size(); i++)
{
if (ngraph[v][i].second==p)
continue;
if (pre[ngraph[v][i].first])
{
low[v]=min(low[v], pre[ngraph[v][i].first]);
}
else
{
dfs3(ngraph[v][i].first, ngraph[v][i].second);
low[v]=min(low[v], low[ngraph[v][i].first]);
}
}
if (pre[v]==low[v])
{
b++;
while(sta.back()!=v)
{
bic2[sta.back()]=b;
sta.pop_back();
}
bic2[sta.back()]=b;
sta.pop_back();
}
}
long long R;
int rotate(int element)
{
element=(element+R)%n;
if (element==0)
element=n;
return element;
}
int main()
{
scanf("%d%d%d", &n, &m, &q);
for (int i=1; i<=m; i++)
{
scanf("%d%d", &p1, &p2);
graph[p1].push_back(make_pair(p2, i));
graph[p2].push_back(make_pair(p1, i));
}
for (int i=1; i<=n; i++)
{
if (!pre[i])
{
dfs1(i, 0);
}
}
for (int i=1; i<=n; i++)
{
for (int j=0; j<graph[i].size(); j++)
{
if (bic[i]!=bic[graph[i][j].first])
{
bgraph[bic[i]].push_back(bic[graph[i][j].first]);
}
}
}
l=0;
for (int i=1; i<=b; i++)
{
if (!bpre[i])
{
c++;
dfs2(i, 0);
}
}
for (int h=1; h<=q; h++)
{
subset.clear();
edges.clear();
vec.clear();
scanf("%d%d", &p1, &p2);
while(p1--)
{
scanf("%d", &p3);
p3=rotate(p3);
subset.push_back(bic[p3]);
vec.push_back(bic[p3]);
}
while(p2--)
{
scanf("%d%d", &p3, &p4);
p3=rotate(p3);
p4=rotate(p4);
edges.push_back(make_pair(bic[p3], bic[p4]));
vec.push_back(bic[p3]);
vec.push_back(bic[p4]);
}
sort(vec.begin(), vec.end(), comp);
for (int i=vec.size()-1; i; i--)
{
vec.push_back(lca(vec[i], vec[i-1]));
}
filtr();
c=vec.size();
for (int i=0; i<c; i++)
{
trans[vec[i]]=i+1;
ngraph[i+1].clear();
pre[i+1]=0;
low[i+1]=0;
}
l=0;
sta.clear();
for (int i=0; i<c; i++)
{
while(!sta.empty() && bpost[vec[i]]>bpost[sta.back()])
{
sta.pop_back();
}
if (!sta.empty())
{
l++;
ngraph[trans[vec[i]]].push_back(make_pair(trans[sta.back()], l));
ngraph[trans[sta.back()]].push_back(make_pair(trans[vec[i]], l));
}
sta.push_back(vec[i]);
}
sta.clear();
for (int i=0; i<edges.size(); i++)
{
l++;
ngraph[trans[edges[i].first]].push_back(make_pair(trans[edges[i].second], l));
ngraph[trans[edges[i].second]].push_back(make_pair(trans[edges[i].first], l));
}
b=0;
l=0;
for (int i=1; i<=c; i++)
{
if (!pre[i])
{
dfs3(i, 0);
}
}
res=1;
for (int i=1; i<subset.size(); i++)
{
if (bic2[trans[subset[i]]]!=bic2[trans[subset[0]]])
{
res=0;
}
}
if (res)
{
printf("YES\n");
R+=h;
}
else
{
printf("NO\n");
}
}
return 0;
}
// version2
import java.io.*;
import java.util.*;
public class G_bm_ac {
FastScanner in;
PrintWriter out;
class Solver {
int n;
Solver(int n) {
this.n = n;
par = new int[n];
bl = new int[n];
comp = new int[n];
size = new int[n];
u = new int[n];
init(n);
}
int[] par;
int[] bl;
int[] comp;
int[] size;
void init(int n) {
for (int i = 0; i < n; ++i) {
bl[i] = comp[i] = i;
size[i] = 1;
par[i] = -1;
}
}
int get(int v) {
if (v == -1) {
return -1;
}
return bl[v] == v ? v : (bl[v] = get(bl[v]));
}
int get_comp(int v) {
v = get(v);
return comp[v] == v ? v : (comp[v] = get_comp(comp[v]));
}
void make_root(int v) {
v = get(v);
int root = v, child = -1;
while (v != -1) {
int p = get(par[v]);
par[v] = child;
comp[v] = root;
child = v;
v = p;
}
size[root] = size[child];
}
int cu;
int[] u;
void merge_path(int a, int b) {
++cu;
ArrayList<Integer> va = new ArrayList<>();
ArrayList<Integer> vb = new ArrayList<>();
int lca = -1;
for (;;) {
if (a != -1) {
a = get(a);
va.add(a);
if (u[a] == cu) {
lca = a;
break;
}
u[a] = cu;
a = par[a];
}
if (b != -1) {
b = get(b);
vb.add(b);
if (u[b] == cu) {
lca = b;
break;
}
u[b] = cu;
b = par[b];
}
}
for (int i = 0; i < va.size(); ++i) {
bl[va.get(i)] = lca;
if (va.get(i) == lca)
break;
}
for (int i = 0; i < vb.size(); ++i) {
bl[vb.get(i)] = lca;
if (vb.get(i) == lca)
break;
}
}
void addEdge(int a, int b) {
a = get(a);
b = get(b);
if (a == b)
return;
int ca = get_comp(a), cb = get_comp(b);
if (ca != cb) {
if (size[ca] > size[cb]) {
int tmp = a;
a = b;
b = tmp;
tmp = ca;
ca = cb;
cb = tmp;
}
make_root(a);
par[a] = comp[a] = b;
size[cb] += size[a];
} else {
merge_path(a, b);
}
}
}
int R = 0;
int n;
int rot(int x) {
x = (x + R) % n;
if (x == 0) {
x += n;
}
return x;
}
class Forest {
ArrayList<Integer>[] g;
final int M = 20;
int[][] up;
int n;
boolean[] alive;
int time;
int[] tin, tout;
Solver sol;
Forest(Solver sol) {
this.sol = sol;
this.n = sol.n;
alive = new boolean[n];
g = new ArrayList[n];
for (int i = 0; i < n; i++) {
g[i] = new ArrayList<>();
}
up = new int[M][n];
for (int i = 0; i < n; i++) {
alive[i] = sol.get(i) == i;
}
for (int i = 0; i < n; i++) {
if (alive[i] && sol.par[i] != -1) {
int fr = i;
int to = sol.get(sol.par[i]);
g[fr].add(to);
g[to].add(fr);
}
}
tin = new int[n];
tout = new int[n];
for (int i = 0; i < n; i++) {
if (alive[i] && sol.par[i] == -1) {
go(i, i);
}
}
}
void go(int v, int p) {
tin[v] = time++;
up[0][v] = p;
for (int i = 1; i < M; i++) {
up[i][v] = up[i - 1][up[i - 1][v]];
}
for (int to : g[v]) {
if (to == p) {
continue;
}
go(to, v);
}
tout[v] = time - 1;
}
boolean isAnc(int anc, int v) {
return tin[anc] <= tin[v] && tout[anc] >= tout[v];
}
int lca(int x, int y) {
if (isAnc(x, y)) {
return x;
}
if (up[M - 1][x] != up[M - 1][y]) {
return -1;
}
for (int i = M - 1; i >= 0; i--) {
if (!isAnc(up[i][x], y)) {
x = up[i][x];
}
}
return up[0][x];
}
}
class Vertex {
int oldId, newId;
ArrayList<Vertex> g;
public Vertex(int oldId) {
super();
this.oldId = oldId;
g = new ArrayList<>();
}
@Override
public String toString() {
return "Vertex [oldId=" + oldId + ", newId=" + newId + ", g=" + g
+ "]";
}
}
class Contraction {
ArrayList<Vertex> vertices;
Solver solver;
Forest f;
void addEdge(Vertex v, Vertex u) {
v.g.add(u);
u.g.add(v);
}
public Contraction(final Forest f, ArrayList<Integer> interesting) {
this.f = f;
Collections.sort(interesting, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(f.tin[o1], f.tin[o2]);
}
});
ArrayList<Vertex> stack = new ArrayList<>();
int prevV = -1;
vertices = new ArrayList<>();
for (int v : interesting) {
if (v == prevV) {
continue;
}
prevV = v;
while (stack.size() > 0) {
Vertex last = stack.get(stack.size() - 1);
if (f.isAnc(last.oldId, v)) {
break;
}
int lca = f.lca(last.oldId, v);
if (stack.size() > 1) {
Vertex last2 = stack.get(stack.size() - 2);
if (f.isAnc(last2.oldId, v)) {
if (last2.oldId != lca) {
if (lca == -1) {
throw new AssertionError();
}
System.err.println(lca + "!");
Vertex newV = new Vertex(lca);
vertices.add(newV);
addEdge(last, newV);
stack.remove(stack.size() - 1);
stack.add(newV);
} else {
addEdge(last, last2);
stack.remove(stack.size() - 1);
}
} else {
addEdge(last, last2);
stack.remove(stack.size() - 1);
}
} else {
if (lca != -1) {
Vertex newV = new Vertex(lca);
vertices.add(newV);
addEdge(last, newV);
stack.remove(stack.size() - 1);
stack.add(newV);
} else {
stack.remove(stack.size() - 1);
}
}
}
Vertex newV = new Vertex(v);
stack.add(newV);
vertices.add(newV);
}
while (stack.size() > 1) {
Vertex v1 = stack.get(stack.size() - 1);
Vertex v2 = stack.get(stack.size() - 2);
addEdge(v1, v2);
stack.remove(stack.size() - 1);
}
Collections.sort(vertices, new Comparator<Vertex>() {
@Override
public int compare(Vertex o1, Vertex o2) {
return Integer.compare(o1.oldId, o2.oldId);
}
});
for (int i = 0; i < vertices.size(); i++) {
vertices.get(i).newId = i;
}
solver = new Solver(vertices.size());
for (int i = 0; i < vertices.size(); i++) {
for (Vertex toV : vertices.get(i).g) {
int fr = vertices.get(i).newId;
int to = toV.newId;
if (fr < to) {
solver.addEdge(fr, to);
}
}
}
}
int getNewId(int id) {
int left = 0, right = vertices.size();
while (right - left > 1) {
int mid = (left + right) >> 1;
if (vertices.get(mid).oldId > id) {
right = mid;
} else {
left = mid;
}
}
return left;
}
void addEdge(int fr, int to) {
fr = getNewId(fr);
to = getNewId(to);
solver.addEdge(fr, to);
}
boolean allSame(int[] ids) {
int res = -1;
for (int x : ids) {
int y = getNewId(x);
y = solver.get(y);
if (res != -1 && res != y) {
return false;
}
res = y;
}
return true;
}
}
void solve() {
n = in.nextInt();
int m = in.nextInt();
int q = in.nextInt();
Solver solver = new Solver(n);
for (int i = 0; i < m; i++) {
int fr = in.nextInt() - 1;
int to = in.nextInt() - 1;
solver.addEdge(fr, to);
}
Forest f = new Forest(solver);
for (int i = 0; i < q; i++) {
int ni = in.nextInt();
int mi = in.nextInt();
int[] vertices = new int[ni];
for (int j = 0; j < ni; j++) {
vertices[j] = f.sol.get(rot(in.nextInt()) - 1);
}
int[][] edges = new int[2][mi];
for (int j = 0; j < mi; j++) {
for (int k = 0; k < 2; k++) {
edges[k][j] = f.sol.get(rot(in.nextInt()) - 1);
}
}
ArrayList<Integer> interestingVertices = new ArrayList<>();
for (int v : vertices) {
interestingVertices.add(v);
}
for (int j = 0; j < mi; j++) {
for (int k = 0; k < 2; k++) {
interestingVertices.add(edges[k][j]);
}
}
Contraction contr = new Contraction(f, interestingVertices);
for (int j = 0; j < mi; j++) {
contr.addEdge(edges[0][j], edges[1][j]);
}
boolean ok = contr.allSame(vertices);
out.println(ok ? "YES" : "NO");
R += ok ? (1 + i) : 0;
R %= n;
}
}
void run() {
try {
in = new FastScanner(new File("object.in"));
out = new PrintWriter(new File("object.out"));
solve();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
void runIO() {
in = new FastScanner(System.in);
out = new PrintWriter(System.out);
solve();
out.close();
}
class FastScanner {
BufferedReader br;
StringTokenizer st;
public FastScanner(File f) {
try {
br = new BufferedReader(new FileReader(f));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public FastScanner(InputStream f) {
br = new BufferedReader(new InputStreamReader(f));
}
String next() {
while (st == null || !st.hasMoreTokens()) {
String s = null;
try {
s = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
if (s == null)
return null;
st = new StringTokenizer(s);
}
return st.nextToken();
}
boolean hasMoreTokens() {
while (st == null || !st.hasMoreTokens()) {
String s = null;
try {
s = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
if (s == null)
return false;
st = new StringTokenizer(s);
}
return true;
}
int nextInt() {
return Integer.parseInt(next());
}
long nextLong() {
return Long.parseLong(next());
}
double nextDouble() {
return Double.parseDouble(next());
}
}
public static void main(String[] args) {
new G_bm_ac().runIO();
}
}