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

public class maze_mb_slow {
    private static void myAssertLine(int lineN, String msg, boolean exp) {
        if (!exp) {
            if (lineN == -1) {
                msg = "Last line: " + msg;
            } else {
                msg = "Line " + lineN + ": " + msg;
            }
            throw new AssertionError(msg);
        }
    }

    private static class Edge {
        public final int source;
        public final int target;
        public final int length;

        public Edge(int source, int target, int length) {
            this.source = source;
            this.target = target;
            this.length = length;
        }
    }

    private static class LabeledEdge {
        public final int source;
        public final int target;
        public final String label;

        public LabeledEdge(int source, int target, String label) {
            this.source = source;
            this.target = target;
            this.label = label;
        }
    }

    private static class DijkstraRecord implements Comparable<DijkstraRecord> {
        public final int vertex;
        public final int distance;

        public DijkstraRecord(int vertex, int distance) {
            this.vertex = vertex;
            this.distance = distance;
        }

        public int compareTo(DijkstraRecord that) {
            return distance - that.distance;
        }
    }

    private static final int INF = 1000000000;

    private static void dijkstra(int source, List<Edge>[] edges, int[] distance) {
        Arrays.fill(distance, INF);
        distance[source] = 0;
        PriorityQueue<DijkstraRecord> heap = new PriorityQueue<DijkstraRecord>();
        heap.add(new DijkstraRecord(source, 0));
        while (!heap.isEmpty()) {
            DijkstraRecord top = heap.remove();
            if (top.distance == distance[top.vertex]) {
                for (Edge e : edges[top.vertex]) {
                    if (distance[e.target] > top.distance + e.length) {
                        distance[e.target] = top.distance + e.length;
                        heap.add(new DijkstraRecord(e.target, distance[e.target]));
                    }
                }
            }
        }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new FileReader("maze.in"));
        int n, m;
        {
            String firstLine = in.readLine();
            int firstSpace = firstLine.indexOf(" ");
            int lastSpace = firstLine.lastIndexOf(" ");
            myAssertLine(1, "must contain a separating whitespace", firstSpace >= 0);
            myAssertLine(1, "must contain exactly one whitespace symbol", firstSpace == lastSpace);
            n = Integer.parseInt(firstLine.substring(0, firstSpace));
            m = Integer.parseInt(firstLine.substring(firstSpace + 1));
            myAssertLine(1, "n is out of bounds", 2 <= n && n <= 2000);
            myAssertLine(1, "m is out of bounds", 1 <= m && m <= 50000);
        }

        int[] source = new int[m];
        int[] target = new int[m];
        String[] message = new String[m];
        for (int i = 0; i < m; ++i) {
            String line = in.readLine();
            int firstWS = line.indexOf(" ");
            int lastWS = line.lastIndexOf(" ");
            source[i] = Integer.parseInt(line.substring(0, firstWS)) - 1;
            target[i] = Integer.parseInt(line.substring(firstWS + 1, lastWS)) - 1;
            message[i] = line.substring(lastWS + 1);
            myAssertLine(i + 2, "source vertex is wrong", 0 <= source[i] && source[i] < n);
            myAssertLine(i + 2, "target vertex is wrong", 0 <= target[i] && target[i] < n);
            myAssertLine(i + 2, "source == target", source[i] != target[i]);
            myAssertLine(i + 2, "label's length is wrong", 1 <= message[i].length() && message[i].length() <= 10);
            for (int j = 0; j < message[i].length(); ++j) {
                char c = message[i].charAt(j);
                myAssertLine(i + 2, "label contains illegal characters", 'a' <= c && c <= 'z');
            }
        }
        int sourceVertex, targetVertex;
        {
            String lastLine = in.readLine();
            int firstSpace = lastLine.indexOf(" ");
            int lastSpace = lastLine.lastIndexOf(" ");
            myAssertLine(-1, "must contain a separating whitespace", firstSpace >= 0);
            myAssertLine(-1, "must contain exactly one whitespace symbol", firstSpace == lastSpace);
            sourceVertex = Integer.parseInt(lastLine.substring(0, firstSpace)) - 1;
            targetVertex = Integer.parseInt(lastLine.substring(firstSpace + 1)) - 1;
            myAssertLine(-1, "source vertex is out of bounds", 0 <= sourceVertex && sourceVertex < n);
            myAssertLine(-1, "target vertex is out of bounds", 0 <= targetVertex && targetVertex < n);
        }
        in.close();

        /** Step 1: Two Dijkstras over lengths **/
        @SuppressWarnings({"unchecked"}) List<Edge>[] fwEdges = new List[n];
        @SuppressWarnings({"unchecked"}) List<Edge>[] bwEdges = new List[n];
        for (int i = 0; i < n; ++i) {
            fwEdges[i] = new ArrayList<Edge>();
            bwEdges[i] = new ArrayList<Edge>();
        }
        for (int i = 0; i < m; ++i) {
            fwEdges[source[i]].add(new Edge(source[i], target[i], message[i].length()));
            bwEdges[target[i]].add(new Edge(target[i], source[i], message[i].length()));
        }
        int[] fwDistance = new int[n];
        int[] bwDistance = new int[n];

        dijkstra(sourceVertex, fwEdges, fwDistance);
        dijkstra(targetVertex, bwEdges, bwDistance);

        int minDistance = fwDistance[targetVertex];

        if (minDistance >= INF) {
            PrintWriter out = new PrintWriter("maze.out");
            out.println("Impossible");
            out.close();
            return;
        }

        myAssertLine(146, "Algorithm failed", fwDistance[targetVertex] == bwDistance[sourceVertex]);

        /** Step 2: Writing out survived edges **/
        @SuppressWarnings({"unchecked"}) List<LabeledEdge>[] latticeEdges = new List[n];
        for (int i = 0; i < n; ++i) {
            latticeEdges[i] = new ArrayList<LabeledEdge>();
        }
        boolean[] usedVertices = new boolean[n];
        for (int i = 0; i < m; ++i) {
            if (fwDistance[source[i]] + message[i].length() + bwDistance[target[i]] == minDistance) {
                latticeEdges[source[i]].add(new LabeledEdge(source[i], target[i], message[i]));
                usedVertices[source[i]] = true;
                usedVertices[target[i]] = true;
            }
        }

        /** Step 3: Determining the order the vertices are served in **/
        List<DijkstraRecord> verticesX = new ArrayList<DijkstraRecord>();
        for (int i = 0; i < n; ++i) {
            if (usedVertices[i]) {
                verticesX.add(new DijkstraRecord(i, fwDistance[i]));
            }
        }
        DijkstraRecord[] vertices = verticesX.toArray(new DijkstraRecord[verticesX.size()]);
        Arrays.sort(vertices);
        int[] reindex = new int[n];
        Arrays.fill(reindex, -1);
        for (int i = 0; i < vertices.length; ++i) {
            reindex[vertices[i].vertex] = i;
        }

        /** Step 4: Dynamic Programming over the lattice induced by shortest paths **/
        String[] prefices = new String[vertices.length];
        prefices[0] = "";
        for (int i = 0; i < vertices.length; ++i) {
            for (LabeledEdge e : latticeEdges[vertices[i].vertex]) {
                String newv = prefices[i] + e.label;
                int dest = reindex[e.target];
                if (prefices[dest] == null || prefices[dest].compareTo(newv) > 0) {
                    prefices[dest] = newv;
                }
            }
        }

        PrintWriter out = new PrintWriter("maze.out");
        out.println(prefices[vertices.length - 1]);
        out.close();
    }
}
