import java.util.*; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int N = in.nextInt(); int M = in.nextInt(); int S = in.nextInt(); int G = in.nextInt(); Dijkstra d = new Dijkstra(N); for( int i = 0; i < M; i++ ) { int a = in.nextInt(); int b = in.nextInt(); int c = in.nextInt(); d.addEdge(a,b,c); d.addEdge(b,a,c); } int[] dist = d.run(S); ArrayList> g = new ArrayList>(); for( int i = 0; i < N; i++ ) { ArrayList es = new ArrayList(); for( Edge e : d.g.get(i) ) { if( dist[e.from] + e.weight == dist[e.to] ) { es.add(e); } } g.add(es); } int v = S; while( v != G ) { System.out.print(v + " "); ArrayList es = g.get(v); v = N; for( Edge e : es ) { if( !reachable(g,e.to,G) ) continue; v = Math.min(v, e.to); } } System.out.println(v); } static boolean reachable(ArrayList> g, int s, int t){ boolean[] vis = new boolean[g.size()]; Deque stack = new ArrayDeque(); stack.push(s); while(!stack.isEmpty()) { int v = stack.pop(); if( v == t ) return true; if( vis[v] ) continue; vis[v] = true; for( Edge e : g.get(v) ) { stack.push(e.to); } } return false; } } class Edge implements Comparable{ int from; int to; int weight; public Edge(int from, int to, int weight) { this.from = from; this.to = to; this.weight = weight; } public int compareTo(Edge e) { if( this.weight < e.weight ) return -1; if( this.weight > e.weight ) return 1; if( this.from < e.from ) return -1; if( this.from > e.from ) return 1; if( this.to < e.to ) return -1; if( this.to > e.to ) return 1; return 0; } } class Dijkstra { int N; ArrayList> g; public Dijkstra(int N) { this.N = N; g = new ArrayList>(); for( int i = 0; i < N; i++ ) { g.add(new ArrayList()); } } public void addEdge(Edge e) { g.get(e.from).add(e); } public void addEdge(int from, int to, int weight) { addEdge(new Edge(from, to, weight)); } public int[] run(int start) { boolean[] vis = new boolean[N]; int[] dist = new int[N]; PriorityQueue queue = new PriorityQueue(); queue.add(new Edge(start,0,0)); while( !queue.isEmpty() ) { Edge e = queue.poll(); if( vis[e.from] ) continue; vis[e.from] = true; dist[e.from] = e.weight; for( Edge ne : g.get(e.from) ) { if( !vis[ne.to] ) { queue.add(new Edge(ne.to,0,ne.weight + e.weight)); } } } return dist; } }