//galactic.cpp - 2nd version
//pgmr: T Feil
// EC regional contest 2002

#include <iostream.h>

struct node{
  int val;
  node *next;
};

struct mnode{
  mnode * next;
  node * first;
  int size;
};

mnode *Monarchies;
node *G[27000];
int Component[27000], kount, n, m, k, l, size;

void Add(int d, int x){
  node *N;

  N = new node;
  N->val = x;
  N->next = G[d];
  G[d]=N;
}

void MakeGraph(){
  int A[30][30][30], i, j, h, d, c;

  c=0;
  for(h=0;h<k;h++)
   for(j=0;j<m;j++)
    for(i=0;i<n;i++)
      A[i][j][h]=c++;

  
  for(i=0;i<n*m*k;i++)
      G[i]=NULL;

  for(i=0;i<n;i++)
   for(j=0;j<m;j++)
    for(h=0;h<k;h++)
    {
      d=A[i][j][h];
      if(i>0) Add(d,A[i-1][j][h]);
      if(i<n-1) Add(d,A[i+1][j][h]);
      if(j>0) Add(d,A[i][j-1][h]);
      if(j<m-1) Add(d,A[i][j+1][h]);
      if(h>0) Add(d,A[i][j][h-1]);
      if(h<k-1) Add(d,A[i][j][h+1]);
    }
}

int GetNextComponent(mnode *&M, int &C, node *&N){
  int b;

  N=M->first;
  C++;
  b=N->val;
  Component[b]=b;
  N=N->next;
  while(N != NULL){
    Component[N->val]=b;
    N=N->next;
  }
  N=M->first;
  M=M->next;
  return b;
}

//make all cells connected to a with val b have val c
void MakeAll(int c, int b, int a){
  node * ptr=G[a];
  while(ptr!=NULL){
    if(Component[ptr->val]==b){
      Component[ptr->val]=c;
      MakeAll(c,b,ptr->val);
    }
    ptr=ptr->next;
  }
}

//do DFS thru b's component. joining adjacent monarchies
void JoinEmpire(int b, int &Components, node *N){
  node* ptr = N, *ptr2;
  int c;

  while(ptr != NULL){
    ptr2 = G[ptr->val];
    while(ptr2 != NULL){
      if(Component[ptr2->val] !=-1 && Component[ptr2->val] !=b){
        c = Component[ptr2->val];
        MakeAll(c,b,ptr->val);
        Component[ptr->val]=c;
        b=c;
        Components--;
      }
      ptr2=ptr2->next;
    }
    ptr=ptr->next;
  }
}

int main(){
	int ncases;
	cin >> ncases;
	for(int icase = 1; icase <= ncases; icase++) {
	  int count, i, j, a, b, h, months=0;
	  node * N;
	  mnode *M;
	  int Components;
	  cin>>n>>m>>k>>l;
	  count = size = n*m*k;
	  MakeGraph();

	  //Get monarchies
	  Monarchies = NULL;
	  for(i=0;i<l;i++){
		cin>>a;
		M = new mnode;
		M->size = a;
		M->first = NULL;
		M->next = Monarchies;
		Monarchies = M;
		for(j=0;j<a;j++){
		  cin>>b;
		  N = new node;
		  N->val = b;
		  N->next = M->first;
		  M->first = N;
		}
	  }
	  //process monarchies in reverse order
	  for(i=0;i<size;i++) Component[i]=-1;  
	  Components = 0;
	  months = 0;
	  M = Monarchies;
	  b = GetNextComponent(M,Components,N);
	//for(i=0;i<size;i++) cout<<Component[i];
	//cout<<' '<<Components<<endl;
	  while(M!=NULL){
		b = GetNextComponent(M,Components,N);
	//for(i=0;i<size;i++) cout<<Component[i];
	//cout<<' '<<Components<<endl;
		JoinEmpire(b,Components,N);
	//cout<<   "Joined"<<endl;
	//for(i=0;i<size;i++) cout<<Component[i];
	//cout<<' '<<Components<<endl;
		if(Components>1) months++;
	  }
	  cout<<months<<endl;
	}
	return 0;
}



