← Home
package main

import (
	"bufio"
	"io"
	"os"
	"strconv"
)

type Edge struct {
	to int
	w  int
}

const INF = int(1e9)

func dijkstra(src int, adj [][]Edge, v int) []int {
	dist := make([]int, v)
	used := make([]bool, v)
	for i := 0; i < v; i++ {
		dist[i] = INF
	}
	dist[src] = 0
	for {
		x := -1
		best := INF
		for i := 0; i < v; i++ {
			if !used[i] && dist[i] < best {
				best = dist[i]
				x = i
			}
		}
		if x == -1 {
			break
		}
		used[x] = true
		dx := dist[x]
		for _, e := range adj[x] {
			nd := dx + e.w
			if nd < dist[e.to] {
				dist[e.to] = nd
			}
		}
	}
	return dist
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	idx := 0
	nextInt := func() int {
		for idx < len(data) && (data[idx] < '0' || data[idx] > '9') {
			idx++
		}
		n := 0
		for idx < len(data) && data[idx] >= '0' && data[idx] <= '9' {
			n = n*10 + int(data[idx]-'0')
			idx++
		}
		return n
	}

	V := nextInt()
	E := nextInt()
	N := nextInt()
	K := nextInt()

	startMap := make(map[int]int)
	teamToUnique := make([]int, N)
	uniqueStarts := make([]int, 0)

	for i := 0; i < N; i++ {
		s := nextInt() - 1
		if id, ok := startMap[s]; ok {
			teamToUnique[i] = id
		} else {
			id := len(uniqueStarts)
			startMap[s] = id
			uniqueStarts = append(uniqueStarts, s)
			teamToUnique[i] = id
		}
	}

	adj := make([][]Edge, V)
	for i := 0; i < E; i++ {
		a := nextInt() - 1
		b := nextInt() - 1
		t := nextInt()
		adj[a] = append(adj[a], Edge{b, t})
		adj[b] = append(adj[b], Edge{a, t})
	}

	uniqueDists := make([][]int, len(uniqueStarts))
	maxDist := 0
	for i, s := range uniqueStarts {
		d := dijkstra(s, adj, V)
		uniqueDists[i] = d
		for _, x := range d {
			if x < INF && x > maxDist {
				maxDist = x
			}
		}
	}

	teamDists := make([][]int, N)
	for i := 0; i < N; i++ {
		teamDists[i] = uniqueDists[teamToUnique[i]]
	}

	adjU := make([][]int, N)
	for i := 0; i < N; i++ {
		adjU[i] = make([]int, 0, V)
	}

	feasible := func(T int) bool {
		for i := 0; i < N; i++ {
			a := adjU[i][:0]
			d := teamDists[i]
			for c := 0; c < V; c++ {
				if d[c] <= T {
					a = append(a, c)
				}
			}
			adjU[i] = a
		}

		pairU := make([]int, N)
		for i := 0; i < N; i++ {
			pairU[i] = -1
		}
		pairV := make([]int, V)
		for i := 0; i < V; i++ {
			pairV[i] = -1
		}
		level := make([]int, N)

		bfs := func() bool {
			q := make([]int, N)
			head, tail := 0, 0
			for u := 0; u < N; u++ {
				if pairU[u] == -1 {
					level[u] = 0
					q[tail] = u
					tail++
				} else {
					level[u] = -1
				}
			}
			found := false
			for head < tail {
				u := q[head]
				head++
				for _, v := range adjU[u] {
					pu := pairV[v]
					if pu == -1 {
						found = true
					} else if level[pu] == -1 {
						level[pu] = level[u] + 1
						q[tail] = pu
						tail++
					}
				}
			}
			return found
		}

		var dfs func(int) bool
		dfs = func(u int) bool {
			for _, v := range adjU[u] {
				pu := pairV[v]
				if pu == -1 || (level[pu] == level[u]+1 && dfs(pu)) {
					pairU[u] = v
					pairV[v] = u
					return true
				}
			}
			level[u] = -1
			return false
		}

		matched := 0
		for bfs() {
			for u := 0; u < N; u++ {
				if pairU[u] == -1 && dfs(u) {
					matched++
					if matched >= K {
						return true
					}
				}
			}
		}
		return false
	}

	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	defer out.Flush()

	if !feasible(maxDist) {
		out.WriteString("-1\n")
		return
	}

	low, high := -1, maxDist
	for high-low > 1 {
		mid := (low + high) / 2
		if feasible(mid) {
			high = mid
		} else {
			low = mid
		}
	}

	out.WriteString(strconv.Itoa(high))
	out.WriteByte('\n')
}