← Home
```go
package main

import (
	"bufio"
	"container/heap"
	"os"
	"sort"
	"strconv"
)

// Configure fast I/O
var scanner *bufio.Scanner

func init() {
	scanner = bufio.NewScanner(os.Stdin)
	// Increase buffer size to handle large inputs
	scanner.Buffer(make([]byte, 1024*1024), 20*1024*1024)
	scanner.Split(bufio.ScanWords)
}

func readInt() int {
	scanner.Scan()
	x, _ := strconv.Atoi(scanner.Text())
	return x
}

// Priority Queue Implementation for Dijkstra
type Item struct {
	u, d int // u: city node, d: time step index
}

type PriorityQueue []Item

func (pq PriorityQueue) Len() int { return len(pq) }
func (pq PriorityQueue) Less(i, j int) bool {
	return pq[i].d < pq[j].d
}
func (pq PriorityQueue) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
}
func (pq *PriorityQueue) Push(x interface{}) {
	*pq = append(*pq, x.(Item))
}
func (pq *PriorityQueue) Pop() interface{} {
	old := *pq
	n := len(old)
	item := old[n-1]
	*pq = old[0 : n-1]
	return item
}

type Edge struct {
	to, id int
}

func main() {
	n := readInt()
	t := readInt()

	// Adjacency list: adj[u] contains list of Edges connected to u.
	// Edge contains the neighbor 'to' and the record 'id' (time config).
	adj := make([][]Edge, n+1)

	for i := 1; i <= t; i++ {
		m := readInt()
		for j := 0; j < m; j++ {
			u := readInt()
			v := readInt()
			adj[u] = append(adj[u], Edge{v, i})
			adj[v] = append(adj[v], Edge{u, i})
		}
	}

	k := readInt()
	// occ[id] stores the sorted list of time indices (steps) where record 'id' is active.
	occ := make([][]int, t+1)
	for i := 1; i <= k; i++ {
		val := readInt()
		occ[val] = append(occ[val], i)
	}

	// Dijkstra's Algorithm
	// dist[u] stores the minimum time step index to reach city u.
	dist := make([]int, n+1)
	for i := range dist {
		dist[i] = -1 // -1 represents infinity
	}

	pq := &PriorityQueue{}
	heap.Init(pq)

	dist[1] = 0
	heap.Push(pq, Item{1, 0})

	for pq.Len() > 0 {
		item := heap.Pop(pq).(Item)
		u := item.u
		d := item.d

		// If we found a shorter path to u before, skip
		if dist[u] != -1 && d > dist[u] {
			continue
		}

		// If we reached the target city n
		if u == n {
			os.Stdout.WriteString(strconv.Itoa(d) + "\n")
			return
		}

		// Explore neighbors
		for _, e := range adj[u] {
			v := e.to
			recID := e.id

			// Find the earliest occurrence of record recID after current time step d
			list := occ[recID]
			// We need the smallest index in list such that list[idx] > d
			idx := sort.Search(len(list), func(i int) bool {
				return list[i] > d
			})

			if idx < len(list) {
				nextTime := list[idx]
				// If this path improves the arrival time at v
				if dist[v] == -1 || nextTime < dist[v] {
					dist[v] = nextTime
					heap.Push(pq, Item{v, nextTime})
				}
			}
		}
	}

	// If n is not reachable
	os.Stdout.WriteString("-1\n")
}
```