← Home
```go
package main

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

const chunks = 16 // 1000 bits fit in 16 uint64s

type Bitset [chunks]uint64

func (b *Bitset) SetBit(pos int) {
	b[pos/64] |= (1 << uint(pos%64))
}

func (b *Bitset) TestBit(pos int) bool {
	return (b[pos/64] & (1 << uint(pos%64))) != 0
}

func (b *Bitset) Xor(other *Bitset) {
	for i := 0; i < chunks; i++ {
		b[i] ^= other[i]
	}
}

func (b *Bitset) IsZero() bool {
	for i := 0; i < chunks; i++ {
		if b[i] != 0 {
			return false
		}
	}
	return true
}

var scanner *bufio.Scanner

func scanInt() int {
	scanner.Scan()
	bytes := scanner.Bytes()
	x := 0
	for _, b := range bytes {
		x = x*10 + int(b-'0')
	}
	return x
}

func main() {
	scanner = bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	// Read N, S, D
	if !scanner.Scan() {
		return
	}
	// We skip parsing N as it's not strictly needed for logic beyond array sizing
	
	S := scanInt()
	D := scanInt()

	switches := make([]Bitset, S)
	for i := 0; i < S; i++ {
		c := scanInt()
		for j := 0; j < c; j++ {
			idx := scanInt()
			switches[i].SetBit(idx - 1)
		}
	}

	// Gaussian Elimination to find basis and pivot columns
	mat := make([]Bitset, S)
	copy(mat, switches)

	pivots := make([]int, 0, S)
	basisRows := make([]Bitset, 0, S)

	row := 0
	col := 0
	// max cols is 1000
	for col < 1000 && row < S {
		sel := -1
		for r := row; r < S; r++ {
			if mat[r].TestBit(col) {
				sel = r
				break
			}
		}
		if sel == -1 {
			col++
			continue
		}

		mat[row], mat[sel] = mat[sel], mat[row]

		for r := 0; r < S; r++ {
			if r != row && mat[r].TestBit(col) {
				mat[r].Xor(&mat[row])
			}
		}
		pivots = append(pivots, col)
		basisRows = append(basisRows, mat[row])
		row++
		col++
	}

	// Function to compress a bitset into a uint32 based on pivot columns
	compress := func(b *Bitset) uint32 {
		var res uint32
		for i, p := range pivots {
			if b.TestBit(p) {
				res |= (1 << i)
			}
		}
		return res
	}

	// Meet-in-the-middle
	half := S / 2
	part1 := switches[:half]
	part2 := switches[half:]

	cPart1 := make([]uint32, len(part1))
	for i := range part1 {
		cPart1[i] = compress(&part1[i])
	}
	cPart2 := make([]uint32, len(part2))
	for i := range part2 {
		cPart2[i] = compress(&part2[i])
	}

	minSteps := make(map[uint32]int)
	
	var gen1 func(int, uint32, int)
	gen1 = func(idx int, mask uint32, cnt int) {
		if idx == len(part1) {
			if v, ok := minSteps[mask]; !ok || cnt < v {
				minSteps[mask] = cnt
			}
			return
		}
		gen1(idx+1, mask, cnt)
		gen1(idx+1, mask^cPart1[idx], cnt+1)
	}
	gen1(0, 0, 0)

	type Pair struct {
		mask uint32
		cnt  int
	}
	list2 := make([]Pair, 0, 1<<uint(len(part2)))
	var gen2 func(int, uint32, int)
	gen2 = func(idx int, mask uint32, cnt int) {
		if idx == len(part2) {
			list2 = append(list2, Pair{mask, cnt})
			return
		}
		gen2(idx+1, mask, cnt)
		gen2(idx+1, mask^cPart2[idx], cnt+1)
	}
	gen2(0, 0, 0)

	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	for i := 0; i < D; i++ {
		k := scanInt()
		var target Bitset
		for j := 0; j < k; j++ {
			idx := scanInt()
			target.SetBit(idx - 1)
		}

		// Check if target is in the span of switches using basis
		tempT := target
		for j := 0; j < len(basisRows); j++ {
			if tempT.TestBit(pivots[j]) {
				tempT.Xor(&basisRows[j])
			}
		}

		if !tempT.IsZero() {
			fmt.Fprintln(out, -1)
			continue
		}

		tMask := compress(&target)
		best := -1

		for _, p := range list2 {
			needed := tMask ^ p.mask
			if v, ok := minSteps[needed]; ok {
				tot := v + p.cnt
				if best == -1 || tot < best {
					best = tot
				}
			}
		}
		fmt.Fprintln(out, best)
	}
}
```