Kirill lives on a connected undirected graph of $$$n$$$ vertices and $$$m$$$ edges at vertex $$$1$$$. One fine evening he gathered $$$f$$$ friends, the $$$i$$$-th friend lives at the vertex $$$h_i$$$. So all friends are now in the vertex $$$1$$$, the $$$i$$$-th friend must get to his home to the vertex $$$h_i$$$.The evening is about to end and it is time to leave. It turned out that $$$k$$$ ($$$k \le 6$$$) of his friends have no cars, and they would have to walk if no one gives them a ride. One friend with a car can give a ride to any number of friends without cars, but only if he can give them a ride by driving along one of the shortest paths to his house.For example, in the graph below, a friend from vertex $$$h_i=5$$$ can give a ride to friends from the following sets of vertices: $$$[2, 3]$$$, $$$[2, 4]$$$, $$$[2]$$$, $$$[3]$$$, $$$[4]$$$, but can't give a ride to friend from vertex $$$6$$$ or a set $$$[3, 4]$$$.    The vertices where friends without cars live are highlighted in green, and with cars — in red. Kirill wants as few friends as possible to have to walk. Help him find the minimum possible number.

The first line of input data contains an integer $$$t$$$ ($$$1 \le t \le 10^3$$$) — the number of test cases in the test. The first line of the test case contains two integers $$$n$$$ and $$$m$$$ ($$$2 \le n \le 10^4$$$, $$$n-1 \le m \le min (10^4, $$$$$$ \frac{n \cdot (n - 1)}{2} $$$$$$)$$$) — the number of vertices and edges, respectively. The next $$$m$$$ lines of the test case contain a description of the edges, two integers each $$$u$$$ and $$$v$$$ ($$$1 \le u, v \le n$$$, $$$u \ne v$$$) — indexes of vertices connected by an edge. It is guaranteed that there is at most one edge between any pair of vertices (i.e. no multiple edges in the graph). Then follows line containing the number $$$f$$$ ($$$1 \le f \le 10^4$$$) — the number of Kirill's friends. The next line of the test case contains $$$f$$$ integers: $$$h_1, h_2, \dots, h_f$$$ ($$$2 \le h_i \le n$$$) — the vertices in which they live. Some vertices may be repeated. The next line of the set contains the number $$$k$$$ ($$$1 \le k \le min(6, f)$$$) — the number of friends without cars. The last line of each test case contains $$$k$$$ integers: $$$p_1, p_2, \dots, p_k$$$ ($$$1 \le p_i \le f$$$, $$$p_i < p_{i+1}$$$) — indexes of friends without cars. It is guaranteed that the sum of $$$n$$$ over all cases does not exceed $$$10^4$$$, as well as the sums of $$$m$$$ and $$$f$$$.

Output $$$t$$$ lines, each of which contains the answer to the corresponding test case. As an answer, output a single integer — the minimum possible number of friends who will have to walk.

NoteThe first test case of the first example is explained in the statement.In the second test case of the first example, two friends with cars live at vertex $$$5$$$, one can give a ride to friends from vertices $$$2$$$ and $$$3$$$, and the second from vertex $$$4$$$, only a friend from vertex $$$6$$$ will have to walk.

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"index/suffixarray"
	"log"
	"math"
	"net"
	"os"
	"path"
	"sort"
	"strconv"
	"strings"
	"time"
)

/*
praticamente lui trova per ogni destinazione di una macchina tutti percorsi con le persone che può portare
(ogni percorso è identificato dall'insieme matematico tipo delle persone che porta con sè),
e il numero di questi percorsi è umano, infatti è massimo 2^6.
Poi una volta che hai tutti i possbili percorsi trovi tutte le possbili loro combinazioni tra tutti
 nodi finale macchine (dove puoi prendere massimo 1 percorso per nodo finale macchina) e returni quella migliore
il clou sta nel trovare tutte le combinazioni
che è sto codice qua (guarda soluzione ufficiale dove usa backpack), dove si salva le possibili combiniazioni in backpack,
credo sia questa la parte di programmazione dinamica
e usa il bitwise or dove ogni bit corrisponde ad una persona senza macchina
*/

// For Codeforces
func main() {
	io := newStdIO()
	defer io.Flush()
	for T := io.ScanUInt16(); T > 0; T-- {
		solve(&io)
	}
}
func solve(io *IO) {
	n := io.ScanInt32()
	m := io.ScanInt32()
	adj := make(map[int32]*SingleLinkedList[int32, uint32])
	for i := int32(0); i < n; i++ {
		adj[i] = NewSingleLinkedList[int32, uint32]()
	}
	for i := int32(0); i < m; i++ {
		a := io.ScanInt32() - 1
		b := io.ScanInt32() - 1
		adj[a].InsertLast(b)
		adj[b].InsertLast(a)
	}
	Nfrends := io.ScanInt32()
	friends := make([]int32, Nfrends)
	for i := int32(0); i < Nfrends; i++ {
		tmp := io.ScanInt32() - 1
		friends[i] = tmp
	}
	NfriendsWithoutCar := io.ScanUInt8()
	friendsWithoutCar := make([]int32, NfriendsWithoutCar+1)
	for i := uint8(0); i < NfriendsWithoutCar; i++ {
		tmp := io.ScanInt32() - 1
		friendsWithoutCar[i] = tmp
	}
	friendsWithoutCar[NfriendsWithoutCar] = -1
	dist := make([]int32, n)
	masks := make([]uint8, n)
	for k, _ := range dist {
		dist[k] = -1
	}
	dist[0] = 0
	dfs := NewQueue[int32, uint32]()
	dfs.Enqueue(0)
	for i := uint8(0); i < NfriendsWithoutCar; i++ {
		masks[friends[friendsWithoutCar[i]]] += 1 << i
	}

	path := make([]*Set[uint8], n)
	for i, _ := range path {
		path[i] = NewSet[uint8]()
	}
	path[0].Add(0)
	for dfs.Len() > 0 {
		tmp := dfs.Dequeue()
		next := adj[tmp].ToSlice()
		for i := 0; i < len(next); i++ {
			if dist[next[i]] == -1 {
				dist[next[i]] = dist[tmp] + 1
				dfs.Enqueue(next[i])
			}
			if dist[next[i]] == dist[tmp]+1 {
				tmp2 := path[tmp].ToSlice()
				for _, p := range tmp2 {
					path[next[i]].Add(masks[next[i]] | p)
				}
			}
		}
	}

	dp := make([]bool, 1<<NfriendsWithoutCar)
	j := 0
	dp[0] = true
	dpCopy := make([]bool, len(dp))
	for i := int32(0); i < Nfrends; i++ {
		if i == friendsWithoutCar[j] {
			j++
			continue
		}

		copy(dpCopy, dp)

		for m := uint8(0); m < 1<<NfriendsWithoutCar; m++ {
			if dp[m] {
				paths := path[friends[i]].ToSlice()
				for _, p := range paths {
					dpCopy[p|m] = true
				}
			}
		}
		dp, dpCopy = dpCopy, dp

	}
	min := NfriendsWithoutCar
	for m := uint8(0); m < 1<<NfriendsWithoutCar; m++ {
		if dp[m] {
			c := uint8(0)
			for i := uint8(0); i < NfriendsWithoutCar; i++ {
				if m&(1<<i) == 0 {
					c++
				}
			}
			min = Min(min, c)
		}
	}
	io.PrintLn(min)
}

// #region INTERFACES

// From https://pkg.go.dev/golang.org/x/exp/constraints
type Signed interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64
}
type Unsigned interface {
	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}
type Integer interface {
	Signed | Unsigned
}
type Float interface {
	~float32 | ~float64
}
type Complex interface {
	~complex64 | ~complex128
}
type Ordered interface {
	Integer | Float | ~string
}

type Prioritizable[T any] interface {
	PriorTo(x T) bool // If you take this as a relation: if (a,b) in R => (b,a) not in R
}

// #endregion
// #region TYPES WITH METHODS
// #region SingleLinkedList
type singleLinkedListNode[T comparable] struct {
	Value T
	Next  *singleLinkedListNode[T]
}

type SingleLinkedList[T comparable, IndexType Unsigned] struct {
	first  *singleLinkedListNode[T]
	last   *singleLinkedListNode[T]
	length IndexType
}

func NewSingleLinkedList[T comparable, IndexType Unsigned]() *SingleLinkedList[T, IndexType] {
	return &SingleLinkedList[T, IndexType]{
		first:  nil,
		last:   nil,
		length: 0,
	}
}
func (l *SingleLinkedList[T, I]) Len() I { return l.length }

// length > 0
func (l *SingleLinkedList[T, I]) First() T { return l.first.Value }

// length > 0
func (l *SingleLinkedList[T, I]) Last() T { return l.last.Value }

func (l *SingleLinkedList[T, I]) InsertFirst(value T) {
	if l.length == 0 {
		nodeToInsert := &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
		l.first = nodeToInsert
		l.last = nodeToInsert
	} else {
		l.first = &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
	}
	l.length++
}

func (l *SingleLinkedList[T, I]) InsertLast(value T) {
	if l.length == 0 {
		nodeToInsert := &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
		l.first = nodeToInsert
		l.last = nodeToInsert
	} else {
		l.last.Next = &singleLinkedListNode[T]{
			Value: value,
			Next:  nil,
		}
		l.last = l.last.Next
	}
	l.length++
}

// index <= length
func (l *SingleLinkedList[T, I]) InsertAt(index I, value T) {
	if index == 0 {
		l.InsertFirst(value)
		return
	}
	if index == l.length {
		l.InsertLast(value)
		return
	}

	n := l.first
	for index > 1 {
		n = n.Next
		index--
	}
	n.Next = &singleLinkedListNode[T]{
		Value: value,
		Next:  n.Next,
	}
	l.length++
}

func (l *SingleLinkedList[T, I]) Contains(value T) bool {
	tmp := l.first
	for i := I(0); i < l.length; i++ {
		if tmp.Value == value {
			return true
		}
		tmp = tmp.Next
	}
	return false
}
func (l *SingleLinkedList[T, I]) Clear() {
	l.first = nil
	l.last = nil
	l.length = 0
}

// index < length
func (l *SingleLinkedList[T, I]) GetElementAt(index I) T {
	n := l.first
	for index > 0 {
		n = n.Next
		index--
	}
	return n.Value
}

// index < length
func (l *SingleLinkedList[T, I]) SetElementAt(index I, value T) {
	n := l.first
	for index > 0 {
		n = n.Next
		index--
	}
	n.Value = value
}

func (l *SingleLinkedList[T, I]) RemoveFirst() T {
	tmp := l.first
	l.first = l.first.Next
	l.length--
	if l.length == 0 {
		l.last = nil
	}
	return tmp.Value
}
func (l *SingleLinkedList[T, I]) RemoveLast() (value T) {
	value = l.last.Value
	if l.length == 1 {
		l.first = nil
		l.last = nil
		l.length = 0
		return
	}

	tmp := l.first
	for i := I(2); i < l.length; i++ {
		tmp = tmp.Next
	}
	l.last = tmp
	return
}

func (l *SingleLinkedList[T, I]) RemoveAt(index I) T {
	if index == 0 {
		return l.RemoveFirst()
	}
	if index == l.length-1 {
		return l.RemoveLast()
	}

	tmp := l.first
	for i := I(1); i < index; i++ {
		tmp = tmp.Next
	}
	res := tmp.Next.Value
	tmp.Next = tmp.Next.Next
	return res
}

func (l *SingleLinkedList[T, I]) ToSlice() (res []T) {
	res = make([]T, 0, l.length)
	tmp := l.first
	for i := I(0); i < l.length; i++ {
		res = append(res, tmp.Value)
		tmp = tmp.Next
	}
	return
}
func (it *SingleLinkedList[T, I]) String() string {
	return "Qua:: " + fmt.Sprint(it.ToSlice())
}

// #endregion
// #region Queue

type Queue[T comparable, I Unsigned] struct {
	l SingleLinkedList[T, I]
}

func NewQueue[T comparable, I Unsigned]() *Queue[T, I] {
	return &Queue[T, I]{
		l: SingleLinkedList[T, I]{
			first:  nil,
			last:   nil,
			length: 0,
		},
	}
}
func (q *Queue[T, I]) Len() I          { return q.l.length }
func (q *Queue[T, I]) Enqueue(value T) { q.l.InsertLast(value) }
func (q *Queue[T, I]) Dequeue() T      { return q.l.RemoveFirst() }
func (q *Queue[T, I]) Preview() T      { return q.l.First() }
func (q *Queue[T, I]) String() string  { return q.l.String() }

// #endregion
// #region Stack

type Stack[T comparable, I Unsigned] struct {
	l SingleLinkedList[T, I]
}

func NewStack[T comparable, I Unsigned]() *Stack[T, I] {
	return &Stack[T, I]{
		l: SingleLinkedList[T, I]{
			first:  nil,
			last:   nil,
			length: 0,
		},
	}
}
func (s *Stack[T, I]) Len() I         { return s.l.length }
func (s *Stack[T, I]) Push(value T)   { s.l.InsertFirst(value) }
func (s *Stack[T, I]) Pop() T         { return s.l.RemoveFirst() }
func (s *Stack[T, I]) Preview() T     { return s.l.First() }
func (s *Stack[T, I]) String() string { return s.l.String() }

// #endregion

// #endregion
// #region Heap
type BinaryHeap[T Prioritizable[T], I Signed] struct {
	s []T
}

func NewBinaryHeap[T Prioritizable[T], I Signed](s []T) (h *BinaryHeap[T, I]) {
	h = &BinaryHeap[T, I]{
		s: s,
	}

	for i := (h.Len() - 2) / 2; i >= 0; i-- {
		h.heapifyDown(i)
	}
	return
}
func (h *BinaryHeap[T, I]) Len() I {
	return I(len(h.s))
}
func (h *BinaryHeap[T, I]) Push(value T) {
	h.s = append(h.s, value)
	h.heapifyUp(h.Len() - 1)
}
func (h *BinaryHeap[T, I]) Pop() (res T) {
	res = h.s[0]
	h.s[0] = h.s[h.Len()-1]
	h.s = h.s[:h.Len()-1]
	h.heapifyDown(0)
	return
}

func (h *BinaryHeap[T, I]) heapifyDown(index I) bool {
	origin := index
	for {
		j := index*2 + 2
		if j < h.Len() {
			if h.s[j-1].PriorTo(h.s[j]) {
				j--
			}
		} else {
			if j <= h.Len() && !h.s[j].PriorTo(h.s[index]) {
				h.s[j], h.s[index] = h.s[index], h.s[j]
			}
			break
		}
		if h.s[j].PriorTo(h.s[index]) {
			h.s[j], h.s[index] = h.s[index], h.s[j]
			index = j
		} else {
			break
		}
	}
	return origin != index
}
func (h *BinaryHeap[T, I]) heapifyUp(index I) {
	for {
		parent := (index - 1) / 2
		if parent == index || h.s[parent].PriorTo(h.s[index]) {
			break
		}
		h.s[index], h.s[parent] = h.s[parent], h.s[index]
		index = parent
	}
}

// #endregion
// #region Set
type Set[T comparable] struct {
	l SingleLinkedList[T, uint64]
}

func NewSet[T comparable]() *Set[T] {
	return &Set[T]{l: *NewSingleLinkedList[T, uint64]()}
}
func (s *Set[T]) Add(element T) (added bool) {
	if !s.l.Contains(element) {
		s.l.InsertLast(element)
		return true
	} else {
		return false
	}
}
func (s *Set[T]) ToSlice() (res []T) {
	return s.l.ToSlice()
}
func (s *Set[T]) String() (res []T) {
	return s.l.ToSlice()
}

// #endregion

// #region FUNCTIONS
func Max[T Ordered](a, b T) T {
	if a >= b {
		return a
	}
	return b
}
func Min[T Ordered](a, b T) T {
	if a <= b {
		return a
	}
	return b
}
func Abs[T Integer | Float](a T) T {
	if a < 0 {
		return -a
	}
	return a
}
func Swap[T any](a, b *T) {
	*a, *b = *b, *a
}

// At least one != 0
func GCD[T Unsigned](a, b T) T {
	if b < a {
		Swap(&a, &b)
	}
	for {
		if a == 0 {
			return b
		}
		r := (b % a)
		b = a
		a = r
	}
}

// At least one != 0
func LCM[T Unsigned](a, b T) T {
	return (a * b) / GCD(a, b)
}

func First[T any](a T, _ any) T { return a }

// #endregion

// #region IO STUFF
type IO struct {
	r *bufio.Reader
	w *bufio.Writer
}

func newStdIO() IO {
	return IO{
		r: bufio.NewReader(os.Stdin),
		w: bufio.NewWriter(os.Stdout),
	}
}

// Is assumed that input.txt file exists
func newFileIO() IO {
	return IO{
		r: bufio.NewReader(First(os.Open("input.txt"))),
		w: bufio.NewWriter(First(os.OpenFile("output.txt", os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm))),
	}
}

func (io *IO) ScanInt8() (x int8)   { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt16() (x int16) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt32() (x int32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt64() (x int64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanUInt8() (x uint8)   { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt16() (x uint16) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt32() (x uint32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt64() (x uint64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanFloat32() (x float32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanFloat64() (x float64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanString() (x string) { fmt.Fscan(io.r, &x); return }

func (io *IO) Print(x ...any)   { fmt.Fprint(io.w, x...) }
func (io *IO) PrintLn(x ...any) { fmt.Fprintln(io.w, x...) }

func (io *IO) Flush() { io.w.Flush() }

// #endregion

// #region KEEP IMPORTS
func D() {
	_ = bufio.Reader{}
	_ = bytes.Buffer{}
	_ = suffixarray.Index{}
	_ = log.Default()
	_ = math.Abs(0)
	_ = net.Dialer{}
	_ = path.ErrBadPattern
	_ = sort.Float64sAreSorted(nil)
	_ = strconv.ErrRange
	_ = strings.Builder{}
	_ = time.ANSIC
	_ = newStdIO()
	_ = newFileIO()
}

// #endregion

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"index/suffixarray"
	"log"
	"math"
	"net"
	"os"
	"path"
	"sort"
	"strconv"
	"strings"
	"time"
)

/*
praticamente lui trova per ogni destinazione di una macchina tutti percorsi con le persone che può portare
(ogni percorso è identificato dall'insieme matematico tipo delle persone che porta con sè),
e il numero di questi percorsi è umano, infatti è massimo 2^6.
Poi una volta che hai tutti i possbili percorsi trovi tutte le possbili loro combinazioni tra tutti
 nodi finale macchine (dove puoi prendere massimo 1 percorso per nodo finale macchina) e returni quella migliore
il clou sta nel trovare tutte le combinazioni
che è sto codice qua (guarda soluzione ufficiale dove usa backpack), dove si salva le possibili combiniazioni in backpack,
credo sia questa la parte di programmazione dinamica
e usa il bitwise or dove ogni bit corrisponde ad una persona senza macchina
*/

// For Codeforces
func main() {
	io := newStdIO()
	defer io.Flush()
	for T := io.ScanUInt16(); T > 0; T-- {
		solve(&io)
	}
}
func solve(io *IO) {
	n := io.ScanInt32()
	m := io.ScanInt32()
	adj := make(map[int32]*SingleLinkedList[int32, uint32])
	for i := int32(0); i < n; i++ {
		adj[i] = NewSingleLinkedList[int32, uint32]()
	}
	for i := int32(0); i < m; i++ {
		a := io.ScanInt32() - 1
		b := io.ScanInt32() - 1
		adj[a].InsertLast(b)
		adj[b].InsertLast(a)
	}
	Nfrends := io.ScanInt32()
	friends := make([]int32, Nfrends)
	for i := int32(0); i < Nfrends; i++ {
		tmp := io.ScanInt32() - 1
		friends[i] = tmp
	}
	NfriendsWithoutCar := io.ScanUInt8()
	friendsWithoutCar := make([]int32, NfriendsWithoutCar+1)
	for i := uint8(0); i < NfriendsWithoutCar; i++ {
		tmp := io.ScanInt32() - 1
		friendsWithoutCar[i] = tmp
	}
	friendsWithoutCar[NfriendsWithoutCar] = -1
	dist := make([]int32, n)
	masks := make([]uint8, n)
	for k, _ := range dist {
		dist[k] = -1
	}
	dist[0] = 0
	dfs := NewQueue[int32, uint32]()
	dfs.Enqueue(0)
	for i := uint8(0); i < NfriendsWithoutCar; i++ {
		masks[friends[friendsWithoutCar[i]]] += 1 << i
	}

	path := make([]*Set[uint8], n)
	for i, _ := range path {
		path[i] = NewSet[uint8]()
	}
	path[0].Add(0)
	for dfs.Len() > 0 {
		tmp := dfs.Dequeue()
		next := adj[tmp].ToSlice()
		for i := 0; i < len(next); i++ {
			if dist[next[i]] == -1 {
				dist[next[i]] = dist[tmp] + 1
				dfs.Enqueue(next[i])
			}
			if dist[next[i]] == dist[tmp]+1 {
				tmp2 := path[tmp].ToSlice()
				for _, p := range tmp2 {
					path[next[i]].Add(masks[next[i]] | p)
				}
			}
		}
	}

	dp := make([]bool, 1<<NfriendsWithoutCar)
	j := 0
	dp[0] = true

	for i := int32(0); i < Nfrends; i++ {
		if i == friendsWithoutCar[j] {
			j++
			continue
		}
		dpCopy := make([]bool, len(dp))
		copy(dpCopy, dp)

		for m := uint8(0); m < 1<<NfriendsWithoutCar; m++ {
			if dp[m] {
				paths := path[friends[i]].ToSlice()
				for _, p := range paths {
					dpCopy[p|m] = true
				}
			}
		}
		dp = dpCopy

	}
	min := NfriendsWithoutCar
	for m := uint8(0); m < 1<<NfriendsWithoutCar; m++ {
		if dp[m] {
			c := uint8(0)
			for i := uint8(0); i < NfriendsWithoutCar; i++ {
				if m&(1<<i) == 0 {
					c++
				}
			}
			min = Min(min, c)
		}
	}
	io.PrintLn(min)
}

// #region INTERFACES

// From https://pkg.go.dev/golang.org/x/exp/constraints
type Signed interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64
}
type Unsigned interface {
	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}
type Integer interface {
	Signed | Unsigned
}
type Float interface {
	~float32 | ~float64
}
type Complex interface {
	~complex64 | ~complex128
}
type Ordered interface {
	Integer | Float | ~string
}

type Prioritizable[T any] interface {
	PriorTo(x T) bool // If you take this as a relation: if (a,b) in R => (b,a) not in R
}

// #endregion
// #region TYPES WITH METHODS
// #region SingleLinkedList
type singleLinkedListNode[T comparable] struct {
	Value T
	Next  *singleLinkedListNode[T]
}

type SingleLinkedList[T comparable, IndexType Unsigned] struct {
	first  *singleLinkedListNode[T]
	last   *singleLinkedListNode[T]
	length IndexType
}

func NewSingleLinkedList[T comparable, IndexType Unsigned]() *SingleLinkedList[T, IndexType] {
	return &SingleLinkedList[T, IndexType]{
		first:  nil,
		last:   nil,
		length: 0,
	}
}
func (l *SingleLinkedList[T, I]) Len() I { return l.length }

// length > 0
func (l *SingleLinkedList[T, I]) First() T { return l.first.Value }

// length > 0
func (l *SingleLinkedList[T, I]) Last() T { return l.last.Value }

func (l *SingleLinkedList[T, I]) InsertFirst(value T) {
	if l.length == 0 {
		nodeToInsert := &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
		l.first = nodeToInsert
		l.last = nodeToInsert
	} else {
		l.first = &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
	}
	l.length++
}

func (l *SingleLinkedList[T, I]) InsertLast(value T) {
	if l.length == 0 {
		nodeToInsert := &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
		l.first = nodeToInsert
		l.last = nodeToInsert
	} else {
		l.last.Next = &singleLinkedListNode[T]{
			Value: value,
			Next:  nil,
		}
		l.last = l.last.Next
	}
	l.length++
}

// index <= length
func (l *SingleLinkedList[T, I]) InsertAt(index I, value T) {
	if index == 0 {
		l.InsertFirst(value)
		return
	}
	if index == l.length {
		l.InsertLast(value)
		return
	}

	n := l.first
	for index > 1 {
		n = n.Next
		index--
	}
	n.Next = &singleLinkedListNode[T]{
		Value: value,
		Next:  n.Next,
	}
	l.length++
}

func (l *SingleLinkedList[T, I]) Contains(value T) bool {
	tmp := l.first
	for i := I(0); i < l.length; i++ {
		if tmp.Value == value {
			return true
		}
		tmp = tmp.Next
	}
	return false
}
func (l *SingleLinkedList[T, I]) Clear() {
	l.first = nil
	l.last = nil
	l.length = 0
}

// index < length
func (l *SingleLinkedList[T, I]) GetElementAt(index I) T {
	n := l.first
	for index > 0 {
		n = n.Next
		index--
	}
	return n.Value
}

// index < length
func (l *SingleLinkedList[T, I]) SetElementAt(index I, value T) {
	n := l.first
	for index > 0 {
		n = n.Next
		index--
	}
	n.Value = value
}

func (l *SingleLinkedList[T, I]) RemoveFirst() T {
	tmp := l.first
	l.first = l.first.Next
	l.length--
	if l.length == 0 {
		l.last = nil
	}
	return tmp.Value
}
func (l *SingleLinkedList[T, I]) RemoveLast() (value T) {
	value = l.last.Value
	if l.length == 1 {
		l.first = nil
		l.last = nil
		l.length = 0
		return
	}

	tmp := l.first
	for i := I(2); i < l.length; i++ {
		tmp = tmp.Next
	}
	l.last = tmp
	return
}

func (l *SingleLinkedList[T, I]) RemoveAt(index I) T {
	if index == 0 {
		return l.RemoveFirst()
	}
	if index == l.length-1 {
		return l.RemoveLast()
	}

	tmp := l.first
	for i := I(1); i < index; i++ {
		tmp = tmp.Next
	}
	res := tmp.Next.Value
	tmp.Next = tmp.Next.Next
	return res
}

func (l *SingleLinkedList[T, I]) ToSlice() (res []T) {
	res = make([]T, 0, l.length)
	tmp := l.first
	for i := I(0); i < l.length; i++ {
		res = append(res, tmp.Value)
		tmp = tmp.Next
	}
	return
}
func (it *SingleLinkedList[T, I]) String() string {
	return "Qua:: " + fmt.Sprint(it.ToSlice())
}

// #endregion
// #region Queue

type Queue[T comparable, I Unsigned] struct {
	l SingleLinkedList[T, I]
}

func NewQueue[T comparable, I Unsigned]() *Queue[T, I] {
	return &Queue[T, I]{
		l: SingleLinkedList[T, I]{
			first:  nil,
			last:   nil,
			length: 0,
		},
	}
}
func (q *Queue[T, I]) Len() I          { return q.l.length }
func (q *Queue[T, I]) Enqueue(value T) { q.l.InsertLast(value) }
func (q *Queue[T, I]) Dequeue() T      { return q.l.RemoveFirst() }
func (q *Queue[T, I]) Preview() T      { return q.l.First() }
func (q *Queue[T, I]) String() string  { return q.l.String() }

// #endregion
// #region Stack

type Stack[T comparable, I Unsigned] struct {
	l SingleLinkedList[T, I]
}

func NewStack[T comparable, I Unsigned]() *Stack[T, I] {
	return &Stack[T, I]{
		l: SingleLinkedList[T, I]{
			first:  nil,
			last:   nil,
			length: 0,
		},
	}
}
func (s *Stack[T, I]) Len() I         { return s.l.length }
func (s *Stack[T, I]) Push(value T)   { s.l.InsertFirst(value) }
func (s *Stack[T, I]) Pop() T         { return s.l.RemoveFirst() }
func (s *Stack[T, I]) Preview() T     { return s.l.First() }
func (s *Stack[T, I]) String() string { return s.l.String() }

// #endregion

// #endregion
// #region Heap
type BinaryHeap[T Prioritizable[T], I Signed] struct {
	s []T
}

func NewBinaryHeap[T Prioritizable[T], I Signed](s []T) (h *BinaryHeap[T, I]) {
	h = &BinaryHeap[T, I]{
		s: s,
	}

	for i := (h.Len() - 2) / 2; i >= 0; i-- {
		h.heapifyDown(i)
	}
	return
}
func (h *BinaryHeap[T, I]) Len() I {
	return I(len(h.s))
}
func (h *BinaryHeap[T, I]) Push(value T) {
	h.s = append(h.s, value)
	h.heapifyUp(h.Len() - 1)
}
func (h *BinaryHeap[T, I]) Pop() (res T) {
	res = h.s[0]
	h.s[0] = h.s[h.Len()-1]
	h.s = h.s[:h.Len()-1]
	h.heapifyDown(0)
	return
}

func (h *BinaryHeap[T, I]) heapifyDown(index I) bool {
	origin := index
	for {
		j := index*2 + 2
		if j < h.Len() {
			if h.s[j-1].PriorTo(h.s[j]) {
				j--
			}
		} else {
			if j <= h.Len() && !h.s[j].PriorTo(h.s[index]) {
				h.s[j], h.s[index] = h.s[index], h.s[j]
			}
			break
		}
		if h.s[j].PriorTo(h.s[index]) {
			h.s[j], h.s[index] = h.s[index], h.s[j]
			index = j
		} else {
			break
		}
	}
	return origin != index
}
func (h *BinaryHeap[T, I]) heapifyUp(index I) {
	for {
		parent := (index - 1) / 2
		if parent == index || h.s[parent].PriorTo(h.s[index]) {
			break
		}
		h.s[index], h.s[parent] = h.s[parent], h.s[index]
		index = parent
	}
}

// #endregion
// #region Set
type Set[T comparable] struct {
	l SingleLinkedList[T, uint64]
}

func NewSet[T comparable]() *Set[T] {
	return &Set[T]{l: *NewSingleLinkedList[T, uint64]()}
}
func (s *Set[T]) Add(element T) (added bool) {
	if !s.l.Contains(element) {
		s.l.InsertLast(element)
		return true
	} else {
		return false
	}
}
func (s *Set[T]) ToSlice() (res []T) {
	return s.l.ToSlice()
}
func (s *Set[T]) String() (res []T) {
	return s.l.ToSlice()
}

// #endregion

// #region FUNCTIONS
func Max[T Ordered](a, b T) T {
	if a >= b {
		return a
	}
	return b
}
func Min[T Ordered](a, b T) T {
	if a <= b {
		return a
	}
	return b
}
func Abs[T Integer | Float](a T) T {
	if a < 0 {
		return -a
	}
	return a
}
func Swap[T any](a, b *T) {
	*a, *b = *b, *a
}

// At least one != 0
func GCD[T Unsigned](a, b T) T {
	if b < a {
		Swap(&a, &b)
	}
	for {
		if a == 0 {
			return b
		}
		r := (b % a)
		b = a
		a = r
	}
}

// At least one != 0
func LCM[T Unsigned](a, b T) T {
	return (a * b) / GCD(a, b)
}

func First[T any](a T, _ any) T { return a }

// #endregion

// #region IO STUFF
type IO struct {
	r *bufio.Reader
	w *bufio.Writer
}

func newStdIO() IO {
	return IO{
		r: bufio.NewReader(os.Stdin),
		w: bufio.NewWriter(os.Stdout),
	}
}

// Is assumed that input.txt file exists
func newFileIO() IO {
	return IO{
		r: bufio.NewReader(First(os.Open("input.txt"))),
		w: bufio.NewWriter(First(os.OpenFile("output.txt", os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm))),
	}
}

func (io *IO) ScanInt8() (x int8)   { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt16() (x int16) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt32() (x int32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt64() (x int64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanUInt8() (x uint8)   { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt16() (x uint16) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt32() (x uint32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt64() (x uint64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanFloat32() (x float32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanFloat64() (x float64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanString() (x string) { fmt.Fscan(io.r, &x); return }

func (io *IO) Print(x ...any)   { fmt.Fprint(io.w, x...) }
func (io *IO) PrintLn(x ...any) { fmt.Fprintln(io.w, x...) }

func (io *IO) Flush() { io.w.Flush() }

// #endregion

// #region KEEP IMPORTS
func D() {
	_ = bufio.Reader{}
	_ = bytes.Buffer{}
	_ = suffixarray.Index{}
	_ = log.Default()
	_ = math.Abs(0)
	_ = net.Dialer{}
	_ = path.ErrBadPattern
	_ = sort.Float64sAreSorted(nil)
	_ = strconv.ErrRange
	_ = strings.Builder{}
	_ = time.ANSIC
	_ = newStdIO()
	_ = newFileIO()
}

// #endregion

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"index/suffixarray"
	"log"
	"math"
	"net"
	"os"
	"path"
	"sort"
	"strconv"
	"strings"
	"time"
)

/*
praticamente lui trova per ogni destinazione di una macchina tutti percorsi con le persone che può portare
(ogni percorso è identificato dall'insieme matematico tipo delle persone che porta con sè),
e il numero di questi percorsi è umano, infatti è massimo 2^6.
Poi una volta che hai tutti i possbili percorsi trovi tutte le possbili loro combinazioni tra tutti
 nodi finale macchine (dove puoi prendere massimo 1 percorso per nodo finale macchina) e returni quella migliore
il clou sta nel trovare tutte le combinazioni
che è sto codice qua (guarda soluzione ufficiale dove usa backpack), dove si salva le possibili combiniazioni in backpack,
credo sia questa la parte di programmazione dinamica
e usa il bitwise or dove ogni bit corrisponde ad una persona senza macchina
*/

// For Codeforces
func main() {
	io := newStdIO()
	defer io.Flush()
	for T := io.ScanUInt16(); T > 0; T-- {
		solve(&io)
	}
}
func solve(io *IO) {
	n := io.ScanInt32()
	m := io.ScanInt32()
	adj := make(map[int32]*SingleLinkedList[int32, uint32])
	for i := int32(0); i < n; i++ {
		adj[i] = NewSingleLinkedList[int32, uint32]()
	}
	for i := int32(0); i < m; i++ {
		a := io.ScanInt32() - 1
		b := io.ScanInt32() - 1
		adj[a].InsertLast(b)
		adj[b].InsertLast(a)
	}
	Nfrends := io.ScanInt32()
	friends := make([]int32, Nfrends)
	for i := int32(0); i < Nfrends; i++ {
		tmp := io.ScanInt32() - 1
		friends[i] = tmp
	}
	NfriendsWithoutCar := io.ScanUInt8()
	friendsWithoutCar := make([]int32, NfriendsWithoutCar+1)
	for i := uint8(0); i < NfriendsWithoutCar; i++ {
		tmp := io.ScanInt32() - 1
		friendsWithoutCar[i] = tmp
	}
	friendsWithoutCar[NfriendsWithoutCar] = -1
	dist := make([]int32, n)
	masks := make([]uint8, n)
	for k, _ := range dist {
		dist[k] = -1
	}
	dist[0] = 0
	dfs := NewQueue[int32, uint32]()
	dfs.Enqueue(0)
	for i := uint8(0); i < NfriendsWithoutCar; i++ {
		masks[friends[friendsWithoutCar[i]]] += 1 << i
	}

	path := make([]*Set[uint8], n)
	for i, _ := range path {
		path[i] = NewSet[uint8]()
	}
	path[0].Add(masks[0])
	for dfs.Len() > 0 {
		tmp := dfs.Dequeue()
		next := adj[tmp].ToSlice()
		for i := 0; i < len(next); i++ {
			if dist[next[i]] == -1 {
				dist[next[i]] = dist[tmp] + 1
				dfs.Enqueue(next[i])
			}
			if dist[next[i]] == dist[tmp]+1 {
				tmp2 := path[tmp].ToSlice()
				for _, p := range tmp2 {
					path[next[i]].Add(masks[next[i]] | p)
				}
			}
		}
	}

	dp := make([]bool, 1<<NfriendsWithoutCar)
	j := 0
	dp[0] = true

	for i := int32(0); i < Nfrends; i++ {
		if i == friendsWithoutCar[j] {
			j++
			continue
		}
		dpCopy := make([]bool, len(dp))
		copy(dpCopy, dp)

		for m := uint8(0); m < 1<<NfriendsWithoutCar; m++ {
			if dp[m] {
				paths := path[friends[i]].ToSlice()
				for _, p := range paths {
					dpCopy[p|m] = true
				}
			}
		}
		dp = dpCopy

	}
	min := NfriendsWithoutCar
	for m := uint8(0); m < 1<<NfriendsWithoutCar; m++ {
		if dp[m] {
			c := uint8(0)
			for i := uint8(0); i < NfriendsWithoutCar; i++ {
				if m&(1<<i) == 0 {
					c++
				}
			}
			min = Min(min, c)
		}
	}
	io.PrintLn(min)
}

// #region INTERFACES

// From https://pkg.go.dev/golang.org/x/exp/constraints
type Signed interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64
}
type Unsigned interface {
	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}
type Integer interface {
	Signed | Unsigned
}
type Float interface {
	~float32 | ~float64
}
type Complex interface {
	~complex64 | ~complex128
}
type Ordered interface {
	Integer | Float | ~string
}

type Prioritizable[T any] interface {
	PriorTo(x T) bool // If you take this as a relation: if (a,b) in R => (b,a) not in R
}

// #endregion
// #region TYPES WITH METHODS
// #region SingleLinkedList
type singleLinkedListNode[T comparable] struct {
	Value T
	Next  *singleLinkedListNode[T]
}

type SingleLinkedList[T comparable, IndexType Unsigned] struct {
	first  *singleLinkedListNode[T]
	last   *singleLinkedListNode[T]
	length IndexType
}

func NewSingleLinkedList[T comparable, IndexType Unsigned]() *SingleLinkedList[T, IndexType] {
	return &SingleLinkedList[T, IndexType]{
		first:  nil,
		last:   nil,
		length: 0,
	}
}
func (l *SingleLinkedList[T, I]) Len() I { return l.length }

// length > 0
func (l *SingleLinkedList[T, I]) First() T { return l.first.Value }

// length > 0
func (l *SingleLinkedList[T, I]) Last() T { return l.last.Value }

func (l *SingleLinkedList[T, I]) InsertFirst(value T) {
	if l.length == 0 {
		nodeToInsert := &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
		l.first = nodeToInsert
		l.last = nodeToInsert
	} else {
		l.first = &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
	}
	l.length++
}

func (l *SingleLinkedList[T, I]) InsertLast(value T) {
	if l.length == 0 {
		nodeToInsert := &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
		l.first = nodeToInsert
		l.last = nodeToInsert
	} else {
		l.last.Next = &singleLinkedListNode[T]{
			Value: value,
			Next:  nil,
		}
		l.last = l.last.Next
	}
	l.length++
}

// index <= length
func (l *SingleLinkedList[T, I]) InsertAt(index I, value T) {
	if index == 0 {
		l.InsertFirst(value)
		return
	}
	if index == l.length {
		l.InsertLast(value)
		return
	}

	n := l.first
	for index > 1 {
		n = n.Next
		index--
	}
	n.Next = &singleLinkedListNode[T]{
		Value: value,
		Next:  n.Next,
	}
	l.length++
}

func (l *SingleLinkedList[T, I]) Contains(value T) bool {
	tmp := l.first
	for i := I(0); i < l.length; i++ {
		if tmp.Value == value {
			return true
		}
		tmp = tmp.Next
	}
	return false
}
func (l *SingleLinkedList[T, I]) Clear() {
	l.first = nil
	l.last = nil
	l.length = 0
}

// index < length
func (l *SingleLinkedList[T, I]) GetElementAt(index I) T {
	n := l.first
	for index > 0 {
		n = n.Next
		index--
	}
	return n.Value
}

// index < length
func (l *SingleLinkedList[T, I]) SetElementAt(index I, value T) {
	n := l.first
	for index > 0 {
		n = n.Next
		index--
	}
	n.Value = value
}

func (l *SingleLinkedList[T, I]) RemoveFirst() T {
	tmp := l.first
	l.first = l.first.Next
	l.length--
	if l.length == 0 {
		l.last = nil
	}
	return tmp.Value
}
func (l *SingleLinkedList[T, I]) RemoveLast() (value T) {
	value = l.last.Value
	if l.length == 1 {
		l.first = nil
		l.last = nil
		l.length = 0
		return
	}

	tmp := l.first
	for i := I(2); i < l.length; i++ {
		tmp = tmp.Next
	}
	l.last = tmp
	return
}

func (l *SingleLinkedList[T, I]) RemoveAt(index I) T {
	if index == 0 {
		return l.RemoveFirst()
	}
	if index == l.length-1 {
		return l.RemoveLast()
	}

	tmp := l.first
	for i := I(1); i < index; i++ {
		tmp = tmp.Next
	}
	res := tmp.Next.Value
	tmp.Next = tmp.Next.Next
	return res
}

func (l *SingleLinkedList[T, I]) ToSlice() (res []T) {
	res = make([]T, 0, l.length)
	tmp := l.first
	for i := I(0); i < l.length; i++ {
		res = append(res, tmp.Value)
		tmp = tmp.Next
	}
	return
}
func (it *SingleLinkedList[T, I]) String() string {
	return "Qua:: " + fmt.Sprint(it.ToSlice())
}

// #endregion
// #region Queue

type Queue[T comparable, I Unsigned] struct {
	l SingleLinkedList[T, I]
}

func NewQueue[T comparable, I Unsigned]() *Queue[T, I] {
	return &Queue[T, I]{
		l: SingleLinkedList[T, I]{
			first:  nil,
			last:   nil,
			length: 0,
		},
	}
}
func (q *Queue[T, I]) Len() I          { return q.l.length }
func (q *Queue[T, I]) Enqueue(value T) { q.l.InsertLast(value) }
func (q *Queue[T, I]) Dequeue() T      { return q.l.RemoveFirst() }
func (q *Queue[T, I]) Preview() T      { return q.l.First() }
func (q *Queue[T, I]) String() string  { return q.l.String() }

// #endregion
// #region Stack

type Stack[T comparable, I Unsigned] struct {
	l SingleLinkedList[T, I]
}

func NewStack[T comparable, I Unsigned]() *Stack[T, I] {
	return &Stack[T, I]{
		l: SingleLinkedList[T, I]{
			first:  nil,
			last:   nil,
			length: 0,
		},
	}
}
func (s *Stack[T, I]) Len() I         { return s.l.length }
func (s *Stack[T, I]) Push(value T)   { s.l.InsertFirst(value) }
func (s *Stack[T, I]) Pop() T         { return s.l.RemoveFirst() }
func (s *Stack[T, I]) Preview() T     { return s.l.First() }
func (s *Stack[T, I]) String() string { return s.l.String() }

// #endregion

// #endregion
// #region Heap
type BinaryHeap[T Prioritizable[T], I Signed] struct {
	s []T
}

func NewBinaryHeap[T Prioritizable[T], I Signed](s []T) (h *BinaryHeap[T, I]) {
	h = &BinaryHeap[T, I]{
		s: s,
	}

	for i := (h.Len() - 2) / 2; i >= 0; i-- {
		h.heapifyDown(i)
	}
	return
}
func (h *BinaryHeap[T, I]) Len() I {
	return I(len(h.s))
}
func (h *BinaryHeap[T, I]) Push(value T) {
	h.s = append(h.s, value)
	h.heapifyUp(h.Len() - 1)
}
func (h *BinaryHeap[T, I]) Pop() (res T) {
	res = h.s[0]
	h.s[0] = h.s[h.Len()-1]
	h.s = h.s[:h.Len()-1]
	h.heapifyDown(0)
	return
}

func (h *BinaryHeap[T, I]) heapifyDown(index I) bool {
	origin := index
	for {
		j := index*2 + 2
		if j < h.Len() {
			if h.s[j-1].PriorTo(h.s[j]) {
				j--
			}
		} else {
			if j <= h.Len() && !h.s[j].PriorTo(h.s[index]) {
				h.s[j], h.s[index] = h.s[index], h.s[j]
			}
			break
		}
		if h.s[j].PriorTo(h.s[index]) {
			h.s[j], h.s[index] = h.s[index], h.s[j]
			index = j
		} else {
			break
		}
	}
	return origin != index
}
func (h *BinaryHeap[T, I]) heapifyUp(index I) {
	for {
		parent := (index - 1) / 2
		if parent == index || h.s[parent].PriorTo(h.s[index]) {
			break
		}
		h.s[index], h.s[parent] = h.s[parent], h.s[index]
		index = parent
	}
}

// #endregion
// #region Set
type Set[T comparable] struct {
	l SingleLinkedList[T, uint64]
}

func NewSet[T comparable]() *Set[T] {
	return &Set[T]{l: *NewSingleLinkedList[T, uint64]()}
}
func (s *Set[T]) Add(element T) (added bool) {
	if !s.l.Contains(element) {
		s.l.InsertLast(element)
		return true
	} else {
		return false
	}
}
func (s *Set[T]) ToSlice() (res []T) {
	return s.l.ToSlice()
}
func (s *Set[T]) String() (res []T) {
	return s.l.ToSlice()
}

// #endregion

// #region FUNCTIONS
func Max[T Ordered](a, b T) T {
	if a >= b {
		return a
	}
	return b
}
func Min[T Ordered](a, b T) T {
	if a <= b {
		return a
	}
	return b
}
func Abs[T Integer | Float](a T) T {
	if a < 0 {
		return -a
	}
	return a
}
func Swap[T any](a, b *T) {
	*a, *b = *b, *a
}

// At least one != 0
func GCD[T Unsigned](a, b T) T {
	if b < a {
		Swap(&a, &b)
	}
	for {
		if a == 0 {
			return b
		}
		r := (b % a)
		b = a
		a = r
	}
}

// At least one != 0
func LCM[T Unsigned](a, b T) T {
	return (a * b) / GCD(a, b)
}

func First[T any](a T, _ any) T { return a }

// #endregion

// #region IO STUFF
type IO struct {
	r *bufio.Reader
	w *bufio.Writer
}

func newStdIO() IO {
	return IO{
		r: bufio.NewReader(os.Stdin),
		w: bufio.NewWriter(os.Stdout),
	}
}

// Is assumed that input.txt file exists
func newFileIO() IO {
	return IO{
		r: bufio.NewReader(First(os.Open("input.txt"))),
		w: bufio.NewWriter(First(os.OpenFile("output.txt", os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm))),
	}
}

func (io *IO) ScanInt8() (x int8)   { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt16() (x int16) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt32() (x int32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt64() (x int64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanUInt8() (x uint8)   { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt16() (x uint16) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt32() (x uint32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt64() (x uint64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanFloat32() (x float32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanFloat64() (x float64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanString() (x string) { fmt.Fscan(io.r, &x); return }

func (io *IO) Print(x ...any)   { fmt.Fprint(io.w, x...) }
func (io *IO) PrintLn(x ...any) { fmt.Fprintln(io.w, x...) }

func (io *IO) Flush() { io.w.Flush() }

// #endregion

// #region KEEP IMPORTS
func D() {
	_ = bufio.Reader{}
	_ = bytes.Buffer{}
	_ = suffixarray.Index{}
	_ = log.Default()
	_ = math.Abs(0)
	_ = net.Dialer{}
	_ = path.ErrBadPattern
	_ = sort.Float64sAreSorted(nil)
	_ = strconv.ErrRange
	_ = strings.Builder{}
	_ = time.ANSIC
	_ = newStdIO()
	_ = newFileIO()
}

// #endregion

package main

import (
	"bufio"
	"fmt"
	"os"
)

func min(a, b int) int {
	if a < b { return a }
	return b
}

type queue struct {
	sl []int
	top_index int
	bottom_index int
}

func (q *queue) pop() int {
	res := q.top()
	q.top_index++
	return res
}

func (q queue) top() int {
	return q.sl[q.top_index]
}

func (q *queue) push(v int) {
	q.bottom_index++
	q.sl[q.bottom_index] = v
}

func (q queue) is_empty() bool {
	return q.top_index > q.bottom_index
}

func main() {
	r := bufio.NewReader(os.Stdin)
	w := bufio.NewWriter(os.Stdout)
	defer w.Flush()

	var T int
	for fmt.Fscan(r, &T); T > 0; T-- {
		var n, m int
		fmt.Fscan(r, &n, &m)
		adj := make([][]int, n)
		mask := make([]int, n)

		for i := 0; i < m; i++ {
			var u, v int
			fmt.Fscan(r, &u, &v)
			u--
			v--
			adj[u] = append(adj[u], v)
			adj[v] = append(adj[v], u)
		}

		var f int
		fmt.Fscan(r, &f)
		house := make([]int, f)
		has_car := make([]bool, f)
		for i := 0; i < f; i++ {
			fmt.Fscan(r, &house[i])
			house[i]--
			has_car[i] = true
		}

		var k int
		fmt.Fscan(r, &k)
		for i := 0; i < k; i++ {
			var p int
			fmt.Fscan(r, &p)
			p--
			mask[house[p]] |= (1 << i)
			has_car[p] = false
		}

		masks := make([][]bool, n)
		for i := range masks {
			masks[i] = make([]bool, 1 << k)
			masks[i][0] = true
		}

		q := queue{make([]int, n+5), 0, -1}
		dist := make([]int, n)
		for i := range dist { dist[i] = -1 }
		q.push(0)
		dist[0] = 0
		for !q.is_empty() {
			u := q.pop()
			for _, v := range(adj[u]) {
				if dist[v] == -1 {
					dist[v] = dist[u] + 1
					q.push(v)
				}
				if dist[v] == dist[u] + 1 {
					for i, b := range masks[u] {
						if b {
							masks[v][i | mask[v]] = true
						}
					}
				}
			}
		}

		backpack := make([]bool, 1<<k)
		backpack[0] = true
		for i := 0; i < f; i++ {
			if !has_car[i] { continue }
			nb := make([]bool, 1<<k)
			copy(nb, backpack)
			for x, xb := range backpack {
				if !xb { continue }
				for y, yb := range masks[house[i]] {
					if yb {
						nb[x | y] = true
					}
				}
			}
			copy(backpack, nb)
		}

		ans := k
		for x, xb := range backpack {
			if xb {
				cnt := 0
				for i := 0; i < k; i++ {
					if x & (1 << i) == 0 { cnt++ }
				}
				ans = min(ans, cnt)
			}
		}

		fmt.Fprintln(w, ans)
	}

}

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"index/suffixarray"
	"log"
	"math"
	"net"
	"os"
	"path"
	"sort"
	"strconv"
	"strings"
	"time"
)

/*
praticamente lui trova per ogni destinazione di una macchina tutti percorsi con le persone che può portare
(ogni percorso è identificato dall'insieme matematico tipo delle persone che porta con sè),
e il numero di questi percorsi è umano, infatti è massimo 2^6.
Poi una volta che hai tutti i possbili percorsi trovi tutte le possbili loro combinazioni tra tutti
 nodi finale macchine (dove puoi prendere massimo 1 percorso per nodo finale macchina) e returni quella migliore
il clou sta nel trovare tutte le combinazioni
che è sto codice qua (guarda soluzione ufficiale dove usa backpack), dove si salva le possibili combiniazioni in backpack,
credo sia questa la parte di programmazione dinamica
e usa il bitwise or dove ogni bit corrisponde ad una persona senza macchina
*/

// For Codeforces
func main() {
	io := newStdIO()
	defer io.Flush()
	for T := io.ScanUInt16(); T > 0; T-- {
		solve(&io)
	}
}
func solve(io *IO) {
	n := io.ScanInt32()
	m := io.ScanInt32()
	adj := make(map[int32]*SingleLinkedList[int32, uint32])
	for i := int32(0); i < n; i++ {
		adj[i] = NewSingleLinkedList[int32, uint32]()
	}
	for i := int32(0); i < m; i++ {
		a := io.ScanInt32() - 1
		b := io.ScanInt32() - 1
		adj[a].InsertLast(b)
		adj[b].InsertLast(a)
	}
	Nfrends := io.ScanInt32()
	friends := make([]int32, Nfrends)
	for i := int32(0); i < Nfrends; i++ {
		tmp := io.ScanInt32() - 1
		friends[i] = tmp
	}
	NfriendsWithoutCar := io.ScanUInt8()
	friendsWithoutCar := make([]int32, NfriendsWithoutCar+1)
	for i := uint8(0); i < NfriendsWithoutCar; i++ {
		tmp := io.ScanInt32() - 1
		friendsWithoutCar[i] = tmp
	}
	friendsWithoutCar[NfriendsWithoutCar] = -1
	dist := make([]int32, n)
	masks := make([]uint8, n)
	for k, _ := range dist {
		dist[k] = -1
	}
	dist[0] = 0
	dfs := NewQueue[int32, uint32]()
	dfs.Enqueue(0)
	for i := uint8(0); i < NfriendsWithoutCar; i++ {
		masks[friends[friendsWithoutCar[i]]] += 1 << i
	}

	path := make([]*Set[uint8], n)
	for i, _ := range path {
		path[i] = NewSet[uint8]()
	}
	path[0].Add(0)
	for dfs.Len() > 0 {
		tmp := dfs.Dequeue()
		next := adj[tmp].ToSlice()
		for i := 0; i < len(next); i++ {
			if dist[next[i]] == -1 {
				dist[next[i]] = dist[tmp] + 1
				dfs.Enqueue(next[i])
			}
			if dist[next[i]] == dist[tmp]+1 {
				dist[next[i]] = dist[tmp] + 1
				tmp2 := path[tmp].ToSlice()
				for _, p := range tmp2 {
					path[next[i]].Add(masks[next[i]] | p)
				}
			}
		}
	}

	dp := make([]bool, 1<<NfriendsWithoutCar)
	j := 0
	dp[0] = true
	dpCopy := make([]bool, len(dp))
	for i := int32(0); i < Nfrends; i++ {
		if i == friendsWithoutCar[j] {
			j++
			continue
		}

		copy(dpCopy, dp)

		for m := uint8(0); m < 1<<NfriendsWithoutCar; m++ {
			if dp[m] {
				paths := path[friends[i]].ToSlice()
				for _, p := range paths {
					dpCopy[p|m] = true
				}
			}
		}
		dp = dpCopy

	}
	min := NfriendsWithoutCar
	for m := uint8(0); m < 1<<NfriendsWithoutCar; m++ {
		c := uint8(0)
		if dp[m] {
			for i := uint8(0); i < NfriendsWithoutCar; i++ {
				if m&(1<<i) == 0 {
					c++
				}
			}
			min = Min(min, c)
		}
	}
	io.PrintLn(min)
}

// #region INTERFACES

// From https://pkg.go.dev/golang.org/x/exp/constraints
type Signed interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64
}
type Unsigned interface {
	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}
type Integer interface {
	Signed | Unsigned
}
type Float interface {
	~float32 | ~float64
}
type Complex interface {
	~complex64 | ~complex128
}
type Ordered interface {
	Integer | Float | ~string
}

type Prioritizable[T any] interface {
	PriorTo(x T) bool // If you take this as a relation: if (a,b) in R => (b,a) not in R
}

// #endregion
// #region TYPES WITH METHODS
// #region SingleLinkedList
type singleLinkedListNode[T comparable] struct {
	Value T
	Next  *singleLinkedListNode[T]
}

type SingleLinkedList[T comparable, IndexType Unsigned] struct {
	first  *singleLinkedListNode[T]
	last   *singleLinkedListNode[T]
	length IndexType
}

func NewSingleLinkedList[T comparable, IndexType Unsigned]() *SingleLinkedList[T, IndexType] {
	return &SingleLinkedList[T, IndexType]{
		first:  nil,
		last:   nil,
		length: 0,
	}
}
func (l *SingleLinkedList[T, I]) Len() I { return l.length }

// length > 0
func (l *SingleLinkedList[T, I]) First() T { return l.first.Value }

// length > 0
func (l *SingleLinkedList[T, I]) Last() T { return l.last.Value }

func (l *SingleLinkedList[T, I]) InsertFirst(value T) {
	if l.length == 0 {
		nodeToInsert := &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
		l.first = nodeToInsert
		l.last = nodeToInsert
	} else {
		l.first = &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
	}
	l.length++
}

func (l *SingleLinkedList[T, I]) InsertLast(value T) {
	if l.length == 0 {
		nodeToInsert := &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
		l.first = nodeToInsert
		l.last = nodeToInsert
	} else {
		l.last.Next = &singleLinkedListNode[T]{
			Value: value,
			Next:  nil,
		}
		l.last = l.last.Next
	}
	l.length++
}

// index <= length
func (l *SingleLinkedList[T, I]) InsertAt(index I, value T) {
	if index == 0 {
		l.InsertFirst(value)
		return
	}
	if index == l.length {
		l.InsertLast(value)
		return
	}

	n := l.first
	for index > 1 {
		n = n.Next
		index--
	}
	n.Next = &singleLinkedListNode[T]{
		Value: value,
		Next:  n.Next,
	}
	l.length++
}

func (l *SingleLinkedList[T, I]) Contains(value T) bool {
	tmp := l.first
	for i := I(0); i < l.length; i++ {
		if tmp.Value == value {
			return true
		}
		tmp = tmp.Next
	}
	return false
}
func (l *SingleLinkedList[T, I]) Clear() {
	l.first = nil
	l.last = nil
	l.length = 0
}

// index < length
func (l *SingleLinkedList[T, I]) GetElementAt(index I) T {
	n := l.first
	for index > 0 {
		n = n.Next
		index--
	}
	return n.Value
}

// index < length
func (l *SingleLinkedList[T, I]) SetElementAt(index I, value T) {
	n := l.first
	for index > 0 {
		n = n.Next
		index--
	}
	n.Value = value
}

func (l *SingleLinkedList[T, I]) RemoveFirst() T {
	tmp := l.first
	l.first = l.first.Next
	l.length--
	if l.length == 0 {
		l.last = nil
	}
	return tmp.Value
}
func (l *SingleLinkedList[T, I]) RemoveLast() (value T) {
	value = l.last.Value
	if l.length == 1 {
		l.first = nil
		l.last = nil
		l.length = 0
		return
	}

	tmp := l.first
	for i := I(2); i < l.length; i++ {
		tmp = tmp.Next
	}
	l.last = tmp
	return
}

func (l *SingleLinkedList[T, I]) RemoveAt(index I) T {
	if index == 0 {
		return l.RemoveFirst()
	}
	if index == l.length-1 {
		return l.RemoveLast()
	}

	tmp := l.first
	for i := I(1); i < index; i++ {
		tmp = tmp.Next
	}
	res := tmp.Next.Value
	tmp.Next = tmp.Next.Next
	return res
}

func (l *SingleLinkedList[T, I]) ToSlice() (res []T) {
	res = make([]T, 0, l.length)
	tmp := l.first
	for i := I(0); i < l.length; i++ {
		res = append(res, tmp.Value)
		tmp = tmp.Next
	}
	return
}
func (it *SingleLinkedList[T, I]) String() string {
	return "Qua:: " + fmt.Sprint(it.ToSlice())
}

// #endregion
// #region Queue

type Queue[T comparable, I Unsigned] struct {
	l SingleLinkedList[T, I]
}

func NewQueue[T comparable, I Unsigned]() *Queue[T, I] {
	return &Queue[T, I]{
		l: SingleLinkedList[T, I]{
			first:  nil,
			last:   nil,
			length: 0,
		},
	}
}
func (q *Queue[T, I]) Len() I          { return q.l.length }
func (q *Queue[T, I]) Enqueue(value T) { q.l.InsertLast(value) }
func (q *Queue[T, I]) Dequeue() T      { return q.l.RemoveFirst() }
func (q *Queue[T, I]) Preview() T      { return q.l.First() }
func (q *Queue[T, I]) String() string  { return q.l.String() }

// #endregion
// #region Stack

type Stack[T comparable, I Unsigned] struct {
	l SingleLinkedList[T, I]
}

func NewStack[T comparable, I Unsigned]() *Stack[T, I] {
	return &Stack[T, I]{
		l: SingleLinkedList[T, I]{
			first:  nil,
			last:   nil,
			length: 0,
		},
	}
}
func (s *Stack[T, I]) Len() I         { return s.l.length }
func (s *Stack[T, I]) Push(value T)   { s.l.InsertFirst(value) }
func (s *Stack[T, I]) Pop() T         { return s.l.RemoveFirst() }
func (s *Stack[T, I]) Preview() T     { return s.l.First() }
func (s *Stack[T, I]) String() string { return s.l.String() }

// #endregion

// #endregion
// #region Heap
type BinaryHeap[T Prioritizable[T], I Signed] struct {
	s []T
}

func NewBinaryHeap[T Prioritizable[T], I Signed](s []T) (h *BinaryHeap[T, I]) {
	h = &BinaryHeap[T, I]{
		s: s,
	}

	for i := (h.Len() - 2) / 2; i >= 0; i-- {
		h.heapifyDown(i)
	}
	return
}
func (h *BinaryHeap[T, I]) Len() I {
	return I(len(h.s))
}
func (h *BinaryHeap[T, I]) Push(value T) {
	h.s = append(h.s, value)
	h.heapifyUp(h.Len() - 1)
}
func (h *BinaryHeap[T, I]) Pop() (res T) {
	res = h.s[0]
	h.s[0] = h.s[h.Len()-1]
	h.s = h.s[:h.Len()-1]
	h.heapifyDown(0)
	return
}

func (h *BinaryHeap[T, I]) heapifyDown(index I) bool {
	origin := index
	for {
		j := index*2 + 2
		if j < h.Len() {
			if h.s[j-1].PriorTo(h.s[j]) {
				j--
			}
		} else {
			if j <= h.Len() && !h.s[j].PriorTo(h.s[index]) {
				h.s[j], h.s[index] = h.s[index], h.s[j]
			}
			break
		}
		if h.s[j].PriorTo(h.s[index]) {
			h.s[j], h.s[index] = h.s[index], h.s[j]
			index = j
		} else {
			break
		}
	}
	return origin != index
}
func (h *BinaryHeap[T, I]) heapifyUp(index I) {
	for {
		parent := (index - 1) / 2
		if parent == index || h.s[parent].PriorTo(h.s[index]) {
			break
		}
		h.s[index], h.s[parent] = h.s[parent], h.s[index]
		index = parent
	}
}

// #endregion
// #region Set
type Set[T comparable] struct {
	l SingleLinkedList[T, uint64]
}

func NewSet[T comparable]() *Set[T] {
	return &Set[T]{l: *NewSingleLinkedList[T, uint64]()}
}
func (s *Set[T]) Add(element T) (added bool) {
	if !s.l.Contains(element) {
		s.l.InsertLast(element)
		return true
	} else {
		return false
	}
}
func (s *Set[T]) ToSlice() (res []T) {
	return s.l.ToSlice()
}
func (s *Set[T]) String() (res []T) {
	return s.l.ToSlice()
}

// #endregion

// #region FUNCTIONS
func Max[T Ordered](a, b T) T {
	if a >= b {
		return a
	}
	return b
}
func Min[T Ordered](a, b T) T {
	if a <= b {
		return a
	}
	return b
}
func Abs[T Integer | Float](a T) T {
	if a < 0 {
		return -a
	}
	return a
}
func Swap[T any](a, b *T) {
	*a, *b = *b, *a
}

// At least one != 0
func GCD[T Unsigned](a, b T) T {
	if b < a {
		Swap(&a, &b)
	}
	for {
		if a == 0 {
			return b
		}
		r := (b % a)
		b = a
		a = r
	}
}

// At least one != 0
func LCM[T Unsigned](a, b T) T {
	return (a * b) / GCD(a, b)
}

func First[T any](a T, _ any) T { return a }

// #endregion

// #region IO STUFF
type IO struct {
	r *bufio.Reader
	w *bufio.Writer
}

func newStdIO() IO {
	return IO{
		r: bufio.NewReader(os.Stdin),
		w: bufio.NewWriter(os.Stdout),
	}
}

// Is assumed that input.txt file exists
func newFileIO() IO {
	return IO{
		r: bufio.NewReader(First(os.Open("input.txt"))),
		w: bufio.NewWriter(First(os.OpenFile("output.txt", os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm))),
	}
}

func (io *IO) ScanInt8() (x int8)   { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt16() (x int16) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt32() (x int32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt64() (x int64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanUInt8() (x uint8)   { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt16() (x uint16) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt32() (x uint32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt64() (x uint64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanFloat32() (x float32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanFloat64() (x float64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanString() (x string) { fmt.Fscan(io.r, &x); return }

func (io *IO) Print(x ...any)   { fmt.Fprint(io.w, x...) }
func (io *IO) PrintLn(x ...any) { fmt.Fprintln(io.w, x...) }

func (io *IO) Flush() { io.w.Flush() }

// #endregion

// #region KEEP IMPORTS
func D() {
	_ = bufio.Reader{}
	_ = bytes.Buffer{}
	_ = suffixarray.Index{}
	_ = log.Default()
	_ = math.Abs(0)
	_ = net.Dialer{}
	_ = path.ErrBadPattern
	_ = sort.Float64sAreSorted(nil)
	_ = strconv.ErrRange
	_ = strings.Builder{}
	_ = time.ANSIC
	_ = newStdIO()
	_ = newFileIO()
}

// #endregion

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"index/suffixarray"
	"log"
	"math"
	"net"
	"os"
	"path"
	"sort"
	"strconv"
	"strings"
	"time"
)

/*
praticamente lui trova per ogni destinazione di una macchina tutti percorsi con le persone che può portare
(ogni percorso è identificato dall'insieme matematico tipo delle persone che porta con sè),
e il numero di questi percorsi è umano, infatti è massimo 2^6.
Poi una volta che hai tutti i possbili percorsi trovi tutte le possbili loro combinazioni tra tutti
 nodi finale macchine (dove puoi prendere massimo 1 percorso per nodo finale macchina) e returni quella migliore
il clou sta nel trovare tutte le combinazioni
che è sto codice qua (guarda soluzione ufficiale dove usa backpack), dove si salva le possibili combiniazioni in backpack,
credo sia questa la parte di programmazione dinamica
e usa il bitwise or dove ogni bit corrisponde ad una persona senza macchina
*/

// For Codeforces
func main() {
	io := newStdIO()
	defer io.Flush()
	for T := io.ScanUInt16(); T > 0; T-- {
		solve(&io)
	}
}
func solve(io *IO) {
	n := io.ScanInt32()
	m := io.ScanInt32()
	adj := make(map[int32]*SingleLinkedList[int32, uint32])
	for i := int32(0); i < n; i++ {
		adj[i] = NewSingleLinkedList[int32, uint32]()
	}
	for i := int32(0); i < m; i++ {
		a := io.ScanInt32() - 1
		b := io.ScanInt32() - 1
		adj[a].InsertLast(b)
		adj[b].InsertLast(a)
	}
	Nfrends := io.ScanInt32()
	friends := make([]int32, Nfrends)
	for i := int32(0); i < Nfrends; i++ {
		tmp := io.ScanInt32() - 1
		friends[i] = tmp
	}
	NfriendsWithoutCar := io.ScanUInt8()
	friendsWithoutCar := make([]int32, NfriendsWithoutCar)
	for i := uint8(0); i < NfriendsWithoutCar; i++ {
		tmp := io.ScanInt32() - 1
		friendsWithoutCar[i] = tmp
	}
	dist := make([]int32, n)
	masks := make([]uint8, n)
	for k, _ := range dist {
		dist[k] = -1
	}
	dist[0] = 0
	dfs := NewQueue[int32, uint32]()
	dfs.Enqueue(0)
	for i := uint8(0); i < NfriendsWithoutCar; i++ {
		masks[friends[friendsWithoutCar[i]]] += 1 << i
	}

	path := make([]*Set[uint8], n)
	for i, _ := range path {
		path[i] = NewSet[uint8]()
	}
	path[0].Add(0)
	for dfs.Len() > 0 {
		tmp := dfs.Dequeue()
		next := adj[tmp].ToSlice()
		for i := 0; i < len(next); i++ {
			if dist[next[i]] == -1 {
				dfs.Enqueue(next[i])
			}
			if dist[next[i]] != dist[tmp] {
				dist[next[i]] = dist[tmp] + 1
				tmp2 := path[tmp].ToSlice()
				for _, p := range tmp2 {
					path[next[i]].Add(masks[next[i]] | p)
				}
			}
		}
	}

	dp := make([]bool, 1<<NfriendsWithoutCar)
	j := 0
	dp[0] = true
	dpCopy := make([]bool, len(dp))
	for i := int32(0); i < Nfrends; i++ {
		if j < int(NfriendsWithoutCar) && i == friendsWithoutCar[j] {
			j++
			continue
		}

		copy(dpCopy, dp)

		for m := uint8(0); m < 1<<NfriendsWithoutCar; m++ {
			if dp[m] {
				paths := path[friends[i]].ToSlice()
				for _, p := range paths {
					dpCopy[p|m] = true
				}
			}
		}
		dp = dpCopy

	}
	min := NfriendsWithoutCar
	for m := uint8(0); m < 1<<NfriendsWithoutCar; m++ {
		c := uint8(0)
		if dp[m] {
			for i := uint8(0); i < NfriendsWithoutCar; i++ {
				if m&(1<<i) == 0 {
					c++
				}
			}
			min = Min(min, c)
		}
	}
	io.PrintLn(min)
}

// #region INTERFACES

// From https://pkg.go.dev/golang.org/x/exp/constraints
type Signed interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64
}
type Unsigned interface {
	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}
type Integer interface {
	Signed | Unsigned
}
type Float interface {
	~float32 | ~float64
}
type Complex interface {
	~complex64 | ~complex128
}
type Ordered interface {
	Integer | Float | ~string
}

type Prioritizable[T any] interface {
	PriorTo(x T) bool // If you take this as a relation: if (a,b) in R => (b,a) not in R
}

// #endregion
// #region TYPES WITH METHODS
// #region SingleLinkedList
type singleLinkedListNode[T comparable] struct {
	Value T
	Next  *singleLinkedListNode[T]
}

type SingleLinkedList[T comparable, IndexType Unsigned] struct {
	first  *singleLinkedListNode[T]
	last   *singleLinkedListNode[T]
	length IndexType
}

func NewSingleLinkedList[T comparable, IndexType Unsigned]() *SingleLinkedList[T, IndexType] {
	return &SingleLinkedList[T, IndexType]{
		first:  nil,
		last:   nil,
		length: 0,
	}
}
func (l *SingleLinkedList[T, I]) Len() I { return l.length }

// length > 0
func (l *SingleLinkedList[T, I]) First() T { return l.first.Value }

// length > 0
func (l *SingleLinkedList[T, I]) Last() T { return l.last.Value }

func (l *SingleLinkedList[T, I]) InsertFirst(value T) {
	if l.length == 0 {
		nodeToInsert := &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
		l.first = nodeToInsert
		l.last = nodeToInsert
	} else {
		l.first = &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
	}
	l.length++
}

func (l *SingleLinkedList[T, I]) InsertLast(value T) {
	if l.length == 0 {
		nodeToInsert := &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
		l.first = nodeToInsert
		l.last = nodeToInsert
	} else {
		l.last.Next = &singleLinkedListNode[T]{
			Value: value,
			Next:  nil,
		}
		l.last = l.last.Next
	}
	l.length++
}

// index <= length
func (l *SingleLinkedList[T, I]) InsertAt(index I, value T) {
	if index == 0 {
		l.InsertFirst(value)
		return
	}
	if index == l.length {
		l.InsertLast(value)
		return
	}

	n := l.first
	for index > 1 {
		n = n.Next
		index--
	}
	n.Next = &singleLinkedListNode[T]{
		Value: value,
		Next:  n.Next,
	}
	l.length++
}

func (l *SingleLinkedList[T, I]) Contains(value T) bool {
	tmp := l.first
	for i := I(0); i < l.length; i++ {
		if tmp.Value == value {
			return true
		}
		tmp = tmp.Next
	}
	return false
}
func (l *SingleLinkedList[T, I]) Clear() {
	l.first = nil
	l.last = nil
	l.length = 0
}

// index < length
func (l *SingleLinkedList[T, I]) GetElementAt(index I) T {
	n := l.first
	for index > 0 {
		n = n.Next
		index--
	}
	return n.Value
}

// index < length
func (l *SingleLinkedList[T, I]) SetElementAt(index I, value T) {
	n := l.first
	for index > 0 {
		n = n.Next
		index--
	}
	n.Value = value
}

func (l *SingleLinkedList[T, I]) RemoveFirst() T {
	tmp := l.first
	l.first = l.first.Next
	l.length--
	if l.length == 0 {
		l.last = nil
	}
	return tmp.Value
}
func (l *SingleLinkedList[T, I]) RemoveLast() (value T) {
	value = l.last.Value
	if l.length == 1 {
		l.first = nil
		l.last = nil
		l.length = 0
		return
	}

	tmp := l.first
	for i := I(2); i < l.length; i++ {
		tmp = tmp.Next
	}
	l.last = tmp
	return
}

func (l *SingleLinkedList[T, I]) RemoveAt(index I) T {
	if index == 0 {
		return l.RemoveFirst()
	}
	if index == l.length-1 {
		return l.RemoveLast()
	}

	tmp := l.first
	for i := I(1); i < index; i++ {
		tmp = tmp.Next
	}
	res := tmp.Next.Value
	tmp.Next = tmp.Next.Next
	return res
}

func (l *SingleLinkedList[T, I]) ToSlice() (res []T) {
	res = make([]T, 0, l.length)
	tmp := l.first
	for i := I(0); i < l.length; i++ {
		res = append(res, tmp.Value)
		tmp = tmp.Next
	}
	return
}
func (it *SingleLinkedList[T, I]) String() string {
	return "Qua:: " + fmt.Sprint(it.ToSlice())
}

// #endregion
// #region Queue

type Queue[T comparable, I Unsigned] struct {
	l SingleLinkedList[T, I]
}

func NewQueue[T comparable, I Unsigned]() *Queue[T, I] {
	return &Queue[T, I]{
		l: SingleLinkedList[T, I]{
			first:  nil,
			last:   nil,
			length: 0,
		},
	}
}
func (q *Queue[T, I]) Len() I          { return q.l.length }
func (q *Queue[T, I]) Enqueue(value T) { q.l.InsertLast(value) }
func (q *Queue[T, I]) Dequeue() T      { return q.l.RemoveFirst() }
func (q *Queue[T, I]) Preview() T      { return q.l.First() }
func (q *Queue[T, I]) String() string  { return q.l.String() }

// #endregion
// #region Stack

type Stack[T comparable, I Unsigned] struct {
	l SingleLinkedList[T, I]
}

func NewStack[T comparable, I Unsigned]() *Stack[T, I] {
	return &Stack[T, I]{
		l: SingleLinkedList[T, I]{
			first:  nil,
			last:   nil,
			length: 0,
		},
	}
}
func (s *Stack[T, I]) Len() I         { return s.l.length }
func (s *Stack[T, I]) Push(value T)   { s.l.InsertFirst(value) }
func (s *Stack[T, I]) Pop() T         { return s.l.RemoveFirst() }
func (s *Stack[T, I]) Preview() T     { return s.l.First() }
func (s *Stack[T, I]) String() string { return s.l.String() }

// #endregion

// #endregion
// #region Heap
type BinaryHeap[T Prioritizable[T], I Signed] struct {
	s []T
}

func NewBinaryHeap[T Prioritizable[T], I Signed](s []T) (h *BinaryHeap[T, I]) {
	h = &BinaryHeap[T, I]{
		s: s,
	}

	for i := (h.Len() - 2) / 2; i >= 0; i-- {
		h.heapifyDown(i)
	}
	return
}
func (h *BinaryHeap[T, I]) Len() I {
	return I(len(h.s))
}
func (h *BinaryHeap[T, I]) Push(value T) {
	h.s = append(h.s, value)
	h.heapifyUp(h.Len() - 1)
}
func (h *BinaryHeap[T, I]) Pop() (res T) {
	res = h.s[0]
	h.s[0] = h.s[h.Len()-1]
	h.s = h.s[:h.Len()-1]
	h.heapifyDown(0)
	return
}

func (h *BinaryHeap[T, I]) heapifyDown(index I) bool {
	origin := index
	for {
		j := index*2 + 2
		if j < h.Len() {
			if h.s[j-1].PriorTo(h.s[j]) {
				j--
			}
		} else {
			if j <= h.Len() && !h.s[j].PriorTo(h.s[index]) {
				h.s[j], h.s[index] = h.s[index], h.s[j]
			}
			break
		}
		if h.s[j].PriorTo(h.s[index]) {
			h.s[j], h.s[index] = h.s[index], h.s[j]
			index = j
		} else {
			break
		}
	}
	return origin != index
}
func (h *BinaryHeap[T, I]) heapifyUp(index I) {
	for {
		parent := (index - 1) / 2
		if parent == index || h.s[parent].PriorTo(h.s[index]) {
			break
		}
		h.s[index], h.s[parent] = h.s[parent], h.s[index]
		index = parent
	}
}

// #endregion
// #region Set
type Set[T comparable] struct {
	l SingleLinkedList[T, uint64]
}

func NewSet[T comparable]() *Set[T] {
	return &Set[T]{l: *NewSingleLinkedList[T, uint64]()}
}
func (s *Set[T]) Add(element T) (added bool) {
	if !s.l.Contains(element) {
		s.l.InsertLast(element)
		return true
	} else {
		return false
	}
}
func (s *Set[T]) ToSlice() (res []T) {
	return s.l.ToSlice()
}
func (s *Set[T]) String() (res []T) {
	return s.l.ToSlice()
}

// #endregion

// #region FUNCTIONS
func Max[T Ordered](a, b T) T {
	if a >= b {
		return a
	}
	return b
}
func Min[T Ordered](a, b T) T {
	if a <= b {
		return a
	}
	return b
}
func Abs[T Integer | Float](a T) T {
	if a < 0 {
		return -a
	}
	return a
}
func Swap[T any](a, b *T) {
	*a, *b = *b, *a
}

// At least one != 0
func GCD[T Unsigned](a, b T) T {
	if b < a {
		Swap(&a, &b)
	}
	for {
		if a == 0 {
			return b
		}
		r := (b % a)
		b = a
		a = r
	}
}

// At least one != 0
func LCM[T Unsigned](a, b T) T {
	return (a * b) / GCD(a, b)
}

func First[T any](a T, _ any) T { return a }

// #endregion

// #region IO STUFF
type IO struct {
	r *bufio.Reader
	w *bufio.Writer
}

func newStdIO() IO {
	return IO{
		r: bufio.NewReader(os.Stdin),
		w: bufio.NewWriter(os.Stdout),
	}
}

// Is assumed that input.txt file exists
func newFileIO() IO {
	return IO{
		r: bufio.NewReader(First(os.Open("input.txt"))),
		w: bufio.NewWriter(First(os.OpenFile("output.txt", os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm))),
	}
}

func (io *IO) ScanInt8() (x int8)   { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt16() (x int16) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt32() (x int32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt64() (x int64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanUInt8() (x uint8)   { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt16() (x uint16) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt32() (x uint32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt64() (x uint64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanFloat32() (x float32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanFloat64() (x float64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanString() (x string) { fmt.Fscan(io.r, &x); return }

func (io *IO) Print(x ...any)   { fmt.Fprint(io.w, x...) }
func (io *IO) PrintLn(x ...any) { fmt.Fprintln(io.w, x...) }

func (io *IO) Flush() { io.w.Flush() }

// #endregion

// #region KEEP IMPORTS
func D() {
	_ = bufio.Reader{}
	_ = bytes.Buffer{}
	_ = suffixarray.Index{}
	_ = log.Default()
	_ = math.Abs(0)
	_ = net.Dialer{}
	_ = path.ErrBadPattern
	_ = sort.Float64sAreSorted(nil)
	_ = strconv.ErrRange
	_ = strings.Builder{}
	_ = time.ANSIC
	_ = newStdIO()
	_ = newFileIO()
}

// #endregion

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"index/suffixarray"
	"log"
	"math"
	"net"
	"os"
	"path"
	"sort"
	"strconv"
	"strings"
	"time"
)

/*
praticamente lui trova per ogni destinazione di una macchina tutti percorsi con le persone che può portare
(ogni percorso è identificato dall'insieme matematico tipo delle persone che porta con sè),
e il numero di questi percorsi è umano, infatti è massimo 2^6.
Poi una volta che hai tutti i possbili percorsi trovi tutte le possbili loro combinazioni tra tutti
 nodi finale macchine (dove puoi prendere massimo 1 percorso per nodo finale macchina) e returni quella migliore
il clou sta nel trovare tutte le combinazioni
che è sto codice qua (guarda soluzione ufficiale dove usa backpack), dove si salva le possibili combiniazioni in backpack,
credo sia questa la parte di programmazione dinamica
e usa il bitwise or dove ogni bit corrisponde ad una persona senza macchina
*/

// For Codeforces
func main() {
	io := newStdIO()
	defer io.Flush()
	for T := io.ScanUInt16(); T > 0; T-- {
		solve(&io)
	}
}
func solve(io *IO) {
	n := io.ScanInt32()
	m := io.ScanInt32()
	adj := make(map[int32]*SingleLinkedList[int32, uint32])
	for i := int32(0); i < n; i++ {
		adj[i] = NewSingleLinkedList[int32, uint32]()
	}
	for i := int32(0); i < m; i++ {
		a := io.ScanInt32() - 1
		b := io.ScanInt32() - 1
		adj[a].InsertLast(b)
	}
	Nfrends := io.ScanInt32()
	friends := make([]int32, Nfrends)
	for i := int32(0); i < Nfrends; i++ {
		tmp := io.ScanInt32() - 1
		friends[i] = tmp
	}
	NfriendsWithoutCar := io.ScanUInt8()
	friendsWithoutCar := make([]int32, NfriendsWithoutCar)
	for i := uint8(0); i < NfriendsWithoutCar; i++ {
		tmp := io.ScanInt32() - 1
		friendsWithoutCar[i] = tmp
	}
	dist := make([]int32, n)
	masks := make([]uint8, n)
	for k, _ := range dist {
		dist[k] = -1
	}
	dist[0] = 0
	dfs := NewQueue[int32, uint32]()
	dfs.Enqueue(0)
	for i := uint8(0); i < NfriendsWithoutCar; i++ {
		masks[friends[friendsWithoutCar[i]]] = 1 << i
	}

	path := make([]*Set[uint8], n)
	for i, _ := range path {
		path[i] = NewSet[uint8]()
	}
	path[0].Add(0)
	for dfs.Len() > 0 {
		tmp := dfs.Dequeue()
		next := adj[tmp].ToSlice()
		for i := 0; i < len(next); i++ {
			dfs.Enqueue(next[i])
			if dist[next[i]] != dist[tmp] {
				dist[next[i]] = dist[tmp]+1
				tmp2 := path[tmp].ToSlice()
				for _, p := range tmp2 {
					path[next[i]].Add(masks[next[i]] | p)
				}
			}
		}
	}

	dp := make([]bool, 1 << NfriendsWithoutCar)
	j := 0
	dp[0] = true
	dpCopy := make([]bool, len(dp))
	for i := int32(0); i < Nfrends; i++ {
		if j < int(NfriendsWithoutCar) && i == friendsWithoutCar[j] {
			j++
			continue
		}

		copy(dpCopy, dp)

		for m := uint8(0); m < 1<<NfriendsWithoutCar; m++ {
			if dp[m]{
				paths := path[friends[i]].ToSlice()
				for _, p := range paths {
					dpCopy[p|m] = true
				}
			}
		}
		dp = dpCopy

	}
	min := NfriendsWithoutCar
	for m := uint8(0); m < 1<<NfriendsWithoutCar; m++ {
		c := uint8(0)
		if dp[m]{
			for i := uint8(0); i < NfriendsWithoutCar; i++ {
				if m&(1 << i) == 0 {
					c++
				}
			}
			min = Min(min, c)
		}
	}
	io.PrintLn(min)
}

// #region INTERFACES

// From https://pkg.go.dev/golang.org/x/exp/constraints
type Signed interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64
}
type Unsigned interface {
	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}
type Integer interface {
	Signed | Unsigned
}
type Float interface {
	~float32 | ~float64
}
type Complex interface {
	~complex64 | ~complex128
}
type Ordered interface {
	Integer | Float | ~string
}

type Prioritizable[T any] interface {
	PriorTo(x T) bool // If you take this as a relation: if (a,b) in R => (b,a) not in R
}

// #endregion
// #region TYPES WITH METHODS
// #region SingleLinkedList
type singleLinkedListNode[T comparable] struct {
	Value T
	Next  *singleLinkedListNode[T]
}

type SingleLinkedList[T comparable, IndexType Unsigned] struct {
	first  *singleLinkedListNode[T]
	last   *singleLinkedListNode[T]
	length IndexType
}

func NewSingleLinkedList[T comparable, IndexType Unsigned]() *SingleLinkedList[T, IndexType] {
	return &SingleLinkedList[T, IndexType]{
		first:  nil,
		last:   nil,
		length: 0,
	}
}
func (l *SingleLinkedList[T, I]) Len() I { return l.length }

// length > 0
func (l *SingleLinkedList[T, I]) First() T { return l.first.Value }

// length > 0
func (l *SingleLinkedList[T, I]) Last() T { return l.last.Value }

func (l *SingleLinkedList[T, I]) InsertFirst(value T) {
	if l.length == 0 {
		nodeToInsert := &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
		l.first = nodeToInsert
		l.last = nodeToInsert
	} else {
		l.first = &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
	}
	l.length++
}

func (l *SingleLinkedList[T, I]) InsertLast(value T) {
	if l.length == 0 {
		nodeToInsert := &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
		l.first = nodeToInsert
		l.last = nodeToInsert
	} else {
		l.last.Next = &singleLinkedListNode[T]{
			Value: value,
			Next:  nil,
		}
		l.last = l.last.Next
	}
	l.length++
}

// index <= length
func (l *SingleLinkedList[T, I]) InsertAt(index I, value T) {
	if index == 0 {
		l.InsertFirst(value)
		return
	}
	if index == l.length {
		l.InsertLast(value)
		return
	}

	n := l.first
	for index > 1 {
		n = n.Next
		index--
	}
	n.Next = &singleLinkedListNode[T]{
		Value: value,
		Next:  n.Next,
	}
	l.length++
}

func (l *SingleLinkedList[T, I]) Contains(value T) bool {
	tmp := l.first
	for i := I(0); i < l.length; i++ {
		if tmp.Value == value {
			return true
		}
		tmp = tmp.Next
	}
	return false
}
func (l *SingleLinkedList[T, I]) Clear() {
	l.first = nil
	l.last = nil
	l.length = 0
}

// index < length
func (l *SingleLinkedList[T, I]) GetElementAt(index I) T {
	n := l.first
	for index > 0 {
		n = n.Next
		index--
	}
	return n.Value
}

// index < length
func (l *SingleLinkedList[T, I]) SetElementAt(index I, value T) {
	n := l.first
	for index > 0 {
		n = n.Next
		index--
	}
	n.Value = value
}

func (l *SingleLinkedList[T, I]) RemoveFirst() T {
	tmp := l.first
	l.first = l.first.Next
	l.length--
	if l.length == 0 {
		l.last = nil
	}
	return tmp.Value
}
func (l *SingleLinkedList[T, I]) RemoveLast() (value T) {
	value = l.last.Value
	if l.length == 1 {
		l.first = nil
		l.last = nil
		l.length = 0
		return
	}

	tmp := l.first
	for i := I(2); i < l.length; i++ {
		tmp = tmp.Next
	}
	l.last = tmp
	return
}

func (l *SingleLinkedList[T, I]) RemoveAt(index I) T {
	if index == 0 {
		return l.RemoveFirst()
	}
	if index == l.length-1 {
		return l.RemoveLast()
	}

	tmp := l.first
	for i := I(1); i < index; i++ {
		tmp = tmp.Next
	}
	res := tmp.Next.Value
	tmp.Next = tmp.Next.Next
	return res
}

func (l *SingleLinkedList[T, I]) ToSlice() (res []T) {
	res = make([]T, 0, l.length)
	tmp := l.first
	for i := I(0); i < l.length; i++ {
		res = append(res, tmp.Value)
		tmp = tmp.Next
	}
	return
}
func (it *SingleLinkedList[T, I]) String() string {
	return "Qua:: " + fmt.Sprint(it.ToSlice())
}

// #endregion
// #region Queue

type Queue[T comparable, I Unsigned] struct {
	l SingleLinkedList[T, I]
}

func NewQueue[T comparable, I Unsigned]() *Queue[T, I] {
	return &Queue[T, I]{
		l: SingleLinkedList[T, I]{
			first:  nil,
			last:   nil,
			length: 0,
		},
	}
}
func (q *Queue[T, I]) Len() I          { return q.l.length }
func (q *Queue[T, I]) Enqueue(value T) { q.l.InsertLast(value) }
func (q *Queue[T, I]) Dequeue() T      { return q.l.RemoveFirst() }
func (q *Queue[T, I]) Preview() T      { return q.l.First() }
func (q *Queue[T, I]) String() string  { return q.l.String() }

// #endregion
// #region Stack

type Stack[T comparable, I Unsigned] struct {
	l SingleLinkedList[T, I]
}

func NewStack[T comparable, I Unsigned]() *Stack[T, I] {
	return &Stack[T, I]{
		l: SingleLinkedList[T, I]{
			first:  nil,
			last:   nil,
			length: 0,
		},
	}
}
func (s *Stack[T, I]) Len() I         { return s.l.length }
func (s *Stack[T, I]) Push(value T)   { s.l.InsertFirst(value) }
func (s *Stack[T, I]) Pop() T         { return s.l.RemoveFirst() }
func (s *Stack[T, I]) Preview() T     { return s.l.First() }
func (s *Stack[T, I]) String() string { return s.l.String() }

// #endregion

// #endregion
// #region Heap
type BinaryHeap[T Prioritizable[T], I Signed] struct {
	s []T
}

func NewBinaryHeap[T Prioritizable[T], I Signed](s []T) (h *BinaryHeap[T, I]) {
	h = &BinaryHeap[T, I]{
		s: s,
	}

	for i := (h.Len() - 2) / 2; i >= 0; i-- {
		h.heapifyDown(i)
	}
	return
}
func (h *BinaryHeap[T, I]) Len() I {
	return I(len(h.s))
}
func (h *BinaryHeap[T, I]) Push(value T) {
	h.s = append(h.s, value)
	h.heapifyUp(h.Len() - 1)
}
func (h *BinaryHeap[T, I]) Pop() (res T) {
	res = h.s[0]
	h.s[0] = h.s[h.Len()-1]
	h.s = h.s[:h.Len()-1]
	h.heapifyDown(0)
	return
}

func (h *BinaryHeap[T, I]) heapifyDown(index I) bool {
	origin := index
	for {
		j := index*2 + 2
		if j < h.Len() {
			if h.s[j-1].PriorTo(h.s[j]) {
				j--
			}
		} else {
			if j <= h.Len() && !h.s[j].PriorTo(h.s[index]) {
				h.s[j], h.s[index] = h.s[index], h.s[j]
			}
			break
		}
		if h.s[j].PriorTo(h.s[index]) {
			h.s[j], h.s[index] = h.s[index], h.s[j]
			index = j
		} else {
			break
		}
	}
	return origin != index
}
func (h *BinaryHeap[T, I]) heapifyUp(index I) {
	for {
		parent := (index - 1) / 2
		if parent == index || h.s[parent].PriorTo(h.s[index]) {
			break
		}
		h.s[index], h.s[parent] = h.s[parent], h.s[index]
		index = parent
	}
}

// #endregion
// #region Set
type Set[T comparable] struct {
	l SingleLinkedList[T, uint64]
}

func NewSet[T comparable]() *Set[T] {
	return &Set[T]{l: *NewSingleLinkedList[T, uint64]()}
}
func (s *Set[T]) Add(element T) (added bool) {
	if !s.l.Contains(element) {
		s.l.InsertLast(element)
		return true
	} else {
		return false
	}
}
func (s *Set[T]) ToSlice() (res []T) {
	return s.l.ToSlice()
}
func (s *Set[T]) String() (res []T) {
	return s.l.ToSlice()
}

// #endregion

// #region FUNCTIONS
func Max[T Ordered](a, b T) T {
	if a >= b {
		return a
	}
	return b
}
func Min[T Ordered](a, b T) T {
	if a <= b {
		return a
	}
	return b
}
func Abs[T Integer | Float](a T) T {
	if a < 0 {
		return -a
	}
	return a
}
func Swap[T any](a, b *T) {
	*a, *b = *b, *a
}

// At least one != 0
func GCD[T Unsigned](a, b T) T {
	if b < a {
		Swap(&a, &b)
	}
	for {
		if a == 0 {
			return b
		}
		r := (b % a)
		b = a
		a = r
	}
}

// At least one != 0
func LCM[T Unsigned](a, b T) T {
	return (a * b) / GCD(a, b)
}

func First[T any](a T, _ any) T { return a }

// #endregion

// #region IO STUFF
type IO struct {
	r *bufio.Reader
	w *bufio.Writer
}

func newStdIO() IO {
	return IO{
		r: bufio.NewReader(os.Stdin),
		w: bufio.NewWriter(os.Stdout),
	}
}

// Is assumed that input.txt file exists
func newFileIO() IO {
	return IO{
		r: bufio.NewReader(First(os.Open("input.txt"))),
		w: bufio.NewWriter(First(os.OpenFile("output.txt", os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm))),
	}
}

func (io *IO) ScanInt8() (x int8)   { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt16() (x int16) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt32() (x int32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt64() (x int64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanUInt8() (x uint8)   { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt16() (x uint16) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt32() (x uint32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt64() (x uint64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanFloat32() (x float32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanFloat64() (x float64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanString() (x string) { fmt.Fscan(io.r, &x); return }

func (io *IO) Print(x ...any)   { fmt.Fprint(io.w, x...) }
func (io *IO) PrintLn(x ...any) { fmt.Fprintln(io.w, x...) }

func (io *IO) Flush() { io.w.Flush() }

// #endregion

// #region KEEP IMPORTS
func D() {
	_ = bufio.Reader{}
	_ = bytes.Buffer{}
	_ = suffixarray.Index{}
	_ = log.Default()
	_ = math.Abs(0)
	_ = net.Dialer{}
	_ = path.ErrBadPattern
	_ = sort.Float64sAreSorted(nil)
	_ = strconv.ErrRange
	_ = strings.Builder{}
	_ = time.ANSIC
	_ = newStdIO()
	_ = newFileIO()
}

// #endregion

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"index/suffixarray"
	"log"
	"math"
	"net"
	"os"
	"path"
	"sort"
	"strconv"
	"strings"
	"time"
)

/*
praticamente lui trova per ogni destinazione di una macchina tutti percorsi con le persone che può portare
(ogni percorso è identificato dall'insieme matematico tipo delle persone che porta con sè),
e il numero di questi percorsi è umano, infatti è massimo 2^6.
Poi una volta che hai tutti i possbili percorsi trovi tutte le possbili loro combinazioni tra tutti
 nodi finale macchine (dove puoi prendere massimo 1 percorso per nodo finale macchina) e returni quella migliore
il clou sta nel trovare tutte le combinazioni
che è sto codice qua (guarda soluzione ufficiale dove usa backpack), dove si salva le possibili combiniazioni in backpack,
credo sia questa la parte di programmazione dinamica
e usa il bitwise or dove ogni bit corrisponde ad una persona senza macchina
*/

// For Codeforces
func main() {
	io := newStdIO()
	defer io.Flush()
	for T := io.ScanUInt16(); T > 0; T-- {
		solve(&io)
	}
}
func solve(io *IO) {
	n := io.ScanInt32()
	m := io.ScanInt32()
	adj := make(map[int32]*SingleLinkedList[int32, uint32])
	for i := int32(0); i < n; i++ {
		adj[i] = NewSingleLinkedList[int32, uint32]()
	}
	for i := int32(0); i < m; i++ {
		a := io.ScanInt32() - 1
		b := io.ScanInt32() - 1
		adj[a].InsertLast(b)
		adj[b].InsertLast(a)
	}
	Nfrends := io.ScanInt32()
	friends := make([]int32, Nfrends)
	for i := int32(0); i < Nfrends; i++ {
		tmp := io.ScanInt32() - 1
		friends[i] = tmp
	}
	NfriendsWithoutCar := io.ScanUInt8()
	friendsWithoutCar := make([]int32, NfriendsWithoutCar+1)
	for i := uint8(0); i < NfriendsWithoutCar; i++ {
		tmp := io.ScanInt32() - 1
		friendsWithoutCar[i] = tmp
	}
	friendsWithoutCar[NfriendsWithoutCar] = -1
	dist := make([]int32, n)
	masks := make([]uint8, n)
	for k, _ := range dist {
		dist[k] = -1
	}
	dist[0] = 0
	dfs := NewQueue[int32, uint32]()
	dfs.Enqueue(0)
	for i := uint8(0); i < NfriendsWithoutCar; i++ {
		masks[friends[friendsWithoutCar[i]]] += 1 << i
	}

	path := make([]*Set[uint8], n)
	for i, _ := range path {
		path[i] = NewSet[uint8]()
	}
	path[0].Add(masks[0])
	for dfs.Len() > 0 {
		tmp := dfs.Dequeue()
		next := adj[tmp].ToSlice()
		for i := 0; i < len(next); i++ {
			if dist[next[i]] == -1 {
				dist[next[i]] = dist[tmp] + 1
				dfs.Enqueue(next[i])
			}
			if dist[next[i]] == dist[tmp]+1 {
				tmp2 := path[tmp].ToSlice()
				for _, p := range tmp2 {
					path[next[i]].Add(masks[next[i]] | p)
				}
			}
		}
	}

	dp := make([]bool, 1<<NfriendsWithoutCar)
	j := 0
	dp[0] = true
	dpCopy := make([]bool, len(dp))
	for i := int32(0); i < Nfrends; i++ {
		if i == friendsWithoutCar[j] {
			j++
			continue
		}

		copy(dpCopy, dp)

		for m := uint8(0); m < 1<<NfriendsWithoutCar; m++ {
			if dp[m] {
				paths := path[friends[i]].ToSlice()
				for _, p := range paths {
					dpCopy[p|m] = true
				}
			}
		}
		dp = dpCopy

	}
	min := NfriendsWithoutCar
	for m := uint8(0); m < 1<<NfriendsWithoutCar; m++ {
		if dp[m] {
			c := uint8(0)
			for i := uint8(0); i < NfriendsWithoutCar; i++ {
				if m&(1<<i) == 0 {
					c++
				}
			}
			min = Min(min, c)
		}
	}
	io.PrintLn(min)
}

// #region INTERFACES

// From https://pkg.go.dev/golang.org/x/exp/constraints
type Signed interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64
}
type Unsigned interface {
	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}
type Integer interface {
	Signed | Unsigned
}
type Float interface {
	~float32 | ~float64
}
type Complex interface {
	~complex64 | ~complex128
}
type Ordered interface {
	Integer | Float | ~string
}

type Prioritizable[T any] interface {
	PriorTo(x T) bool // If you take this as a relation: if (a,b) in R => (b,a) not in R
}

// #endregion
// #region TYPES WITH METHODS
// #region SingleLinkedList
type singleLinkedListNode[T comparable] struct {
	Value T
	Next  *singleLinkedListNode[T]
}

type SingleLinkedList[T comparable, IndexType Unsigned] struct {
	first  *singleLinkedListNode[T]
	last   *singleLinkedListNode[T]
	length IndexType
}

func NewSingleLinkedList[T comparable, IndexType Unsigned]() *SingleLinkedList[T, IndexType] {
	return &SingleLinkedList[T, IndexType]{
		first:  nil,
		last:   nil,
		length: 0,
	}
}
func (l *SingleLinkedList[T, I]) Len() I { return l.length }

// length > 0
func (l *SingleLinkedList[T, I]) First() T { return l.first.Value }

// length > 0
func (l *SingleLinkedList[T, I]) Last() T { return l.last.Value }

func (l *SingleLinkedList[T, I]) InsertFirst(value T) {
	if l.length == 0 {
		nodeToInsert := &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
		l.first = nodeToInsert
		l.last = nodeToInsert
	} else {
		l.first = &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
	}
	l.length++
}

func (l *SingleLinkedList[T, I]) InsertLast(value T) {
	if l.length == 0 {
		nodeToInsert := &singleLinkedListNode[T]{
			Value: value,
			Next:  l.first,
		}
		l.first = nodeToInsert
		l.last = nodeToInsert
	} else {
		l.last.Next = &singleLinkedListNode[T]{
			Value: value,
			Next:  nil,
		}
		l.last = l.last.Next
	}
	l.length++
}

// index <= length
func (l *SingleLinkedList[T, I]) InsertAt(index I, value T) {
	if index == 0 {
		l.InsertFirst(value)
		return
	}
	if index == l.length {
		l.InsertLast(value)
		return
	}

	n := l.first
	for index > 1 {
		n = n.Next
		index--
	}
	n.Next = &singleLinkedListNode[T]{
		Value: value,
		Next:  n.Next,
	}
	l.length++
}

func (l *SingleLinkedList[T, I]) Contains(value T) bool {
	tmp := l.first
	for i := I(0); i < l.length; i++ {
		if tmp.Value == value {
			return true
		}
		tmp = tmp.Next
	}
	return false
}
func (l *SingleLinkedList[T, I]) Clear() {
	l.first = nil
	l.last = nil
	l.length = 0
}

// index < length
func (l *SingleLinkedList[T, I]) GetElementAt(index I) T {
	n := l.first
	for index > 0 {
		n = n.Next
		index--
	}
	return n.Value
}

// index < length
func (l *SingleLinkedList[T, I]) SetElementAt(index I, value T) {
	n := l.first
	for index > 0 {
		n = n.Next
		index--
	}
	n.Value = value
}

func (l *SingleLinkedList[T, I]) RemoveFirst() T {
	tmp := l.first
	l.first = l.first.Next
	l.length--
	if l.length == 0 {
		l.last = nil
	}
	return tmp.Value
}
func (l *SingleLinkedList[T, I]) RemoveLast() (value T) {
	value = l.last.Value
	if l.length == 1 {
		l.first = nil
		l.last = nil
		l.length = 0
		return
	}

	tmp := l.first
	for i := I(2); i < l.length; i++ {
		tmp = tmp.Next
	}
	l.last = tmp
	return
}

func (l *SingleLinkedList[T, I]) RemoveAt(index I) T {
	if index == 0 {
		return l.RemoveFirst()
	}
	if index == l.length-1 {
		return l.RemoveLast()
	}

	tmp := l.first
	for i := I(1); i < index; i++ {
		tmp = tmp.Next
	}
	res := tmp.Next.Value
	tmp.Next = tmp.Next.Next
	return res
}

func (l *SingleLinkedList[T, I]) ToSlice() (res []T) {
	res = make([]T, 0, l.length)
	tmp := l.first
	for i := I(0); i < l.length; i++ {
		res = append(res, tmp.Value)
		tmp = tmp.Next
	}
	return
}
func (it *SingleLinkedList[T, I]) String() string {
	return "Qua:: " + fmt.Sprint(it.ToSlice())
}

// #endregion
// #region Queue

type Queue[T comparable, I Unsigned] struct {
	l SingleLinkedList[T, I]
}

func NewQueue[T comparable, I Unsigned]() *Queue[T, I] {
	return &Queue[T, I]{
		l: SingleLinkedList[T, I]{
			first:  nil,
			last:   nil,
			length: 0,
		},
	}
}
func (q *Queue[T, I]) Len() I          { return q.l.length }
func (q *Queue[T, I]) Enqueue(value T) { q.l.InsertLast(value) }
func (q *Queue[T, I]) Dequeue() T      { return q.l.RemoveFirst() }
func (q *Queue[T, I]) Preview() T      { return q.l.First() }
func (q *Queue[T, I]) String() string  { return q.l.String() }

// #endregion
// #region Stack

type Stack[T comparable, I Unsigned] struct {
	l SingleLinkedList[T, I]
}

func NewStack[T comparable, I Unsigned]() *Stack[T, I] {
	return &Stack[T, I]{
		l: SingleLinkedList[T, I]{
			first:  nil,
			last:   nil,
			length: 0,
		},
	}
}
func (s *Stack[T, I]) Len() I         { return s.l.length }
func (s *Stack[T, I]) Push(value T)   { s.l.InsertFirst(value) }
func (s *Stack[T, I]) Pop() T         { return s.l.RemoveFirst() }
func (s *Stack[T, I]) Preview() T     { return s.l.First() }
func (s *Stack[T, I]) String() string { return s.l.String() }

// #endregion

// #endregion
// #region Heap
type BinaryHeap[T Prioritizable[T], I Signed] struct {
	s []T
}

func NewBinaryHeap[T Prioritizable[T], I Signed](s []T) (h *BinaryHeap[T, I]) {
	h = &BinaryHeap[T, I]{
		s: s,
	}

	for i := (h.Len() - 2) / 2; i >= 0; i-- {
		h.heapifyDown(i)
	}
	return
}
func (h *BinaryHeap[T, I]) Len() I {
	return I(len(h.s))
}
func (h *BinaryHeap[T, I]) Push(value T) {
	h.s = append(h.s, value)
	h.heapifyUp(h.Len() - 1)
}
func (h *BinaryHeap[T, I]) Pop() (res T) {
	res = h.s[0]
	h.s[0] = h.s[h.Len()-1]
	h.s = h.s[:h.Len()-1]
	h.heapifyDown(0)
	return
}

func (h *BinaryHeap[T, I]) heapifyDown(index I) bool {
	origin := index
	for {
		j := index*2 + 2
		if j < h.Len() {
			if h.s[j-1].PriorTo(h.s[j]) {
				j--
			}
		} else {
			if j <= h.Len() && !h.s[j].PriorTo(h.s[index]) {
				h.s[j], h.s[index] = h.s[index], h.s[j]
			}
			break
		}
		if h.s[j].PriorTo(h.s[index]) {
			h.s[j], h.s[index] = h.s[index], h.s[j]
			index = j
		} else {
			break
		}
	}
	return origin != index
}
func (h *BinaryHeap[T, I]) heapifyUp(index I) {
	for {
		parent := (index - 1) / 2
		if parent == index || h.s[parent].PriorTo(h.s[index]) {
			break
		}
		h.s[index], h.s[parent] = h.s[parent], h.s[index]
		index = parent
	}
}

// #endregion
// #region Set
type Set[T comparable] struct {
	l SingleLinkedList[T, uint64]
}

func NewSet[T comparable]() *Set[T] {
	return &Set[T]{l: *NewSingleLinkedList[T, uint64]()}
}
func (s *Set[T]) Add(element T) (added bool) {
	if !s.l.Contains(element) {
		s.l.InsertLast(element)
		return true
	} else {
		return false
	}
}
func (s *Set[T]) ToSlice() (res []T) {
	return s.l.ToSlice()
}
func (s *Set[T]) String() (res []T) {
	return s.l.ToSlice()
}

// #endregion

// #region FUNCTIONS
func Max[T Ordered](a, b T) T {
	if a >= b {
		return a
	}
	return b
}
func Min[T Ordered](a, b T) T {
	if a <= b {
		return a
	}
	return b
}
func Abs[T Integer | Float](a T) T {
	if a < 0 {
		return -a
	}
	return a
}
func Swap[T any](a, b *T) {
	*a, *b = *b, *a
}

// At least one != 0
func GCD[T Unsigned](a, b T) T {
	if b < a {
		Swap(&a, &b)
	}
	for {
		if a == 0 {
			return b
		}
		r := (b % a)
		b = a
		a = r
	}
}

// At least one != 0
func LCM[T Unsigned](a, b T) T {
	return (a * b) / GCD(a, b)
}

func First[T any](a T, _ any) T { return a }

// #endregion

// #region IO STUFF
type IO struct {
	r *bufio.Reader
	w *bufio.Writer
}

func newStdIO() IO {
	return IO{
		r: bufio.NewReader(os.Stdin),
		w: bufio.NewWriter(os.Stdout),
	}
}

// Is assumed that input.txt file exists
func newFileIO() IO {
	return IO{
		r: bufio.NewReader(First(os.Open("input.txt"))),
		w: bufio.NewWriter(First(os.OpenFile("output.txt", os.O_CREATE|os.O_RDWR|os.O_TRUNC, os.ModePerm))),
	}
}

func (io *IO) ScanInt8() (x int8)   { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt16() (x int16) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt32() (x int32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanInt64() (x int64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanUInt8() (x uint8)   { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt16() (x uint16) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt32() (x uint32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanUInt64() (x uint64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanFloat32() (x float32) { fmt.Fscan(io.r, &x); return }
func (io *IO) ScanFloat64() (x float64) { fmt.Fscan(io.r, &x); return }

func (io *IO) ScanString() (x string) { fmt.Fscan(io.r, &x); return }

func (io *IO) Print(x ...any)   { fmt.Fprint(io.w, x...) }
func (io *IO) PrintLn(x ...any) { fmt.Fprintln(io.w, x...) }

func (io *IO) Flush() { io.w.Flush() }

// #endregion

// #region KEEP IMPORTS
func D() {
	_ = bufio.Reader{}
	_ = bytes.Buffer{}
	_ = suffixarray.Index{}
	_ = log.Default()
	_ = math.Abs(0)
	_ = net.Dialer{}
	_ = path.ErrBadPattern
	_ = sort.Float64sAreSorted(nil)
	_ = strconv.ErrRange
	_ = strings.Builder{}
	_ = time.ANSIC
	_ = newStdIO()
	_ = newFileIO()
}

// #endregion

package main

import (
	"bufio"
	"fmt"
	"os"
)

func min(a, b int) int {
	if a < b { return a }
	return b
}

type queue struct {
	sl []int
	top_index int
	bottom_index int
}

func (q *queue) pop() int {
	res := q.top()
	q.top_index++
	return res
}

func (q queue) top() int {
	return q.sl[q.top_index]
}

func (q *queue) push(v int) {
	q.bottom_index++
	q.sl[q.bottom_index] = v
}

func (q queue) is_empty() bool {
	return q.top_index > q.bottom_index
}

func main() {
	r := bufio.NewReader(os.Stdin)
	w := bufio.NewWriter(os.Stdout)
	defer w.Flush()

	var T int
	for fmt.Fscan(r, &T); T > 0; T-- {
		var n, m int
		fmt.Fscan(r, &n, &m)
		adj := make([][]int, n+1)
		masks := make([]int, n+1)

		for i := 0; i < m; i++ {
			var u, v int
			fmt.Fscan(r, &u, &v)
			adj[u] = append(adj[u], v)
			adj[v] = append(adj[v], u)
		}

		var f int
		fmt.Fscan(r, &f)
		house := make([]int, f+1)
		cars := make([]int, n+1)
		for i := 1; i <= f; i++ {
			fmt.Fscan(r, &house[i])
			cars[house[i]]++
		}

		var k int
		fmt.Fscan(r, &k)
		for i := 1; i <= k; i++ {
			var p int
			fmt.Fscan(r, &p)
			masks[house[p]] |= (1 << i)
			cars[house[p]]--
		}

		q := queue{make([]int, n+5), 0, -1}
		vis := make([]bool, n+1)

		vis[1] = true
		q.push(1)

		for !q.is_empty() {
			u := q.pop()
			for _, v := range(adj[u]) {
				if !vis[v] || cars[v] > 0 {
					vis[v] = true
					cars[v]--
					masks[v] |= masks[u]
					q.push(v)
				}
			}
		}

		/*
		fmt.Fprintln(w, "%%%%%%%%%%%%%%%")
		fmt.Fprintln(w, "*** masks ", masks)
		fmt.Fprintln(w, "*** house ", house)
		fmt.Fprintln(w, "*** cars ", cars)
		*/
		cnt := k
		for i := 1; i <= f; i++ {
			if cars[house[i]] < 0 { continue }
			rcnt := 0
			for j := 1; j <= k; j++ {
				if masks[house[i]] & (1 << j) == 0 {
					rcnt++
				}
			}
			cnt = min(cnt, rcnt)
		}

		fmt.Fprintln(w, cnt)

	}

}