# 0575.rb by kyuridenamida (2013/08/10)

# Constant value
INF = 1000000000

# Edge structure
class Edge
	def initialize(src,dst,cost)
		@src = src
		@dst = dst
		@cost = cost
	end
	def <(another)
		@cost < another.cost
	end
	def <=>(another)
		if @cost < another.cost
			return -1
		end
		if @cost > another.cost
			return 1
		end
		if @cost = another.cost
			return 0
		end
	end
	
	attr_accessor :src, :dst, :cost
end

# SkewHeap for Priority-Queue
class Heap
	class Node
		def initialize(value)
			@left=nil
			@right=nil
			@value=value
		end
		attr_accessor :value,:right,:left
	end
	
	def initialize()
		@size = 0
		@root = nil
	end

	def meld a,b
		if a == nil
			return b
		end
		if( b == nil )
			return a
		end
		if b.value < a.value 
			a,b=b,a
		end
		a.right = meld(a.right,b)
		a.left,a.right=a.right,a.left
		return a
	end
	
	def top
		@root.value
	end
	
	def pop
		@size -= 1
		@root=meld(@root.left,@root.right)
	end

	def push x
		@size += 1
		@root=meld(@root,Node.new(x))
	end
	attr_accessor :size
end

# UnionFind
def root x
	return $ufdata[x] < 0 ? x : ($ufdata[x]=root($ufdata[x]))
end

def merge x,y
	x = root(x)
	y = root(y)
	if x != y
		if $ufdata[y] < $ufdata[x]
			x,y=y,x
		end
		$ufdata[x] += $ufdata[y]
		
		$ufdata[y] = x
	end
	return x != y
end


# Main
ObjectSpace.garbage_collect

n,m,k,qu=gets.split.map(&:to_i)
g = Array.new(n).map!{Array.new}
$ufdata = Array.new(n,-1)
edgarr = []

m.times{
	a,b,c=gets.split.map(&:to_i)
	a-=1
	b-=1
	g[a].push(Edge.new(a,b,c))
	g[b].push(Edge.new(b,a,c))
	edgarr.push(Edge.new(a,b,c))
}


# Dijkstra Part

que = Heap.new()
dijkCost = Array.new(n,INF)
k.times{
	t=gets.to_i
	t-=1
	#puts k
	que.push(Edge.new(t,-1,0))
	dijkCost[t] = 0
}

while que.size != 0
	
	q = que.top()
	que.pop()
	if dijkCost[q.src] != q.cost
		next
	end
	#puts "#{q.src} = #{q.cost}"
	
	g[q.src].each{|e|
		if dijkCost[q.src]+e.cost < dijkCost[e.dst]
			dijkCost[e.dst] = dijkCost[q.src]+e.cost
			que.push(Edge.new(e.dst,-1,dijkCost[e.dst]))
		end
	}
end
ObjectSpace.garbage_collect

# UFtree-Construction Part
edgarr.each{|e|
	e.cost = [dijkCost[e.src],dijkCost[e.dst]].min
}
edgarr.sort!
edgarr.reverse!

uftree = Array.new(n).map!{Array.new}

edgarr.each{|e|
	if merge(e.src,e.dst)
		#puts e.src,e.dst,""
		
		uftree[e.src].push(Edge.new(e.src,e.dst,e.cost))
		uftree[e.dst].push(Edge.new(e.dst,e.src,e.cost))
	end
}

# Getting Tree infomartion Part(ex. depth, parent)

stack = []

$parent = Array.new(n).map!{Array.new(17,-1)}
$costlca = Array.new(n).map!{Array.new(17,INF)}
$depth  = Array.new(n,-1)
done = Array.new(n,false)
stack.push(0)
done[0]=true
$depth[0] = 0
while stack.size() != 0 
	q = stack[-1]
	stack.pop
	uftree[q].each{|e|
		if !done[e.dst] 
			$parent[e.dst][0] = q
			$depth[e.dst] = $depth[q]+1
			done[e.dst] = true
			stack.push(e.dst)
		end
	}
end

ObjectSpace.garbage_collect

# Construction LCA Part

n.times{|i|
	#puts $parent[i][0]
	if $parent[i][0] != -1
		$costlca[i][0] = [dijkCost[i],dijkCost[$parent[i][0]]].min
	end
}

1.upto(16){|j|
	n.times{|i|
		if $parent[i][j-1] != -1 
			$parent[i][j] = $parent[$parent[i][j-1]][j-1]
			$costlca[i][j] = [$costlca[i][j-1],$costlca[$parent[i][j-1]][j-1]].min
			
		end
	}
}

# Answer to Queries
qu.times{
	u,v=gets.split.map(&:to_i)
	u-=1
	v-=1
	if $depth[u] < $depth[v]
		u,v=v,u
	end
	diff=$depth[u]-$depth[v]
	ans = [dijkCost[u],dijkCost[v]].min
	17.times{|i|
		if (diff>>i&1) != 0
			ans = [ans,$costlca[u][i]].min
			u = $parent[u][i]
		end
	}
	if u == v
		puts ans
		next
	end
	16.downto(0){|i|
		if $parent[u][i] != $parent[v][i]
			ans = [ans,$costlca[u][i]].min
			ans = [ans,$costlca[v][i]].min
			u = $parent[u][i]
			v = $parent[v][i]
		end
	}
	ans = [ans,$costlca[u][0]].min
	ans = [ans,$costlca[v][0]].min
	puts ans
}

Measured memory_bytes: 313192