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')
}