import java.io.BufferedReader import java.io.InputStream import java.io.InputStreamReader import java.io.PrintWriter import java.lang.StringBuilder import java.util.* // region class Edge(val node:Int, val cost:Double) class State(val cost:Double, val position:Int, val prenode:Int) : Comparable { override fun compareTo(other: State): Int { return if (cost == other.cost) position.compareTo(other.position) else cost.compareTo(other.cost) } } fun dijkstra(adj: Array>, start: Int): Array { val n = adj.count() val dist = Array(n) { Double.MAX_VALUE } val preNodes = (0 until n).toMutableList() val heap = PriorityQueue() dist[start] = 0.0 heap.add(State(0.0, start, 0)) while (heap.count() > 0) { val state = heap.poll() val cost = state.cost val position = state.position val prenode = state.prenode if (cost > dist[position]) continue preNodes[position] = prenode for (edge in adj[position]) { val next = State(cost + edge.cost, edge.node, position) if (next.cost < dist[next.position]) { heap.add(next) dist[next.position] = next.cost } } } return dist } // endregion fun PrintWriter.solve(sc: FastScanner) { val n = sc.nextInt() val m = sc.nextInt() val x = sc.nextInt() - 1 val y = sc.nextInt() - 1 val pos = Array(n) { sc.nextInt() to sc.nextInt() } val adj = Array(n) { mutableListOf() } for (i in 0 until m) { val p = sc.nextInt() - 1 val q = sc.nextInt() - 1 val dx = pos[p].first - pos[q].first val dy = pos[p].second - pos[q].second val d = Math.sqrt((dx * dx + dy * dy).toDouble()) adj[p].add(Edge(q, d)) adj[q].add(Edge(p, d)) } val dist = dijkstra(adj, x) println(dist[y]) } fun main(args: Array) { val writer = PrintWriter(System.out, false) writer.solve(FastScanner(System.`in`)) writer.flush() } class FastScanner(s: InputStream) { private var st = StringTokenizer("") private val br = BufferedReader(InputStreamReader(s)) fun next(): String { while (!st.hasMoreTokens()) st = StringTokenizer(br.readLine()) return st.nextToken() } fun nextInt() = next().toInt() fun nextLong() = next().toLong() fun nextLine() = br.readLine() fun nextDouble() = next().toDouble() fun ready() = br.ready() }