← Home
package main

import (
	"bufio"
	"io"
	"math/bits"
	"os"
	"sort"
	"strconv"
)

type Pair struct {
	sum  int64
	cost int64
}

const INF int64 = 1 << 60

func mulMatrix(a, b [][]int64, n int) [][]int64 {
	res := make([][]int64, n)
	for i := 0; i < n; i++ {
		res[i] = make([]int64, n)
		for j := 0; j < n; j++ {
			res[i][j] = INF
		}
	}
	for i := 0; i < n; i++ {
		ri := res[i]
		for k := 0; k < n; k++ {
			av := a[i][k]
			if av >= INF {
				continue
			}
			bk := b[k]
			for j := 0; j < n; j++ {
				bv := bk[j]
				if bv >= INF {
					continue
				}
				v := av + bv
				if v < ri[j] {
					ri[j] = v
				}
			}
		}
	}
	return res
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	p := 0
	nextInt := func() int64 {
		for p < len(data) && data[p] <= ' ' {
			p++
		}
		sign := int64(1)
		if data[p] == '-' {
			sign = -1
			p++
		}
		var x int64
		for p < len(data) && data[p] > ' ' {
			x = x*10 + int64(data[p]-'0')
			p++
		}
		return x * sign
	}

	n := int(nextInt())
	m := int(nextInt())
	q := int(nextInt())
	s := int(nextInt()) - 1

	a := make([]int64, n)
	for i := 0; i < n; i++ {
		a[i] = nextInt()
	}

	adj := make([][]int, n)
	inAdj := make([][]int, n)
	for i := 0; i < m; i++ {
		v := int(nextInt()) - 1
		u := int(nextInt()) - 1
		adj[v] = append(adj[v], u)
		inAdj[u] = append(inAdj[u], v)
	}

	queries := make([]int64, q)
	var maxC int64
	for i := 0; i < q; i++ {
		queries[i] = nextInt()
		if queries[i] > maxC {
			maxC = queries[i]
		}
	}

	sizeMask := 1 << n
	allMask := sizeMask - 1
	totalStates := sizeMask * n

	sumMask := make([]int64, sizeMask)
	for mask := 1; mask < sizeMask; mask++ {
		lsb := mask & -mask
		b := bits.TrailingZeros(uint(lsb))
		sumMask[mask] = sumMask[mask^lsb] + a[b]
	}
	A := sumMask[allMask]

	maskOf := make([]int, totalStates)
	nodeOf := make([]int, totalStates)
	for mask := 0; mask < sizeMask; mask++ {
		base := mask * n
		for v := 0; v < n; v++ {
			idx := base + v
			maskOf[idx] = mask
			nodeOf[idx] = v
		}
	}

	M := make([][]int64, n)
	partSums := make([][]int64, n)
	partSuf := make([][]int64, n)

	queue := make([]int, totalStates)
	distState := make([]int32, totalStates)
	bestMask := make([]int32, sizeMask)

	for st := 0; st < n; st++ {
		for i := 0; i < totalStates; i++ {
			distState[i] = -1
		}
		for i := 0; i < sizeMask; i++ {
			bestMask[i] = -1
		}

		startMask := 1 << st
		startIdx := startMask*n + st
		distState[startIdx] = 0

		head, tail := 0, 0
		queue[tail] = startIdx
		tail++

		for head < tail {
			idx := queue[head]
			head++
			d := distState[idx]
			mask := maskOf[idx]
			if bestMask[mask] == -1 || d < bestMask[mask] {
				bestMask[mask] = d
			}
			v := nodeOf[idx]
			nd := d + 1
			for _, u := range adj[v] {
				nmask := mask | (1 << u)
				nidx := nmask*n + u
				if distState[nidx] == -1 {
					distState[nidx] = nd
					queue[tail] = nidx
					tail++
				}
			}
		}

		row := make([]int64, n)
		for j := 0; j < n; j++ {
			needMask := allMask ^ (1 << j)
			base := needMask * n
			best := INF
			for _, v := range inAdj[j] {
				d := distState[base+v]
				if d >= 0 {
					cand := int64(d) + 1
					if cand < best {
						best = cand
					}
				}
			}
			row[j] = best
		}
		M[st] = row

		pairs := make([]Pair, 0, sizeMask)
		for mask := 0; mask < sizeMask; mask++ {
			d := bestMask[mask]
			if d >= 0 {
				pairs = append(pairs, Pair{sumMask[mask], int64(d)})
			}
		}

		sort.Slice(pairs, func(i, j int) bool {
			if pairs[i].sum == pairs[j].sum {
				return pairs[i].cost < pairs[j].cost
			}
			return pairs[i].sum < pairs[j].sum
		})

		sums := make([]int64, 0, len(pairs))
		costs := make([]int64, 0, len(pairs))
		for _, pr := range pairs {
			if len(sums) > 0 && sums[len(sums)-1] == pr.sum {
				if pr.cost < costs[len(costs)-1] {
					costs[len(costs)-1] = pr.cost
				}
			} else {
				sums = append(sums, pr.sum)
				costs = append(costs, pr.cost)
			}
		}

		suf := make([]int64, len(costs))
		for i := len(costs) - 1; i >= 0; i-- {
			if i == len(costs)-1 || costs[i] < suf[i+1] {
				suf[i] = costs[i]
			} else {
				suf[i] = suf[i+1]
			}
		}

		partSums[st] = sums
		partSuf[st] = suf
	}

	var maxT int64
	for i := 0; i < q; i++ {
		t := (queries[i] - 1) / A
		if t > maxT {
			maxT = t
		}
	}

	maxPow := 1
	for (int64(1) << uint(maxPow)) <= maxT {
		maxPow++
	}

	powers := make([][][]int64, maxPow)
	powers[0] = make([][]int64, n)
	for i := 0; i < n; i++ {
		powers[0][i] = append([]int64(nil), M[i]...)
	}
	for i := 1; i < maxPow; i++ {
		powers[i] = mulMatrix(powers[i-1], powers[i-1], n)
	}

	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	for _, C := range queries {
		t := (C - 1) / A
		need := C - t*A

		cur := make([]int64, n)
		tmp := make([]int64, n)
		for i := 0; i < n; i++ {
			cur[i] = INF
			tmp[i] = INF
		}
		cur[s] = 0

		bit := 0
		for tt := t; tt > 0; tt >>= 1 {
			if tt&1 == 1 {
				for j := 0; j < n; j++ {
					tmp[j] = INF
				}
				mat := powers[bit]
				for i := 0; i < n; i++ {
					if cur[i] >= INF {
						continue
					}
					ci := cur[i]
					row := mat[i]
					for j := 0; j < n; j++ {
						if row[j] >= INF {
							continue
						}
						v := ci + row[j]
						if v < tmp[j] {
							tmp[j] = v
						}
					}
				}
				cur, tmp = tmp, cur
			}
			bit++
		}

		ans := INF
		for j := 0; j < n; j++ {
			if cur[j] >= INF {
				continue
			}
			sums := partSums[j]
			suf := partSuf[j]
			l, r := 0, len(sums)
			for l < r {
				mid := (l + r) >> 1
				if sums[mid] >= need {
					r = mid
				} else {
					l = mid + 1
				}
			}
			v := cur[j] + suf[l]
			if v < ans {
				ans = v
			}
		}

		out.WriteString(strconv.FormatInt(ans, 10))
		out.WriteByte('\n')
	}
	out.Flush()
}