import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Queue;
import java.util.StringTokenizer;

public class maze_sm_wrong_greed {

	class Vertex {
		ArrayList<Edge> e;
		ArrayList<Edge> from;
		int dist = Integer.MAX_VALUE;

		public Vertex() {
			e = new ArrayList<Edge>();
			from = new ArrayList<Edge>();
		}

		@Override
		public String toString() {
			return "[" + hashCode() + " dist = " + dist + " ] ";
		}
	}

	class Edge {

		Vertex from, to;
		char c;

		public Edge(Vertex from, Vertex to, char c) {
			this.from = from;
			this.to = to;
			this.c = c;
		}

		boolean isGood() {
			return from.dist == to.dist - 1;
		}

	}

	void addEdge(Vertex a, Vertex b, char c) {
		Edge e = new Edge(a, b, c);
		a.e.add(e);
		b.from.add(e);
	}

	void solve() {
		int n = nextInt();
		assert 2 <= n && n <= 2000;
		int m = nextInt();
		assert 1 <= m && m <= 50000;
		Vertex[] v = new Vertex[n];
		for (int i = 0; i < v.length; i++) {
			v[i] = new Vertex();
		}
		for (int i = 0; i < m; i++) {
			int a = nextInt() - 1;
			assert 0 <= a && a < n;
			int b = nextInt() - 1;
			assert 0 <= b && b < n;
			String s = nextToken();
			assert 1 <= s.length() && s.length() <= 10;
			for (int j = 0; j < s.length(); j++) {
				assert 'a' <= s.charAt(j) && s.charAt(j) <= 'z';
			}
			Vertex vx = v[a];
			for (int j = 0; j < s.length() - 1; j++) {
				Vertex nv = new Vertex();
				addEdge(vx, nv, s.charAt(j));
				vx = nv;
			}
			addEdge(vx, v[b], s.charAt(s.length() - 1));
		}
		int s = nextInt() - 1;
		int t = nextInt() - 1;
		v[t].dist = 0;
		Queue<Vertex> q = new ArrayDeque<Vertex>();
		q.add(v[t]);
		while (!q.isEmpty()) {
			Vertex w = q.poll();
			for (Edge e : w.from) {
				if (e.from.dist == Integer.MAX_VALUE) {
					e.from.dist = w.dist + 1;
					q.add(e.from);
				}
			}

		}
		if (v[s].dist == Integer.MAX_VALUE) {
			out.println("Impossible");
			return;
		}
		Vertex prev = v[s];
		for (int i = 0; i < v[s].dist; i++) {
			Vertex next = null;
			char ch = 'z' + 1;
			for (Edge e : prev.e) {
				ch = (char) Math.min(ch, e.c);
			}
			assert ch <= 'z';
			for (Edge e : prev.e) {
				if (e.c == ch) {
					next = e.to;
					break;
				}
			}
			prev = next;
			out.print(ch);
		}
	}

	BufferedReader br;
	PrintWriter out;
	StringTokenizer st;

	void run() {
		try {
			br = new BufferedReader(new FileReader("maze.in"));
			out = new PrintWriter(new FileWriter("maze.out"));
			solve();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	String nextToken() {
		try {
			while (st == null || !st.hasMoreTokens()) {
				st = new StringTokenizer(br.readLine());
			}
			return st.nextToken();
		} catch (Exception e) {
			return "0";
		}
	}

	int nextInt() {
		return Integer.parseInt(nextToken());
	}

	public static void main(String[] args) {
		new maze_sm_wrong_greed().run();
	}
}
