import java.io.*;
import java.util.*;
import java.text.*;

class Reinier_repeated_dijkstra {
	static Scanner sc;

	static ArrayList<ArrayList<Integer>> adj, adj2;
	static long[][] d;

	static void run() {
		int n = sc.nextInt();
		int m = sc.nextInt();
		int c = sc.nextInt() - 1;
		int r = sc.nextInt() - 1;
		
		adj = new ArrayList<>();
		for (int i = 0; i < n; i++) {
			adj.add(new ArrayList<>());
		}
		d = new long[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				d[i][j] = -1;
			}
		}

		// Read input
		long[][] d2 = new long[n][n];
		for (int i = 0; i < m; i++) {
			int a = sc.nextInt() - 1;
			int b = sc.nextInt() - 1;
			long l = sc.nextLong();
			d2[a][b] = l;
			d2[b][a] = l;
			adj.get(a).add(b);
			adj.get(b).add(a);
		}

		// APSP
		for (int i = 0; i < n; i++) {
			PriorityQueue<DV> Q = new PriorityQueue<>();
			d[i][i] = 0;
			Q.add(new DV(0, i));
			while (!Q.isEmpty()) {
				DV dv = Q.poll();
				if (d[i][dv.v] < dv.d) continue;
				for (int w : adj.get(dv.v)) {
					if (d[i][w] < 0 || dv.d + d2[dv.v][w] < d[i][w]) {
						d[i][w] = dv.d + d2[dv.v][w];
						Q.add(new DV(dv.d + d2[dv.v][w], w));
					}
				}
			}
		}

		// Compute new graph
		adj2 = new ArrayList<>();
		for (int i = 0; i < n; i++) {
			adj2.add(new ArrayList<>());
		}
		for (int i = 0; i < n; i++) {
			if (adj.get(i).size() <= 1) continue;
			long maxDist = 0;
			for (int j = 0; j < n; j++) {
				if (d[i][j] == maxDist) {
					adj2.get(i).add(j);
				} else if (d[i][j] > maxDist) {
					adj2.set(i, new ArrayList<>());
					adj2.get(i).add(j);
					maxDist = d[i][j];
				}
			}
		}

		// Perform first approach
		int approachDirection = -1;
		for (int i : adj.get(r)) {
			if (d[c][r] == d[c][i] + d[i][r]) {
				approachDirection = i;
			}
		}
		boolean[] reachable = new boolean[n];
		getReachable(r, approachDirection, reachable);
		ArrayList<Integer> posDest = new ArrayList<>();
		long maxDist = 0;
		for (int i = 0; i < n; i++) {
			if (reachable[i] && d[r][i] == maxDist) {
				posDest.add(i);
			} else if (reachable[i] && d[r][i] > maxDist) {
				posDest = new ArrayList<>();
				posDest.add(i);
				maxDist = d[r][i];
			}
		}

		// Check for reachable cycles in new graph
		int[] dfsState = new int[n];
		long[] R = new long[n];
		long res = d[c][r];
		boolean pos = true;
		for (int i : posDest) {
			long partRes = dfs(i, dfsState, R);
			if (partRes < 0) {
				pos = false;
			} else {
				res = Math.max(res, partRes + d[c][r] + d[r][i]);
			}
		}
		if (pos) {
			System.out.println(res);
		} else {
			System.out.println("impossible");
		}
	}

	static void getReachable(int i, int c, boolean[] reachable) {
		if (reachable[i]) return;
		reachable[i] = true;
		for (int j : adj.get(i)) {
			if (j == c) continue;
			getReachable(j, -1, reachable);
		}
	}

	static long dfs(int i, int[] dfsState, long[] R) {
		if (dfsState[i] == 2) return R[i];
		else if (dfsState[i] == 1) return -1;
		dfsState[i] = 1;
		for (int j : adj2.get(i)) {
			long r = dfs(j, dfsState, R);
			if (r < 0) return -1;
			else R[i] = Math.max(R[i], r + d[i][j]);
		}
		dfsState[i] = 2;
		return R[i];
	}

	public static void main(String args[]) {
		sc = new Scanner(System.in);
		run();
	}
}

class DV implements Comparable<DV> {
	long d;
	int v;
	public int compareTo(DV o) {
		if (d != o.d) {
			return Long.compare(d, o.d);
		} else {
			return Integer.compare(v, o.v);
		}
	}
	DV(long d, int v) {
		this.d = d;
		this.v = v;
	}
}
