Little girl Susie accidentally found her elder brother's notebook. She has many things to do, more important than solving problems, but she found this problem too interesting, so she wanted to know its solution and decided to ask you about it. So, the problem statement is as follows.

Let's assume that we are given a connected weighted undirected graph G = (V, E) (here V is the set of vertices, E is the set of edges). The shortest-path tree from vertex u is such graph G_1 = (V, E_1) that is a tree with the set of edges E_1 that is the subset of the set of edges of the initial graph E, and the lengths of the shortest paths from u to any vertex to G and to G_1 are the same. 

You are given a connected weighted undirected graph G and vertex u. Your task is to find the shortest-path tree of the given graph from vertex u, the total weight of whose edges is minimum possible.


-----Input-----

The first line contains two numbers, n and m (1 ≤ n ≤ 3·10^5, 0 ≤ m ≤ 3·10^5) — the number of vertices and edges of the graph, respectively.

Next m lines contain three integers each, representing an edge — u_{i}, v_{i}, w_{i} — the numbers of vertices connected by an edge and the weight of the edge (u_{i} ≠ v_{i}, 1 ≤ w_{i} ≤ 10^9). It is guaranteed that graph is connected and that there is no more than one edge between any pair of vertices.

The last line of the input contains integer u (1 ≤ u ≤ n) — the number of the start vertex.


-----Output-----

In the first line print the minimum total weight of the edges of the tree.

In the next line print the indices of the edges that are included in the tree, separated by spaces. The edges are numbered starting from 1 in the order they follow in the input. You may print the numbers of the edges in any order.

If there are multiple answers, print any of them.


-----Examples-----
Input
3 3
1 2 1
2 3 1
1 3 2
3

Output
2
1 2 

Input
4 4
1 2 1
2 3 1
3 4 1
4 1 2
4

Output
4
2 3 4 



-----Note-----

In the first sample there are two possible shortest path trees:

  with edges 1 – 3 and 2 – 3 (the total weight is 3);  with edges 1 – 2 and 2 – 3 (the total weight is 2); 

And, for example, a tree with edges 1 – 2 and 1 – 3 won't be a shortest path tree for vertex 3, because the distance from vertex 3 to vertex 2 in this tree equals 3, and in the original graph it is 1.

Difficulty: HARD
Tags: Greedy algorithms

Graph algorithms

Shortest paths
Skill types: Greedy algorithms

Starter code:

Solutions:
import heapq
(n, m) = list(map(int, input().split()))
g = [[] for _ in range(n + 1)]
for i in range(1, m + 1):
	(u, v, w) = list(map(int, input().split()))
	g[u].append((i, v, w))
	g[v].append((i, u, w))
src = int(input())
pq = [(0, 0, src, -1)]
mk = [0] * (n + 1)
t = []
s = 0
while pq:
	(d, w, u, e) = heapq.heappop(pq)
	if mk[u]:
		continue
	mk[u] = 1
	s += w
	t.append(e)
	for (e, v, w) in g[u]:
		if not mk[v]:
			heapq.heappush(pq, (d + w, w, v, e))
print(s)
print(*t[1:])


import heapq
(n, m) = list(map(int, input().split()))
g = [[] for i in range(n)]
for i in range(1, m + 1):
	(x, y, z) = list(map(int, input().split()))
	x -= 1
	y -= 1
	g[x].append((y, z, i))
	g[y].append((x, z, i))
v = int(input()) - 1
q = [(0, 0, v, 0)]
s = []
u = [0] * n
a = 0
while len(q):
	(d, l, x, e) = heapq.heappop(q)
	if not u[x]:
		u[x] = 1
		s.append(str(e))
		a += l
		for (i, k, f) in g[x]:
			if not u[i]:
				heapq.heappush(q, (d + k, k, i, f))
print(a)
print(' '.join(s[1:]))


import os
import sys
from io import BytesIO, IOBase
inf = float('inf')
from functools import cmp_to_key
from collections import defaultdict as dd
from collections import Counter, deque
from heapq import *
import math
from math import floor, ceil, sqrt

def geti():
	return map(int, input().strip().split())

def getl():
	return list(map(int, input().strip().split()))

def getis():
	return map(str, input().strip().split())

def getls():
	return list(map(str, input().strip().split()))

def gets():
	return input().strip()

def geta():
	return int(input())

def print_s(s):
	stdout.write(s + '\n')

def solve():
	(n, m) = geti()
	edges = dd(list)
	costs = dd(int)
	for i in range(m):
		(u, v, w) = geti()
		u -= 1
		v -= 1
		edges[u].append([w, v])
		edges[v].append([w, u])
		if u > v:
			(u, v) = (v, u)
		costs[u, v] = [w, i + 1]
	root = geta() - 1
	weight = []
	seen = set()
	mini = [inf] * n
	parent = [None] * n
	last = [inf] * n
	heappush(weight, [0, root, None])
	while weight:
		(cost, node, par) = heappop(weight)
		if node in seen:
			continue
		seen.add(node)
		mini[node] = cost
		for (price, child) in edges[node]:
			if mini[child] > mini[node] + price:
				mini[child] = mini[node] + price
				last[child] = price
				parent[child] = node
				heappush(weight, [mini[child], child, node])
			elif mini[child] == mini[node] + price and last[child] > price:
				last[child] = price
				parent[child] = node
	ans = []
	res = 0
	for i in range(n):
		if i == root:
			continue
		node = i
		par = parent[node]
		if par > node:
			(node, par) = (par, node)
		ans.append(costs[par, node][1])
		res += costs[par, node][0]
	print(res)
	print(*ans)
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
solve()


from collections import defaultdict, deque, Counter, OrderedDict
from heapq import heappop, heappush

def main():
	(n, m) = map(int, input().split())
	adj = [[] for i in range(n + 1)]
	for i in range(m):
		(a, b, c) = map(int, input().split())
		adj[a].append((b, c, i))
		adj[b].append((a, c, i))
	v = int(input())
	(visited, ans, tw) = ([0] * (n + 1), [], 0)
	Q = [(0, 0, v, 0)]
	while Q:
		(w, lew, u, ei) = heappop(Q)
		if visited[u]:
			continue
		visited[u] = 1
		ans.append(str(ei + 1))
		tw += lew
		for (to, we, eii) in adj[u]:
			if not visited[to]:
				heappush(Q, (we + w, we, to, eii))
	print(tw)
	print(' '.join(ans[1:]))
main()


import heapq
from sys import stdin
from math import inf
input = stdin.readline

def put():
	return map(int, input().split())

def dijkstra(u):
	q = [(0, 0, u - 1, 0)]
	vis = [False] * n
	ans = 0
	res = []
	while q:
		(_, k, i, f) = heapq.heappop(q)
		if vis[i]:
			continue
		vis[i] = True
		ans += k
		res.append(f)
		for (w, j, f) in graph[i]:
			if not vis[j]:
				heapq.heappush(q, (_ + w, w, j, f))
	print(ans)
	res = res[1:]
	print(*res)
(n, m) = put()
graph = [[] for _ in range(n)]
for _ in range(m):
	(x, y, z) = put()
	(x, y) = (x - 1, y - 1)
	graph[x].append((z, y, _ + 1))
	graph[y].append((z, x, _ + 1))
d = int(input())
dijkstra(d)


from collections import defaultdict, deque, Counter, OrderedDict
from heapq import heappop, heappush
import bisect, sys, threading

def main():
	(n, m) = map(int, input().split())
	adj = [[] for i in range(n + 1)]
	for i in range(m):
		(a, b, c) = map(int, input().split())
		adj[a].append((b, c, i))
		adj[b].append((a, c, i))
	v = int(input())
	(visited, ans, tw) = ([0] * (n + 1), [], 0)
	Q = [(0, 0, v, 0)]
	while Q:
		(w, lew, u, ei) = heappop(Q)
		if visited[u]:
			continue
		visited[u] = 1
		ans.append(str(ei + 1))
		tw += lew
		for (to, we, eii) in adj[u]:
			if not visited[to]:
				heappush(Q, (we + w, we, to, eii))
	print(tw)
	print(' '.join(ans[1:]))
sys.setrecursionlimit(200000)
threading.stack_size(102400000)
thread = threading.Thread(target=main)
thread.start()


import heapq, sys
input = sys.stdin.readline
(n, m) = list(map(int, input().split()))
ed = [(0, 0, 0)] + [tuple(map(int, input().split())) for _ in range(m)]
src = int(input())
g = [[] for _ in range(n + 1)]
for (i, (u, v, w)) in enumerate(ed):
	g[u].append((i, v, w))
	g[v].append((i, u, w))
pq = [(0, 0, src)]
dist = [(10 ** 15, 0)] * (n + 1)
up = [0] * (n + 1)
while pq:
	(d, e, u) = heapq.heappop(pq)
	if (d, e) > dist[u]:
		continue
	for (i, v, w) in g[u]:
		if (d + w, w) < dist[v]:
			dist[v] = (d + w, w)
			up[v] = i
			heapq.heappush(pq, (d + w, w, v))
t = [up[u] for u in range(1, n + 1) if u != src]
print(sum((ed[e][2] for e in t)))
print(*t)


import heapq
from collections import defaultdict
from sys import stdin, stdout
input = stdin.readline
print = stdout.write

def SPT(adjacency_list, src, v):
	heap = [[0, 0, src, 0]]
	visited = [False] * (n + 1)
	spt = []
	total = 0
	while heap:
		(first_dist, weight, vertex, edge_num) = heapq.heappop(heap)
		if not visited[vertex]:
			spt.append(edge_num)
			total += weight
			visited[vertex] = True
			for (_vertex, _weight, _edgenum) in adjacency_list[vertex]:
				if not visited[_vertex]:
					heapq.heappush(heap, [first_dist + _weight, _weight, _vertex, _edgenum])
	return (spt, total)
(n, m) = map(int, input().split())
d = defaultdict(list)
for i in range(1, m + 1):
	(a, b, w) = map(int, input().split())
	d[a].append([b, w, i])
	d[b].append([a, w, i])
src = int(input())
x = SPT(d, src, n)
print(str(x[1]) + '\n')
x = map(str, x[0][1:])
print(' '.join(x))


from sys import stdin
_data = map(int, stdin.read().split())
from heapq import heappush, heappop
(n, m) = (next(_data), next(_data))
g = [[] for _ in range(n)]
h = [[] for _ in range(n)]
for i in range(m):
	(u, v, w) = (next(_data) - 1, next(_data) - 1, next(_data))
	g[u].append((w, v, i))
	g[v].append((w, u, i))
s = next(_data) - 1
d = [1 << 60] * n
pq = []
heappush(pq, (0, s))
d[s] = 0
while pq:
	(c, v) = heappop(pq)
	if c > d[v]:
		continue
	for e in g[v]:
		(w, u, _) = e
		if d[u] > d[v] + w:
			d[u] = d[v] + w
			heappush(pq, (d[u], u))
			del h[u][:]
		if d[u] == d[v] + w:
			h[u].append(e)
cost = 0
ans = []
for v in range(n):
	if v == s:
		continue
	(w, _, i) = min(h[v])
	cost += w
	ans.append(i + 1)
print(cost)
print(' '.join(map(str, ans)))


import math, string, itertools, fractions, heapq, collections, re, array, bisect
from itertools import chain, dropwhile, permutations, combinations
from collections import defaultdict

def VI():
	return list(map(int, input().split()))

def I():
	return int(input())

def LIST(n, m=None):
	return [0] * n if m is None else [[0] * m for i in range(n)]

def ELIST(n):
	return [[] for i in range(n)]

def MI(n=None, m=None):
	if n is None:
		(n, m) = VI()
	arr = LIST(n)
	for i in range(n):
		arr[i] = VI()
	return arr

def MS(n=None, m=None):
	if n is None:
		(n, m) = VI()
	arr = LIST(n)
	for i in range(n):
		arr[i] = input()
	return arr

def MIT(n=None, m=None):
	if n is None:
		(n, m) = VI()
	arr = LIST(m, n)
	for i in range(n):
		v = VI()
		for j in range(m):
			arr[j][i] = v[j]
	return arr

def run2(n, m, u, v, w, x):
	g = ELIST(n + 1)
	for i in range(m):
		g[u[i]].append((v[i], w[i], i + 1))
		g[v[i]].append((u[i], w[i], i + 1))
	pq = []
	marked = [False] * (n + 1)
	pq.append((0, 0, x, 0))
	sg = []
	wmax = -w[-1]
	while len(pq) != 0:
		(wi, lw, i, ei) = heapq.heappop(pq)
		if not marked[i]:
			marked[i] = True
			sg.append(ei)
			wmax += w[ei - 1]
			for (j, wj, ej) in g[i]:
				if not marked[j]:
					heapq.heappush(pq, (wi + wj, wj, j, ej))
	sg = sg[1:]
	print(wmax)
	for i in sg:
		print(i, end=' ')
	print()

def main2(info=0):
	(n, m) = VI()
	(u, v, w) = MIT(m, 3)
	x = I()
	run(n, m, u, v, w, x)

def run(n, m, g, x):
	pq = [(0, 0, x, 0)]
	marked = [False] * (n + 1)
	sg = []
	wtot = 0
	while len(pq) != 0:
		(wi, lw, i, ei) = heapq.heappop(pq)
		if not marked[i]:
			marked[i] = True
			sg.append(str(ei))
			wtot += lw
			for (j, wj, ej) in g[i]:
				if not marked[j]:
					heapq.heappush(pq, (wi + wj, wj, j, ej))
	print(wtot)
	print(' '.join(sg[1:]))

def main(info=0):
	(n, m) = VI()
	g = ELIST(n + 1)
	for i in range(m):
		(u, v, w) = VI()
		g[u].append((v, w, i + 1))
		g[v].append((u, w, i + 1))
	x = I()
	run(n, m, g, x)

def __starting_point():
	main()
__starting_point()


from sys import stdin
from heapq import heappop, heappush
(n, m) = [int(x) for x in stdin.readline().split()]
graph = [{} for x in range(n + 1)]
for e in range(m):
	(u, v, w) = [int(x) for x in stdin.readline().split()]
	graph[u][v] = (w, e)
	graph[v][u] = (w, e)
u = int(stdin.readline())
visited = set()
dist = [(float('inf'), 0) for x in range(n + 1)]
pathTo = [0 for x in range(n + 1)]
dist[u] = (0, 0)
q = []
heappush(q, (0, u))
while q:
	(d, v) = heappop(q)
	if not v in visited:
		visited.add(v)
		for e in graph[v]:
			if (d + graph[v][e][0], graph[v][e][0]) < dist[e]:
				dist[e] = (d + graph[v][e][0], graph[v][e][0])
				pathTo[e] = graph[v][e][1]
				heappush(q, (d + graph[v][e][0], e))
total = 0
for x in dist[1:]:
	total += x[1]
print(total)
for x in range(1, n + 1):
	if x != u:
		print(pathTo[x] + 1, end=' ')