Fox Ciel is going to publish a paper on FOCS (Foxes Operated Computer Systems, pronounce: "Fox"). She heard a rumor: the authors list on the paper is always sorted in the lexicographical order. 

After checking some examples, she found out that sometimes it wasn't true. On some papers authors' names weren't sorted in lexicographical order in normal sense. But it was always true that after some modification of the order of letters in alphabet, the order of authors becomes lexicographical!

She wants to know, if there exists an order of letters in Latin alphabet such that the names on the paper she is submitting are following in the lexicographical order. If so, you should find out any such order.

Lexicographical order is defined in following way. When we compare s and t, first we find the leftmost position with differing characters: s_{i} ≠ t_{i}. If there is no such position (i. e. s is a prefix of t or vice versa) the shortest string is less. Otherwise, we compare characters s_{i} and t_{i} according to their order in alphabet.


-----Input-----

The first line contains an integer n (1 ≤ n ≤ 100): number of names.

Each of the following n lines contain one string name_{i} (1 ≤ |name_{i}| ≤ 100), the i-th name. Each name contains only lowercase Latin letters. All names are different.


-----Output-----

If there exists such order of letters that the given names are sorted lexicographically, output any such order as a permutation of characters 'a'–'z' (i. e. first output the first letter of the modified alphabet, then the second, and so on).

Otherwise output a single word "Impossible" (without quotes).


-----Examples-----
Input
3
rivest
shamir
adleman

Output
bcdefghijklmnopqrsatuvwxyz

Input
10
tourist
petr
wjmzbmr
yeputons
vepifanov
scottwu
oooooooooooooooo
subscriber
rowdark
tankengineer

Output
Impossible

Input
10
petr
egor
endagorion
feferivan
ilovetanyaromanova
kostka
dmitriyh
maratsnowbear
bredorjaguarturnik
cgyforever

Output
aghjlnopefikdmbcqrstuvwxyz

Input
7
car
care
careful
carefully
becarefuldontforgetsomething
otherwiseyouwillbehacked
goodluck

Output
acbdefhijklmnogpqrstuvwxyz

Difficulty: MEDIUM_HARD
Tags: Sorting

Graph algorithms

Graph traversal
Skill types: Sorting

Starter code:

Solutions:
from collections import deque
from sys import stdout

def toposort(graph, indegrees):
	sort = deque()
	zeros = deque()
	for node in indegrees:
		if indegrees[node] == 0:
			zeros.append(node)
	while len(zeros) > 0:
		node = zeros.popleft()
		sort.append(node)
		for to in graph[node]:
			indegrees[to] -= 1
			if indegrees[to] == 0:
				zeros.append(to)
	for node in indegrees:
		if indegrees[node] != 0:
			return None
	return sort

def solve():

	def strcmp(str1, str2):
		if str1 == None:
			return True
		assert not str1 == str2
		if len(str1) < len(str2):
			if str2[:len(str1)] == str1:
				return True
		if len(str1) > len(str2):
			if str1[:len(str2)] == str2:
				return False
		length = min(len(str1), len(str2))
		for i in range(length):
			if str1[i] != str2[i]:
				return (str1[i], str2[i])
	t = int(input().rstrip())
	letters = 'abcdefghijklmnopqrstuvwxyz'
	assert len(letters) == 26
	graph = {}
	indegrees = {}
	for letter in letters:
		graph[letter] = []
		indegrees[letter] = 0
	prev = None
	for i in range(t):
		name = str(input().rstrip())
		val = strcmp(prev, name)
		if val == False:
			return False
		elif val == True:
			pass
		else:
			graph[val[0]].append(val[1])
			indegrees[val[1]] += 1
		prev = name
	sort = toposort(graph, indegrees)
	if sort == None:
		return False
	else:
		assert len(sort) == 26
		return sort
sort = solve()
if sort == False:
	print('Impossible')
else:
	for i in sort:
		stdout.write(str(i))
	stdout.write('\n')


n = int(input())
names = []
for i in range(n):
	names.append(input())
abc = 'abcdefghijklmnopqrstuvwxyz'
grafo = {}
visited = {}
orden = []
flag = True

def dfs(s):
	visited[s] = True
	if s in grafo.keys():
		for i in grafo[s]:
			if i not in visited.keys():
				dfs(i)
			elif visited[i]:
				orden.append(-1)
	visited[s] = False
	orden.append(s)
for i in range(1, n):
	actual = names[i]
	anterior = names[i - 1]
	aux = 0
	while len(actual) > aux and len(anterior) > aux and (actual[aux] == anterior[aux]):
		aux += 1
	if len(actual) <= aux:
		print('Impossible')
		flag = False
		break
	if len(anterior) <= aux:
		continue
	if anterior[aux] not in grafo.keys():
		grafo[anterior[aux]] = [actual[aux]]
	else:
		grafo[anterior[aux]].append(actual[aux])
if flag:
	for i in grafo.keys():
		if i not in visited.keys():
			dfs(i)
	orden = orden[::-1]
	if -1 in orden:
		print('Impossible')
	else:
		solucion = ''.join(orden)
		for letra in abc:
			if letra not in orden:
				solucion += letra
		print(solucion)


import sys
from string import ascii_lowercase

class AlphabetGraph:

	def __init__(self):
		self.letters = {letter: index for (index, letter) in enumerate(ascii_lowercase)}
		self.nodes = [self.Node(x) for x in range(len(ascii_lowercase))]

	def add_edge(self, u, v):
		u_index = self.letters[u]
		v_index = self.letters[v]
		n1 = self.nodes[u_index]
		n2 = self.nodes[v_index]
		if n2 not in n1.adjacent:
			n1.add_edge(n2)
			n2.in_degree += 1

	def init_set(self):
		s = set()
		for node in self.nodes:
			if node.in_degree == 0:
				s.add(node)
		return s

	def kahn(self):
		topo = []
		s = self.init_set()
		while s:
			n = s.pop()
			topo.append(n)
			for m in n.adjacent:
				m.in_degree -= 1
				if m.in_degree == 0:
					s.add(m)
			n.adjacent.clear()
		if len(topo) < len(ascii_lowercase):
			return -1
		return topo

	class Node:

		def __init__(self, num):
			self.num = num
			self.in_degree = 0
			self.adjacent = set()

		def add_edge(self, v):
			self.adjacent.add(v)
g = AlphabetGraph()
n = int(sys.stdin.readline())
a = sys.stdin.readline().strip()
result = 0
for x in range(n - 1):
	b = sys.stdin.readline().strip()
	min = len(a) if len(a) < len(b) else len(b)
	for y in range(min):
		if a[y] != b[y]:
			g.add_edge(a[y], b[y])
			break
		if y == len(b) - 1 and len(a) > len(b):
			result = -1
			break
	if result == -1:
		break
	a = b
if result == -1:
	print('Impossible')
else:
	result = g.kahn()
	if result == -1:
		print('Impossible')
	else:
		for node in result:
			print(ascii_lowercase[node.num], end='')


import queue

def topological_sort(graph, indegree, ordering):
	zero_indegree = queue.Queue()
	for u in range(26):
		if indegree[u] == 0:
			zero_indegree.put(u)
	while zero_indegree.qsize():
		u = zero_indegree.get()
		ordering.append(u)
		for v in graph[u]:
			indegree[v] -= 1
			if indegree[v] == 0:
				zero_indegree.put(v)
	for u in range(26):
		if indegree[u] != 0:
			return False
	return True
names = []
n = int(input())
for _ in range(n):
	names.append(input())
indegree = [0] * 26
graph = [[] for _ in range(26)]
shorter_comes_first = True
for i in range(n - 1):
	(name_1, name_2) = (names[i], names[i + 1])
	is_prefix = True
	for j in range(min(len(name_1), len(name_2))):
		u = ord(name_1[j]) - ord('a')
		v = ord(name_2[j]) - ord('a')
		if u != v:
			graph[u].append(v)
			indegree[v] += 1
			is_prefix = False
			break
	if is_prefix and len(name_1) > len(name_2):
		shorter_comes_first = False
		break
ordering = []
if shorter_comes_first and topological_sort(graph, indegree, ordering):
	for character_ascii in ordering:
		print(chr(character_ascii + ord('a')), end='')
	print()
else:
	print('Impossible')


n = int(input())
cur_line = ''
next_line = ''
next_line = input()
edges = [[0 for _ in range(27)] for _ in range(27)]
for i in range(n - 1):
	cur_line = next_line
	next_line = input()
	first = ''
	second = ''
	for j in range(min(len(cur_line), len(next_line))):
		if cur_line[j].lower() != next_line[j].lower():
			first = cur_line[j].lower()
			second = next_line[j].lower()
			break
	if not first or not second:
		if len(cur_line) > len(next_line):
			print('Impossible')
			exit()
	else:
		edges[ord(second) - ord('a')][ord(first) - ord('a')] = 1
gray_edges = set()
black_edges = []

def dfs(start):
	global gray_edges
	global black_edges
	global edges
	found_next = False
	for letter in range(26):
		if edges[start][letter]:
			if letter in gray_edges:
				return 'Impossible'
			elif letter not in black_edges:
				gray_edges.add(letter)
				found_next = True
				if dfs(letter) == 'Impossible':
					return 'Impossible'
	black_edges.append(start)
	gray_edges.remove(start)
	if not found_next:
		return 'Proceed with next letter'
for i in range(26):
	if i not in gray_edges and i not in black_edges:
		gray_edges.add(i)
		if dfs(i) == 'Impossible':
			print('Impossible')
			exit()
print(''.join(list(map(lambda x: chr(x + ord('a')), black_edges))))


n = int(input())
s = [input() for i in range(n)]
f = [[0 for i in range(26)] for j in range(26)]
for i in range(n):
	for k in range(i + 1, n):
		if len(s[k]) < len(s[i]) and s[k] == s[i][:len(s[k])]:
			print('Impossible')
			exit(0)
		for j in range(min(len(s[k]), len(s[i]))):
			if s[k][j] != s[i][j]:
				if f[ord(s[k][j]) - ord('a')][ord(s[i][j]) - ord('a')] == 1:
					print('Impossible')
					exit(0)
				if f[ord(s[i][j]) - ord('a')][ord(s[k][j]) - ord('a')] == -1:
					print('Impossible')
					exit(0)
				f[ord(s[k][j]) - ord('a')][ord(s[i][j]) - ord('a')] = -1
				f[ord(s[i][j]) - ord('a')][ord(s[k][j]) - ord('a')] = 1
				break

def dfs(k, used, f, res):
	if used[k] == 1:
		print('Impossible')
		exit(0)
	used[k] = 1
	for i in range(26):
		if used[i] != 2 and f[k][i] == 1:
			dfs(i, used, f, res)
	used[k] = 2
	res.append(k)
used = [0 for i in range(26)]
res = []
for i in range(25, -1, -1):
	if used[i] == 0:
		dfs(i, used, f, res)
for i in range(26):
	print(chr(res[25 - i] + ord('a')), end='')


from itertools import zip_longest

def main():
	names = [input() for _ in range(int(input()))]
	edges = [set() for _ in range(27)]
	for (na, nb) in zip(names, names[1:]):
		for (a, b) in zip_longest(na, nb, fillvalue='`'):
			if a != b:
				edges[ord(a) - 96].add(ord(b) - 96)
				break
	(chars, i, visited) = (list(range(27)), 27, [False] * (27 * 27))
	while i:
		i -= 1
		a = chars[i]
		j = a * 27 + i
		if visited[j]:
			chars[0] = 1
			break
		visited[j] = True
		for b in edges[a]:
			j = chars.index(b)
			if j < i:
				(chars[i], chars[j]) = (b, a)
				i += 1
				break
	print('Impossible' if chars[0] else ''.join((chr(c + 96) for c in chars[1:])))
main()


import string
import sys
from collections import defaultdict
num_names = int(input())
names = [input() for _ in range(num_names)]
adj_list = {c: [] for c in string.ascii_lowercase}
in_degree = {c: 0 for c in string.ascii_lowercase}
for (a, b) in zip(names[:-1], names[1:]):
	have_prefix = True
	for (i, j) in zip(a, b):
		if i != j:
			adj_list[i].append(j)
			in_degree[j] += 1
			have_prefix = False
			break
	if have_prefix and len(b) < len(a):
		print('Impossible')
		sys.exit(0)
alphabet = ''
zeros = [u for u in in_degree if in_degree[u] == 0]
while zeros:
	u = zeros.pop()
	alphabet += u
	for v in adj_list[u]:
		in_degree[v] -= 1
		if in_degree[v] == 0:
			zeros.append(v)
if len(alphabet) == 26:
	print(alphabet)
else:
	print('Impossible')


import sys
from functools import lru_cache, cmp_to_key
from heapq import merge, heapify, heappop, heappush, nsmallest
from math import ceil, floor, gcd, fabs, factorial, fmod, sqrt, inf
from collections import defaultdict as dd, deque, Counter as C
from itertools import combinations as comb, permutations as perm
from bisect import bisect_left as bl, bisect_right as br, bisect
from time import perf_counter
from fractions import Fraction
from decimal import Decimal
mod = pow(10, 9) + 7
mod2 = 998244353

def data():
	return sys.stdin.readline().strip()

def out(var):
	sys.stdout.write(str(var))

def outa(*var, end='\n'):
	sys.stdout.write(' '.join(map(str, var)) + end)

def l():
	return list(sp())

def sl():
	return list(ssp())

def sp():
	return map(int, data().split())

def ssp():
	return map(str, data().split())

def l1d(n, val=0):
	return [val for i in range(n)]

def l2d(n, m, val=0):
	return [l1d(n, val) for j in range(m)]

def dfs(source):
	vis[source] = 1
	for child in graph[source]:
		if vis[child] == 1:
			out('Impossible')
			exit()
		if not vis[child]:
			dfs(child)
	answer.append(source)
	vis[source] = 2
n = int(data())
names = [list(data()) for i in range(n)]
graph = dd(set)
r = True
order = []
for i in range(n - 1):
	j = i + 1
	a = 0
	while a < min(len(names[i]), len(names[j])) and names[i][a] == names[j][a]:
		a += 1
	if a < min(len(names[i]), len(names[j])) and names[i][a] != names[j][a]:
		graph[names[i][a]].add(names[j][a])
		continue
	if len(names[i]) > len(names[j]):
		out('Impossible')
		exit()
vis = dd(int)
answer = []
for i in range(26):
	c = chr(i + 97)
	if not vis[c]:
		dfs(c)
out(''.join(answer[::-1]))


from heapq import heappush, heappop

def ts_kahn(graph, result):
	indegree = [0] * (V + 1)
	zero_indegree = []
	for u in range(1, V + 1):
		for v in graph[u]:
			indegree[v] += 1
	for i in range(1, V + 1):
		if indegree[i] == 0:
			heappush(zero_indegree, i)
	while len(zero_indegree) != 0:
		u = heappop(zero_indegree)
		result.append(u)
		for v in graph[u]:
			indegree[v] -= 1
			if indegree[v] == 0:
				heappush(zero_indegree, v)
	for i in range(1, V + 1):
		if indegree[i] != 0:
			return False
	return True
n = int(input())
V = 26
imp = False
graph = [[] for i in range(V + 1)]
result = []
names = []
for i in range(n):
	names.append(list(input()))
exist = set()
exist.add(names[0][0])
for i in range(n - 1):
	na = names[i]
	nb = names[i + 1]
	size = min(len(na), len(nb))
	for j in range(size):
		if na[j] != nb[j]:
			graph[ord(na[j]) - 96].append(ord(nb[j]) - 96)
			break
		elif j == size - 1 and len(nb) < len(na):
			imp = True
			break
if imp:
	print('Impossible')
elif ts_kahn(graph, result):
	for i in range(V):
		print(chr(result[i] + 96), end='')
else:
	print('Impossible')


n = int(input())
name = []
for i in range(n):
	x = input()
	name.append(x + (101 - len(x)) * '{')
G = [[] for i in range(26)]
G2 = [[] for i in range(26)]

def f(s):
	return ord(s) - ord('a')
flag = True
for i in range(1, n):
	for j in range(100):
		if name[i][j] != name[i - 1][j]:
			if '{' == name[i][j]:
				flag = False
				break
			elif '{' == name[i - 1][j]:
				break
			G[f(name[i - 1][j])].append(f(name[i][j]))
			G2[f(name[i][j])].append(f(name[i - 1][j]))
			break
L = []
S = []
for i in range(26):
	if G2[i] == []:
		S.append(i)
while S != []:
	node = S.pop(0)
	L.append(node)
	for i in G[node]:
		G2[i].remove(node)
		if G2[i] == []:
			S.append(i)
if G2 == [[] for i in range(26)] and len(L) == 26 and flag:
	for i in L:
		print(chr(ord('a') + i), end='')
	print()
else:
	print('Impossible')


n = list(map(int, input().split()))[0]
name_list = []
for _ in range(0, n):
	name = input().split()[0]
	name_list.append(name)
dag = dict()

def add_edge(char1, char2):
	if char1 in dag.keys():
		dag[char1][1].add(char2)
	else:
		dag[char1] = [set(), set([char2])]
	if char2 in dag.keys():
		dag[char2][0].add(char1)
	else:
		dag[char2] = [set([char1]), set()]

def compare_2_names(name1, name2):
	for i in range(min(len(name1), len(name2))):
		if name1[i] != name2[i]:
			add_edge(name1[i], name2[i])
			return True
	if len(name2) <= len(name1):
		return False
	return True

def run():
	res = []
	current_candidate_nodes = []
	for k in dag.keys():
		if len(dag[k][0]) == 0:
			current_candidate_nodes.append(k)
	if len(current_candidate_nodes) == 0:
		return False
	num_letters = len(dag)
	while len(res) < num_letters:
		new_candidate_nodes = []
		for item in current_candidate_nodes:
			dag.pop(item)
		for k in dag.keys():
			if len(current_candidate_nodes) == 0:
				return False
			for c in current_candidate_nodes:
				if c in dag[k][0]:
					if len(dag[k][1] & set(res)) > 0:
						return False
					dag[k][0].remove(c)
					if len(dag[k][0]) == 0:
						new_candidate_nodes.append(k)
		res += current_candidate_nodes
		current_candidate_nodes = new_candidate_nodes
	return res
last_name = name_list[0]
impossible = False
for i in range(1, n):
	name = name_list[i]
	if not impossible and compare_2_names(last_name, name) == False:
		impossible = True
	last_name = name
if impossible:
	print('Impossible')
else:
	all_chars = set('abcdefghijklmnopqrstuvwxyz')
	if len(dag.keys()) == 0:
		print('abcdefghijklmnopqrstuvwxyz')
	else:
		no_contraint_chars = all_chars - set(dag.keys())
		path = run()
		if path == False:
			print('Impossible')
		else:
			print(''.join(path) + ''.join(no_contraint_chars))


from collections import deque, defaultdict
from math import sqrt, ceil, factorial, floor, inf, log2, sqrt, gcd
import bisect
import sys
import copy

def get_array():
	return list(map(int, sys.stdin.readline().strip().split()))

def get_ints():
	return map(int, sys.stdin.readline().strip().split())

def input():
	return sys.stdin.readline().strip()
n = int(input())
arr = []
for i in range(n):
	s = input()
	arr.append(s)
d = defaultdict(list)
indegree = [0] * 26
se = set()
flag = 0
for i in range(n):
	for j in range(i + 1, n):
		ind = -1
		lim = min(len(arr[i]), len(arr[j]))
		for k in range(lim):
			if arr[i][k] != arr[j][k]:
				se.add(ord(arr[i][k]) - 97)
				se.add(ord(arr[j][k]) - 97)
				d[ord(arr[i][k]) - 97].append(ord(arr[j][k]) - 97)
				indegree[ord(arr[j][k]) - 97] += 1
				ind = k
				break
		if ind == -1 and len(arr[i]) > len(arr[j]):
			flag = 1
			break
	if flag == 1:
		break
if flag == 1:
	print('Impossible')
else:
	qu = []
	for i in range(26):
		if indegree[i] == 0 and i in se:
			qu.append(i)
	li = []
	while len(qu) != 0:
		ele = qu.pop(0)
		li.append(ele)
		for x in d[ele]:
			indegree[x] -= 1
			if indegree[x] == 0:
				qu.append(x)
	if len(li) != len(se):
		print('Impossible')
	else:
		stri = 'abcdefghijklmnopqrstuvwxyz'
		for i in range(26):
			if i not in li:
				li.append(i)
		st = ''
		for i in range(len(li)):
			st += stri[li[i]]
		print(st)


from collections import Counter as cntr
from math import inf

def cin():
	return map(int, input().split(' '))
n = int(input())
name1 = input()
latin = [[0 for i in range(26)] for i in range(26)]
for i in range(n - 1):
	name2 = input()
	if name1.startswith(name2):
		print('Impossible')
		exit(0)
	for j in range(len(name1)):
		if name1[j] != name2[j]:
			c1 = ord(name1[j]) - 97
			c2 = ord(name2[j]) - 97
			latin[c1][c2] = 1
			break
	name1 = name2
timer = 1
f = [inf for i in range(26)]

def dfs(src):
	global latin, visited, timer
	visited[src] = True
	for v in range(26):
		if visited[v] == False and latin[src][v] == 1:
			dfs(v)
	timer += 1
	f[src] = timer
visited = [False for i in range(26)]
for i in range(26):
	if not visited[i]:
		dfs(i)
l = sorted(range(26), key=lambda x: -f[x])
ans = ''
for i in range(26):
	ans += chr(97 + l[i])
	for j in range(i):
		if latin[l[i]][l[j]]:
			print('Impossible')
			exit(0)
print(ans)


(s, n) = (1, int(input()))
(a, b) = ([], [])
t = ''
d = [0] * 26
u = input()
exit = False
for i in range(n - 1):
	v = input()
	j = 0
	while j < min(len(u), len(v)) and u[j] == v[j]:
		j += 1
	if j == min(len(u), len(v)):
		if len(u) >= len(v):
			exit = True
			break
	else:
		q = (ord(u[j]) - 97, ord(v[j]) - 97)
		a.append(q)
		u = v
		d[q[1]] = s
if not exit:
	while a:
		b = [q for q in a if d[q[0]] == s]
		s += 1
		for q in b:
			d[q[1]] = s
		if len(a) == len(b):
			exit = True
			break
		else:
			(a, b) = (b, [])
if exit:
	print('Impossible')
else:
	for x in sorted(enumerate(d), key=lambda x: x[1]):
		t += chr(x[0] + 97)
	print(t)


import os
import sys
from io import BytesIO, IOBase
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')
from math import factorial
from collections import Counter, defaultdict, deque
from heapq import heapify, heappop, heappush

def RL():
	return map(int, sys.stdin.readline().rstrip().split())

def RLL():
	return list(map(int, sys.stdin.readline().rstrip().split()))

def N():
	return int(input())

def comb(n, m):
	return factorial(n) / (factorial(m) * factorial(n - m)) if n >= m else 0

def perm(n, m):
	return factorial(n) // factorial(n - m) if n >= m else 0

def mdis(x1, y1, x2, y2):
	return abs(x1 - x2) + abs(y1 - y2)
mod = 998244353
INF = float('inf')

def tn(c):
	return ord(c) - ord('a')

def main():
	n = N()
	arr = [input() for _ in range(n)]
	gp = [[] for _ in range(26)]
	res = []
	tag = True
	for i in range(n - 1):
		now = 0
		(l1, l2) = (len(arr[i]), len(arr[i + 1]))
		while now < l1 and now < l2 and (arr[i][now] == arr[i + 1][now]):
			now += 1
		if now < l1 and now < l2:
			(ca, cb) = (tn(arr[i][now]), tn(arr[i + 1][now]))
			gp[ca].append(cb)
		elif l1 > l2:
			tag = False
	res = []
	vis = [0] * 26

	def dfs(node):
		vis[node] = 1
		nonlocal tag
		for nex in gp[node]:
			if vis[nex] == 1:
				tag = False
				continue
			if vis[nex] == 0:
				dfs(nex)
		vis[node] = 2
		res.append(node)
	for i in range(26):
		if vis[i] == 0:
			dfs(i)
	if tag == False:
		print('Impossible')
	else:
		print(''.join([chr(ord('a') + i) for i in res[::-1]]))
main()


def isPrefix(sa, sb):
	if len(sa) >= len(sb):
		return False
	return sa == sb[0:len(sa)]

def getOrder(sa, sb):
	for i in range(min(len(sa), len(sb))):
		if sa[i] != sb[i]:
			return (sa[i], sb[i])
test = False
if test:
	fp = open('in.txt', 'r')
	n = int(fp.readline().strip())
	names = [fp.readline().strip() for _ in range(n)]
	fp.close()
else:
	n = int(input().strip())
	names = [input().strip() for _ in range(n)]
res = True
g = [[False] * 26 for _ in range(26)]

def printG():
	print(' abcdefghijklmnopqrstuvwxyz')
	for i in range(0, 26):
		print(chr(ord('a') + i), ''.join(['1' if x else '0' for x in g[i]]), sep='')
for i in range(n - 1):
	if names[i] == names[i + 1] or isPrefix(names[i], names[i + 1]):
		continue
	elif isPrefix(names[i + 1], names[i]):
		res = False
		break
	else:
		(ca, cb) = getOrder(names[i], names[i + 1])
		if g[ord(cb) - ord('a')][ord(ca) - ord('a')]:
			res = False
			break
		else:
			a = ord(ca) - ord('a')
			b = ord(cb) - ord('a')
			g[a][b] = True
if not res:
	print('Impossible')
else:

	def getZeroIndegreeNode():
		for i in range(26):
			if not vis[i] and Indegree[i] == 0:
				return i
		return -1
	strOrder = []
	vis = [False] * 26
	Indegree = [0] * 26
	for i in range(26):
		ithIndegree = 0
		for j in range(26):
			if g[j][i]:
				ithIndegree += 1
		Indegree[i] = ithIndegree
	for i in range(26):
		ZeroIndegreeNode = getZeroIndegreeNode()
		if ZeroIndegreeNode == -1:
			res = False
			break
		else:
			strOrder.append(chr(ord('a') + ZeroIndegreeNode))
			vis[ZeroIndegreeNode] = True
			for i in range(26):
				if g[ZeroIndegreeNode][i]:
					Indegree[i] -= 1
	if not res:
		print('Impossible')
	else:
		print(''.join(strOrder))


n = int(input())
g = [set() for _ in range(26)]
t = [0] * 26
a = input()
for _ in range(1, n):
	b = input()
	j = 0
	while j < min(len(a), len(b)) and a[j] == b[j]:
		j += 1
	if j < min(len(a), len(b)) and a[j] != b[j]:
		g[ord(a[j]) - ord('a')].add(ord(b[j]) - ord('a'))
	elif len(a) > len(b):
		print('Impossible')
		exit()
	a = b
o = []

def dfs(x):
	t[x] = 1
	for j in g[x]:
		if t[j] == 1:
			print('Impossible')
			exit()
		if t[j] == 0:
			dfs(j)
	t[x] = 2
	o.append(chr(x + ord('a')))
for i in range(26):
	if t[i] == 0:
		dfs(i)
print(''.join(reversed(o)))


n = int(input())
x = input()
a = len(x)
lex = dict()
ALPHA = list('abcdefghijklmnopqrstuvwxyz')
for i in ALPHA:
	for j in ALPHA:
		lex[i, j] = 0
for i in range(n - 1):
	y = input()
	b = len(y)
	for j in range(min([a, b])):
		if x[j] != y[j]:
			if lex[x[j], y[j]] == -1:
				print('Impossible')
				raise SystemExit
			else:
				lex[x[j], y[j]] = 1
				lex[y[j], x[j]] = -1
				x = y
				a = b
			break
		if j == min([a, b]) - 1:
			if a > b:
				print('Impossible')
				raise SystemExit
			x = y
			a = b

def biggest(alphabet):
	for i in alphabet:
		t = 0
		for j in alphabet:
			if lex[i, j] < 0:
				t = 1
				break
		if t == 0:
			return i
	return -1
newalpha = [''] * 26
i = 0
while ALPHA != []:
	BIG = biggest(ALPHA)
	if biggest(ALPHA) == -1:
		print('Impossible')
		raise SystemExit
	newalpha[i] = BIG
	i = i + 1
	ALPHA.remove(BIG)
print(''.join(newalpha))


import sys
from collections import deque

def func(adj, stack, visited, i):
	visited[i] = 1
	for j in adj[i]:
		if visited[j] == 0:
			func(adj, stack, visited, j)
	stack.append(i)

def topoSort(n, adj):
	visited = [0 for i in range(n)]
	stack = []
	for i in range(n):
		if visited[i] == 0:
			func(adj, stack, visited, i)
	return stack[::-1]

def bfs(graph, vis, start):
	vis[start] = True
	parent = {start: True}
	Q = deque()
	Q.append(start)
	while Q:
		u = Q.popleft()
		for v in graph[u]:
			if v in parent:
				return True
			elif vis[v] == False:
				Q.append(v)
				vis[v] = True
	return False

def cycle(graph, n):
	vis = [False for i in range(n)]
	found = False
	for i in range(n):
		if vis[i] == False:
			found = bfs(graph, vis, i)
			if found:
				break
	if found:
		return True
	else:
		return False

def main():
	input = sys.stdin.readline
	n = int(input())
	arr = []
	for _ in range(n):
		x = input().strip()
		arr.append(x)
	graph = {i: [] for i in range(26)}
	for i in range(1, n):
		j = 0
		while j < len(arr[i - 1]) and j < len(arr[i]) and (arr[i - 1][j] == arr[i][j]):
			j += 1
		if j < len(arr[i - 1]) and j < len(arr[i]):
			u = ord(arr[i - 1][j]) - 97
			v = ord(arr[i][j]) - 97
			graph[u].append(v)
		elif len(arr[i - 1]) > len(arr[i]):
			print('Impossible')
			return
	if cycle(graph, 26):
		sys.stdout.write(str('Impossible'))
	else:
		order = topoSort(26, graph)
		for i in order:
			print(chr(i + 97), end='')
		print()
main()


import os
import sys
from io import BytesIO, IOBase
from collections import deque

def main():
	n = int(input())
	l = []
	for _ in range(n):
		l.append(list(input()))
	graph = [[] for _ in range(26)]
	indegree = [0] * 26
	for i in range(n - 1):
		j = i + 1
		z = 0
		r = 0
		(a, b) = (l[i], l[j])
		while z < len(a) and r < len(b):
			if a[z] != b[r]:
				indegree[ord(b[r]) - 97] += 1
				graph[ord(a[z]) - 97].append(ord(b[r]) - 97)
				break
			z += 1
			r += 1
		if r == len(b):
			print('Impossible')
			exit()
	queue = deque()
	count = 0
	for i in range(26):
		if not indegree[i]:
			queue.append(i)
	order = []
	while queue:
		z = queue.popleft()
		order.append(z)
		for item in graph[z]:
			indegree[item] -= 1
			if indegree[item] == 0:
				queue.append(item)
		count += 1
	if count != 26:
		print('Impossible')
	else:
		for i in range(26):
			order[i] = chr(order[i] + 97)
		print(*order, sep='')
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')
main()


import sys, os, io

def rs():
	return sys.stdin.readline().rstrip()

def ri():
	return int(sys.stdin.readline())

def ria():
	return list(map(int, sys.stdin.readline().split()))

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

def wi(n):
	sys.stdout.write(str(n) + '\n')

def wia(a):
	sys.stdout.write(' '.join([str(x) for x in a]) + '\n')
import math, datetime, functools, itertools, operator, bisect, fractions, statistics
from collections import deque, defaultdict, OrderedDict, Counter
from fractions import Fraction
from decimal import Decimal
from sys import stdout
from heapq import heappush, heappop, heapify, _heapify_max, _heappop_max, nsmallest, nlargest
INF = 999999999999999999999999

class SortedList:

	def __init__(self, iterable=[], _load=200):
		values = sorted(iterable)
		self._len = _len = len(values)
		self._load = _load
		self._lists = _lists = [values[i:i + _load] for i in range(0, _len, _load)]
		self._list_lens = [len(_list) for _list in _lists]
		self._mins = [_list[0] for _list in _lists]
		self._fen_tree = []
		self._rebuild = True

	def _fen_build(self):
		self._fen_tree[:] = self._list_lens
		_fen_tree = self._fen_tree
		for i in range(len(_fen_tree)):
			if i | i + 1 < len(_fen_tree):
				_fen_tree[i | i + 1] += _fen_tree[i]
		self._rebuild = False

	def _fen_update(self, index, value):
		if not self._rebuild:
			_fen_tree = self._fen_tree
			while index < len(_fen_tree):
				_fen_tree[index] += value
				index |= index + 1

	def _fen_query(self, end):
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		x = 0
		while end:
			x += _fen_tree[end - 1]
			end &= end - 1
		return x

	def _fen_findkth(self, k):
		_list_lens = self._list_lens
		if k < _list_lens[0]:
			return (0, k)
		if k >= self._len - _list_lens[-1]:
			return (len(_list_lens) - 1, k + _list_lens[-1] - self._len)
		if self._rebuild:
			self._fen_build()
		_fen_tree = self._fen_tree
		idx = -1
		for d in reversed(range(len(_fen_tree).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(_fen_tree) and k >= _fen_tree[right_idx]:
				idx = right_idx
				k -= _fen_tree[idx]
		return (idx + 1, k)

	def _delete(self, pos, idx):
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len -= 1
		self._fen_update(pos, -1)
		del _lists[pos][idx]
		_list_lens[pos] -= 1
		if _list_lens[pos]:
			_mins[pos] = _lists[pos][0]
		else:
			del _lists[pos]
			del _list_lens[pos]
			del _mins[pos]
			self._rebuild = True

	def _loc_left(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(lo, pos) = (-1, len(_lists) - 1)
		while lo + 1 < pos:
			mi = lo + pos >> 1
			if value <= _mins[mi]:
				pos = mi
			else:
				lo = mi
		if pos and value <= _lists[pos - 1][-1]:
			pos -= 1
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value <= _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def _loc_right(self, value):
		if not self._len:
			return (0, 0)
		_lists = self._lists
		_mins = self._mins
		(pos, hi) = (0, len(_lists))
		while pos + 1 < hi:
			mi = pos + hi >> 1
			if value < _mins[mi]:
				hi = mi
			else:
				pos = mi
		_list = _lists[pos]
		(lo, idx) = (-1, len(_list))
		while lo + 1 < idx:
			mi = lo + idx >> 1
			if value < _list[mi]:
				idx = mi
			else:
				lo = mi
		return (pos, idx)

	def add(self, value):
		_load = self._load
		_lists = self._lists
		_mins = self._mins
		_list_lens = self._list_lens
		self._len += 1
		if _lists:
			(pos, idx) = self._loc_right(value)
			self._fen_update(pos, 1)
			_list = _lists[pos]
			_list.insert(idx, value)
			_list_lens[pos] += 1
			_mins[pos] = _list[0]
			if _load + _load < len(_list):
				_lists.insert(pos + 1, _list[_load:])
				_list_lens.insert(pos + 1, len(_list) - _load)
				_mins.insert(pos + 1, _list[_load])
				_list_lens[pos] = _load
				del _list[_load:]
				self._rebuild = True
		else:
			_lists.append([value])
			_mins.append(value)
			_list_lens.append(1)
			self._rebuild = True

	def discard(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_right(value)
			if idx and _lists[pos][idx - 1] == value:
				self._delete(pos, idx - 1)

	def remove(self, value):
		_len = self._len
		self.discard(value)
		if _len == self._len:
			raise ValueError('{0!r} not in list'.format(value))

	def pop(self, index=-1):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		value = self._lists[pos][idx]
		self._delete(pos, idx)
		return value

	def bisect_left(self, value):
		(pos, idx) = self._loc_left(value)
		return self._fen_query(pos) + idx

	def bisect_right(self, value):
		(pos, idx) = self._loc_right(value)
		return self._fen_query(pos) + idx

	def count(self, value):
		return self.bisect_right(value) - self.bisect_left(value)

	def __len__(self):
		return self._len

	def __getitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		return self._lists[pos][idx]

	def __delitem__(self, index):
		(pos, idx) = self._fen_findkth(self._len + index if index < 0 else index)
		self._delete(pos, idx)

	def __contains__(self, value):
		_lists = self._lists
		if _lists:
			(pos, idx) = self._loc_left(value)
			return idx < len(_lists[pos]) and _lists[pos][idx] == value
		return False

	def __iter__(self):
		return (value for _list in self._lists for value in _list)

	def __reversed__(self):
		return (value for _list in reversed(self._lists) for value in reversed(_list))

	def __repr__(self):
		return 'SortedList({0})'.format(list(self))

def main():
	mod = 1000000007
	starttime = datetime.datetime.now()
	if os.path.exists('input.txt'):
		sys.stdin = open('input.txt', 'r')
		sys.stdout = open('output.txt', 'w')
	tc = 1
	for _ in range(tc):
		n = ri()
		ans = list('abcdefghijklmnopqrstuvwxyz')
		if n == 1:
			ws('abcdefghijklmnopqrstuvwxyz')
		else:
			words = []
			graph = {}
			for i in range(n):
				words.append(rs())
			for i in range(n - 1):
				(a, b) = (words[i], words[i + 1])
				check = 1
				for j in range(min(len(a), len(b))):
					if a[j] != b[j]:
						check = 0
						if a[j] in graph:
							graph[a[j]].append(b[j])
						else:
							graph[a[j]] = [b[j]]
						break
				if check:
					if len(a) > len(b):
						print('Impossible')
						exit()
			color = {}
			parent = {}
			vis = {}

			def dfs(v):
				color[v] = 1
				if v in graph:
					for u in graph[v]:
						if u not in color:
							parent[u] = v
							if dfs(u):
								return True
						elif color[u] == 1:
							return True
				color[v] = 2
				return False
			for v in graph:
				if v not in vis:
					if dfs(v):
						print('Impossible')
						exit()
					vis[v] = 1
			comp = {}
			for i in range(n - 1):
				for k in range(i + 1, n):
					(a, b) = (words[i], words[k])
					for j in range(min(len(a), len(b))):
						if a[j] != b[j]:
							if (b[j], a[j]) in comp:
								print('Impossible')
								exit()
							if (a[j], b[j]) not in comp:
								comp[a[j], b[j]] = 1
							break
			for (x, y) in comp:
				for l in range(26):
					if ans[l] == x:
						break
				for r in range(26):
					if ans[r] == y:
						break
				if l > r:
					tans = ans[:r] + [ans[l], ans[r]] + ans[r + 1:l] + ans[l + 1:]
					ans = tans
			for (x, y) in comp:
				for l in range(26):
					if ans[l] == x:
						break
				for r in range(26):
					if ans[r] == y:
						break
				if l > r:
					tans = ans[:r] + [ans[l], ans[r]] + ans[r + 1:l] + ans[l + 1:]
					ans = tans
			ws(''.join(ans))
	endtime = datetime.datetime.now()
	time = (endtime - starttime).total_seconds() * 1000
	if os.path.exists('input.txt'):
		print('Time:', time, 'ms')

class FastReader(io.IOBase):
	newlines = 0

	def __init__(self, fd, chunk_size=1024 * 8):
		self._fd = fd
		self._chunk_size = chunk_size
		self.buffer = io.BytesIO()

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, self._chunk_size))
			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, size=-1):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, self._chunk_size if size == -1 else size))
			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()

class FastWriter(io.IOBase):

	def __init__(self, fd):
		self._fd = fd
		self.buffer = io.BytesIO()
		self.write = self.buffer.write

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

class FastStdin(io.IOBase):

	def __init__(self, fd=0):
		self.buffer = FastReader(fd)
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

class FastStdout(io.IOBase):

	def __init__(self, fd=1):
		self.buffer = FastWriter(fd)
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.flush = self.buffer.flush
sys.stdin = FastStdin()
sys.stdout = FastStdout()
main()


from heapq import heappop, heappush
n = int(input())
a = []
first = ord('a')
for i in range(n):
	a.append(input())
graph = [[] for x in range(27)]
for i in range(int(n - 1)):
	for j in range(i + 1, n, 1):
		pre = a[i]
		suf = a[j]
		if len(pre) <= len(suf):
			index = 0
			while index < len(pre):
				if pre[index] == suf[index]:
					index += 1
				else:
					graph[ord(pre[index]) - first].append(ord(suf[index]) - first)
					index = -1
					break
		else:
			index = 0
			while index < len(suf):
				if pre[index] == suf[index]:
					index += 1
				else:
					graph[ord(pre[index]) - first].append(ord(suf[index]) - first)
					index = -1
					break
			if index != -1:
				print('Impossible')
				exit(0)
isContructors = True

def dfs(u, stack, vis):
	vis[u] = 2
	global isContructors, graph
	for v in graph[u]:
		if vis[v] == 0:
			dfs(v, stack, vis)
		elif vis[v] == 2:
			isContructors = False
	vis[u] = 1
	stack.append(u)

def roolback(u, vis):
	vis[u] = 1
	global graph
	print(str(chr(u + first)), end='')
	for v in graph[u]:
		if vis[v] == 0:
			roolback(v, vis)
(stack, vis) = ([], [0] * 26)
for i in range(26):
	if vis[i] == 0:
		dfs(i, stack, vis)
if isContructors == False:
	print('Impossible')
else:
	vis = [0] * 26
	while stack:
		u = stack[-1]
		stack.pop()
		print(chr(u + first), end='')


def f():
	(s, n) = (1, int(input()))
	(a, b) = ([], [])
	(t, e) = ('', 'Impossible')
	d = [0] * 26
	u = input()
	for i in range(n - 1):
		v = input()
		(x, y) = (len(u), len(v))
		(j, k) = (0, min(x, y))
		while j < k and u[j] == v[j]:
			j += 1
		if j == k:
			if x >= y:
				return e
		else:
			q = (ord(u[j]) - 97, ord(v[j]) - 97)
			a.append(q)
			(u, d[q[1]]) = (v, s)
	while a:
		b = [q for q in a if d[q[0]] == s]
		s += 1
		for q in b:
			d[q[1]] = s
		if len(a) == len(b):
			return e
		(a, b) = (b, [])
	for x in sorted(enumerate(d), key=lambda x: x[1]):
		t += chr(x[0] + 97)
	return t
print(f())


def do_job():

	def order_info(s1, s2):
		smaller = None
		larger = None
		for i in range(min(len(s1), len(s2))):
			if s1[i] != s2[i]:
				smaller = s1[i]
				larger = s2[i]
				break
		return (smaller, larger)
	n = int(input())
	list_of_string = []
	for _ in range(n):
		list_of_string.append(input())
	g = {x: set() for x in 'abcdefghijklmnopqrstuwvxyz'}
	for ind in range(0, n - 1):
		(small, big) = order_info(list_of_string[ind], list_of_string[ind + 1])
		if big is not None:
			g[big].add(small)
		if big is None and len(list_of_string[ind]) > len(list_of_string[ind + 1]):
			return 'Impossible'
	q = {x for x in g if g[x] == set()}
	order_list = []
	while len(q) > 0:
		elem = q.pop()
		order_list.append(elem)
		for x in g:
			if elem in g[x]:
				g[x].remove(elem)
		q = {x for x in g if g[x] == set() and x not in order_list}
	if len(order_list) == 26:
		return ''.join(order_list)
	else:
		return 'Impossible'
print(do_job())


import string

def make_link(G, char1, char2):
	if char1 in G:
		if char2 in G[char1]:
			return
		else:
			G[char1].append(char2)
	else:
		G[char1] = [char2]

def make_order(G, str1, str2):
	for i in range(min(len(str1), len(str2))):
		if str1[i] != str2[i]:
			make_link(G, str1[i], str2[i])
			return True
	if len(str2) > len(str1):
		return True
	else:
		return False

def topological_sort(G, ans, k='', visited={}):
	if visited.get(k, True) == False:
		return True
	if k not in visited:
		visited[k] = False
		for next in G.get(k, []):
			if topological_sort(G, ans, next, visited):
				return True
		visited[k] = True
		ans.insert(0, k)
	return False

def main():
	N = int(input())
	strs = [input() for i in range(N)]
	G = {}
	for i in range(N - 1):
		if not make_order(G, strs[i], strs[i + 1]):
			print('Impossible')
			return
	G[''] = reversed(string.ascii_lowercase)
	ans = []
	if topological_sort(G, ans):
		print('Impossible')
	else:
		print(''.join(ans))
main()


from collections import deque
from sys import stdin
N = int(stdin.readline().rstrip())
strA = stdin.readline().rstrip()
adj_list = []
in_degrees = [0] * 26
impossible = False
order = []
for index in range(0, 26):
	adj_list.append([])
for n in range(1, N):
	stringEqual = True
	strB = stdin.readline().rstrip()
	length = min(len(strA), len(strB))
	for index in range(0, length):
		a = strA[index]
		b = strB[index]
		if a != b:
			indexA = ord(a) - 97
			indexB = ord(b) - 97
			adj_list[indexA].append(indexB)
			in_degrees[indexB] += 1
			stringEqual = False
			break
	if stringEqual:
		if len(strA) > len(strB):
			impossible = True
			break
	strA = strB
if not impossible:
	queue = deque()
	for index in range(0, 26):
		if in_degrees[index] == 0:
			queue.append(index)
	while queue:
		vertex = queue.popleft()
		order.append(chr(vertex + 97))
		for neighbor in adj_list[vertex]:
			in_degrees[neighbor] -= 1
			if in_degrees[neighbor] == 0:
				queue.append(neighbor)
	for index in range(0, 26):
		if in_degrees[index] != 0:
			impossible = True
			break
if impossible:
	print('Impossible')
else:
	print(''.join(order))


from itertools import zip_longest

def main():
	names = [input() for _ in range(int(input()))]
	edges = [set() for _ in range(27)]
	chars = [True] * 27
	for (na, nb) in zip(names, names[1:]):
		for (a, b) in zip_longest(na, nb, fillvalue='`'):
			if a != b:
				edges[ord(a) - 96].add(ord(b) - 96)
				break

	def dfs(u):
		chars[u] = None
		for v in edges[u]:
			if chars[v]:
				dfs(v)
			elif chars[v] is None:
				raise TabError
		chars[u] = False
	try:
		for (c, f) in enumerate(chars):
			if f:
				dfs(c)
	except TabError:
		print('Impossible')
		return
	(chars, i) = (list(range(27)), 27)
	while i:
		i -= 1
		a = chars[i]
		for b in edges[a]:
			j = chars.index(b)
			if j < i:
				(chars[i], chars[j]) = (b, a)
				i += 1
				break
	print('Impossible' if chars[0] else ''.join((chr(c + 96) for c in chars[1:])))
main()


import string
n = int(input())
words = [input() for _ in range(n)]
letters = string.ascii_lowercase[::-1]

def build_graph():
	graph = {letter: set() for letter in letters}
	previous = ''
	for word in words:
		comparison = compare_words(previous, word)
		if comparison == 'Impossible':
			return 'Impossible'
		elif comparison:
			graph[comparison[0]].add(comparison[1])
		previous = word
	return graph

def compare_words(w0, w1):
	for (l0, l1) in zip(list(w0), list(w1)):
		if l0 == l1:
			continue
		return (l0, l1)
	if len(w0) > len(w1):
		return 'Impossible'
	return False

def topological_sort(graph):
	ordering = []
	(visited, visiting) = (set(), set())

	def explore(node, visited, visiting):
		if node in visiting:
			return False
		elif node not in visited:
			successful = [True]
			visiting.add(node)
			for neighbor in graph[node]:
				successful.append(explore(neighbor, visited, visiting))
			visited.add(node)
			visiting.remove(node)
			ordering.insert(0, node)
			return all(successful)
		return True
	for start in graph:
		if not explore(start, visited, visiting):
			return 'Impossible'
	return ''.join(ordering)

def main():
	graph = build_graph()
	if graph == 'Impossible':
		print('Impossible')
		return
	print(topological_sort(graph))
main()


n = int(input())
names = [''] * n
l = [0] * n
for i in range(n):
	names[i] = input().strip()
	l[i] = len(names[i])
relations = [0] * n
proc = True
res = True
rels = [[0] * 26] * 26
for i in range(1, 26):
	rels[i] = list(rels[0])
j = 0
while proc and res:
	proc = False
	for i in range(n - 1):
		if relations[i] == 0:
			proc = True
			if l[i] > l[i + 1] and j == l[i + 1]:
				res = False
			elif j == l[i]:
				relations[i] = 1
			elif names[i][j] != names[i + 1][j]:
				x = ord(names[i][j]) - ord('a')
				y = ord(names[i + 1][j]) - ord('a')
				if rels[x][y] + rels[y][x] != 0 and rels[x][y] == 2:
					res = False
				else:
					rels[x][y] = 1
					rels[y][x] = 2
					relations[i] = 1
	j += 1
if res:
	ans = ''
	used = [0] * 26
	for i in range(26):
		found = -1
		for j in range(26):
			if used[j]:
				continue
			ok = True
			for x in rels[j]:
				if x == 1:
					ok = False
					break
			if ok:
				found = j
				break
		if found == -1:
			res = False
		else:
			c = chr(ord('a') + found)
			ans = c + ans
			used[found] = 1
			for j in range(26):
				if used[j] == 0 and rels[j][found] == 2:
					res = False
				else:
					rels[j][found] = 0
if res:
	print(ans)
else:
	print('Impossible')


import sys

def topo_dfs(adj_dict, visited, stack, topo_list):
	node = stack[-1]
	for e in adj_dict[node]:
		if visited[e] == False:
			stack.append(e)
			return
	topo_list.append(node)
	visited[node] = True
	stack.pop()
	return

def cycle_dfs(adj_dict, visited, stack):
	node = stack[-1]
	for e in adj_dict[node]:
		if visited[e] == False and e in stack:
			return True
		elif visited[e] == False:
			stack.append(e)
			return False
	visited[node] = True
	stack.pop()
	return False

def answer(n, s):
	adj_dict = {chr(i): [] for i in range(97, 123)}
	for i in range(n - 1):
		ctr = 0
		while s[i][ctr] == s[i + 1][ctr] and ctr < min(len(s[i]), len(s[i + 1])) - 1:
			ctr += 1
		if s[i][ctr] == s[i + 1][ctr]:
			if len(s[i]) > len(s[i + 1]):
				return 'Impossible'
			else:
				continue
		adj_dict[s[i][ctr]].append(s[i + 1][ctr])
	visited = {chr(i): False for i in range(97, 123)}
	for i in range(97, 123):
		if visited[chr(i)] == False:
			stack = [chr(i)]
			while len(stack) > 0:
				cycle = cycle_dfs(adj_dict, visited, stack)
				if cycle == True:
					return 'Impossible'
	visited = {chr(i): False for i in range(97, 123)}
	topo_list = []
	for i in range(97, 123):
		if visited[chr(i)] == False:
			stack = [chr(i)]
			while len(stack) > 0:
				topo_dfs(adj_dict, visited, stack, topo_list)
	topo_list.reverse()
	return ''.join(topo_list)

def main():
	n = int(sys.stdin.readline())
	s = ['' for _ in range(n)]
	for i in range(n):
		s[i] = sys.stdin.readline().rstrip()
	print(answer(n, s))
	return
main()


from collections import defaultdict, deque
from heapq import heappush, heappop
from math import inf
ri = lambda : map(int, input().split())
ro = lambda : int(input())

def solve():
	l = ro()
	A = [input() for _ in range(l)]
	available = set().union(*A)
	used = defaultdict(set)
	g = defaultdict(list)
	indegree = defaultdict(int)
	for i in range(l - 1):
		(first, second) = (A[i], A[i + 1])
		if first.startswith(second):
			print('Impossible')
			return
		(n, m) = (len(first), len(second))
		fst = snd = 0
		while fst < n and snd < m and (first[fst] == second[snd]):
			fst += 1
			snd += 1
		if fst < n and snd < m:
			if second[snd] not in used[first[fst]]:
				used[first[fst]].add(second[snd])
				g[first[fst]].append(second[snd])
				indegree[second[snd]] += 1
	q = deque()
	for c in available:
		if indegree[c] == 0:
			q.append(c)
	order = []
	while q:
		for _ in range(len(q)):
			c = q.popleft()
			order.append(c)
			for ne in g[c]:
				indegree[ne] -= 1
				if indegree[ne] == 0:
					q.append(ne)
	if len(order) != len(available):
		print('Impossible')
	else:
		for c in 'qwertyuiopasdfghjklzxcvbnm':
			if c not in available:
				print(c, end='')
		print(''.join(order))
t = 1
while t:
	t -= 1
	solve()


import queue

def topologicalSort(graph, result, V):
	indegree = [0] * V
	zero_indegree = queue.PriorityQueue()
	for u in range(V):
		for v in graph[u]:
			indegree[v] += 1
	for i in range(V):
		if indegree[i] == 0:
			zero_indegree.put(i)
	cnt = 0
	while not zero_indegree.empty():
		u = zero_indegree.get()
		result.append(u)
		for v in graph[u]:
			indegree[v] -= 1
			if indegree[v] == 0:
				zero_indegree.put(v)
		cnt += 1
	if cnt != V:
		return False
	return True
n = int(input())
graph = [[] for i in range(26)]
result = []
strings = []
for i in range(n):
	strings.append(input())
check = True
for i in range(1, n):
	flag = False
	_len = min(len(strings[i]), len(strings[i - 1]))
	for j in range(_len):
		if strings[i][j] != strings[i - 1][j]:
			flag = True
			graph[ord(strings[i - 1][j]) - ord('a')].append(ord(strings[i][j]) - ord('a'))
			break
	if len(strings[i]) < len(strings[i - 1]) and (not flag):
		print('Impossible')
		check = False
		break
if check:
	not_cycle = topologicalSort(graph, result, 26)
	if not not_cycle:
		print('Impossible')
	else:
		for i in result:
			print(chr(i + ord('a')), end='')
		print()


import os, sys
from io import BytesIO, IOBase

def iscycle(n, path):
	visi = [0] * n
	poi = [0] * n
	for i in range(n):
		if visi[i]:
			continue
		visi[i] = 2
		st = [i]
		while len(st):
			(x, y) = (st[-1], poi[st[-1]])
			if y == len(path[x]):
				visi[x] = 1
				st.pop()
			else:
				z = path[x][y]
				st.append(z)
				poi[x] += 1
				if visi[z] == 2:
					return 1
				visi[z] = 2
	return 0

def top_sort(n, path, indeg):
	ans = []
	for i in range(n):
		if not indeg[i]:
			ans.append(i)
	i = 0
	while i != len(ans):
		for x in path[ans[i]]:
			indeg[x] -= 1
			if not indeg[x]:
				ans.append(x)
		i += 1
	return ans

def main():
	n = int(input())
	word = [input().strip() for _ in range(n)]
	path = [set() for _ in range(26)]
	indeg = [0] * 26
	for i in range(n):
		for j in range(i + 1, n):
			fl = 0
			for x in range(min(len(word[i]), len(word[j]))):
				if word[i][x] != word[j][x]:
					fl = 1
					(a, b) = (ord(word[i][x]) - 97, ord(word[j][x]) - 97)
					if b not in path[a]:
						path[a].add(b)
						indeg[b] += 1
					break
			if not fl and len(word[i]) > len(word[j]):
				print('Impossible')
				exit()
	for i in range(26):
		path[i] = list(path[i])
	if iscycle(26, path):
		print('Impossible')
		exit()
	print(*map(lambda xx: chr(xx + 97), top_sort(26, path, indeg)), sep='')
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')
main()


from math import *
n = int(input())
s = []
le = 0
ts = set()
for i in range(n):
	t = input()
	le = max(le, len(t))
	s.append(t)
al = list('abcdefghijklmnopqrstuvwxyz')
g = {}
for i in al:
	g[i] = set()
hc = False
for i in range(1, le + 1):
	for j in range(n):
		if hc:
			break
		for k in range(j + 1, n):
			if s[j][:i] == s[k][:i] and len(s[j]) > len(s[k]) == i:
				hc = True
				break
			else:
				try:
					if s[j][:i - 1] == s[k][:i - 1] and s[j][i - 1] != s[k][i - 1]:
						g[s[k][i - 1]].add(s[j][i - 1])
				except:
					pass
	if hc:
		break
ans = []
d = {}
while len(ans) < 26:
	if hc:
		break
	for i in al:
		d[i] = 0
	for v in g:
		for u in g[v]:
			d[u] += 1
	c = 0
	for v in d:
		if d[v] == 0 and v not in ans:
			c += 1
			ans.append(v)
			g[v] = set()
	if c == 0:
		hc = True
		break
if hc:
	print('Impossible')
else:
	print(''.join(reversed(ans)))


import collections

def count_incoming_edges(graph):
	ret = collections.defaultdict(lambda : 0)
	for vs in graph.values():
		for v in vs:
			ret[v] += 1
	return ret

def topsort(edges, verts):
	sorted = []
	incoming_edges = count_incoming_edges(edges)
	S = collections.deque([v for v in verts if incoming_edges[v] == 0])
	while len(S) != 0:
		u = S.popleft()
		sorted.append(u)
		for v in edges[u]:
			assert incoming_edges[v] > 0
			incoming_edges[v] -= 1
			if incoming_edges[v] == 0:
				S.append(v)
		del edges[u]
	return sorted if len(edges) == 0 else None

def gen_constraint(a, b):
	if a in b or b in a:
		return None
	shorter = min(len(a), len(b))
	for i in range(shorter):
		ca = a[i]
		cb = b[i]
		if ca != cb:
			return (ca, cb)
	raise RuntimeError('should always find a difference!')

def main():
	num_names = int(input())
	names = []
	for _ in range(num_names):
		names.append(input())
	edges = collections.defaultdict(set)
	for i in range(len(names)):
		for j in range(i + 1, len(names)):
			a = names[i]
			b = names[j]
			constraint = gen_constraint(a, b)
			if constraint:
				(u, v) = constraint
				edges[u].add(v)
	all_letters = list(map(chr, range(ord('a'), ord('z') + 1)))
	if len(edges) == 0:
		sorted_names = list(names)
		names.sort()
		if sorted_names == names:
			print(''.join(all_letters))
		else:
			print('Impossible')
		return
	res = topsort(edges, all_letters)
	if res:
		print(''.join(res))
	else:
		print('Impossible')
main()


import os.path
from math import gcd, floor, ceil
from collections import *
import sys
mod = 1000000007
INF = float('inf')

def st():
	return list(sys.stdin.readline().strip())

def li():
	return list(map(int, sys.stdin.readline().split()))

def mp():
	return map(int, sys.stdin.readline().split())

def inp():
	return int(sys.stdin.readline())

def pr(n):
	return sys.stdout.write(str(n) + '\n')

def prl(n):
	return sys.stdout.write(str(n) + ' ')
if os.path.exists('input.txt'):
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')

def solve():
	n = inp()
	deg = {chr(i): 0 for i in range(97, 97 + 26)}
	q = deque()
	ans = []
	l = [st() for i in range(n)]
	graph = defaultdict(list)
	for i in range(n - 1):
		(a, b) = (l[i], l[i + 1])
		j = 0
		x = min(len(a), len(b))
		while j < x and a[j] == b[j]:
			j += 1
		if j < x:
			graph[a[j]].append(b[j])
			deg[b[j]] += 1
		elif j >= len(b):
			pr('Impossible')
			return
	for i in deg:
		if deg[i] == 0:
			q.append(i)
	while q:
		a = q.popleft()
		ans.append(a)
		for i in graph[a]:
			deg[i] -= 1
			if deg[i] == 0:
				q.append(i)
	if len(ans) != 26:
		pr('Impossible')
	else:
		print(''.join(ans))
for _ in range(1):
	solve()


import string
from collections import defaultdict

def solve(n, s):
	g = defaultdict(set)
	edges = []
	for i in range(n - 1):
		condition = None
		for (ca, cb) in zip(s[i], s[i + 1]):
			if ca == cb:
				continue
			condition = (ca, cb)
			break
		if condition is None:
			if len(s[i]) > len(s[i + 1]):
				return None
			continue
		(parent, child) = condition
		edges.append((parent, child))
		g[parent].add(child)
	visited = set()

	def gen_topology(e):
		if e in visited:
			return
		visited.add(e)
		if e in g:
			for next in g[e]:
				if next in visited:
					continue
				gen_topology(next)
		stack.append(e)
	stack = []
	for e in g.keys():
		if e in visited:
			continue
		gen_topology(e)
	weight = {}
	for (i, e) in enumerate(stack[::-1]):
		weight[e] = i
	for (parent, child) in edges:
		if weight[parent] > weight[child]:
			return None
	r = stack[::-1]
	for e in string.ascii_lowercase:
		if e not in r:
			r.append(e)
	return r
n = int(input())
s = [input() for _ in range(n)]
r = solve(n, s)
if not r:
	print('Impossible')
else:
	print(''.join(r))


import sys
from collections import deque
sys.setrecursionlimit(20000)
adj = [[] for j in range(27)]
indegree = [0 for i in range(27)]

def exits():
	print('Impossible')
	exit(0)

def is_prefix(a, b):
	if len(a) >= len(b):
		return False
	if a == b[:len(a)]:
		return True
	return False

def main():
	(q, cnt, ans) = (deque(), 0, '')
	n = int(input())
	l = [input() for i in range(n)]
	for i in range(n - 1):
		if is_prefix(l[i + 1], l[i]):
			exits()
		if is_prefix(l[i], l[i + 1]):
			continue
		for j in range(min(len(l[i]), len(l[i + 1]))):
			if l[i][j] != l[i + 1][j]:
				(c1, c2) = (ord(l[i][j]) - 97, ord(l[i + 1][j]) - 97)
				adj[c1].append(c2)
				indegree[c2] += 1
				break
	for i in range(26):
		if indegree[i] == 0:
			q.append(i)
	while cnt < 26:
		if len(q) == 0:
			exits()
		curr = q.popleft()
		ans += chr(curr + 97)
		cnt += 1
		for i in adj[curr]:
			indegree[i] -= 1
			if indegree[i] == 0:
				q.append(i)
	print(ans)
main()


__author__ = 'Utena'
n = int(input())
e = []

def cmp(a, b):
	for i in range(min(len(a), len(b))):
		if a[i] != b[i]:
			e.append((a[i], b[i]))
			return 0
	if len(a) > len(b):
		print('Impossible')
		exit(0)

def indegree0(v, e):
	if v == []:
		return None
	tmp = v[:]
	for i in e:
		if i[1] in tmp:
			tmp.remove(i[1])
	tmp = tmp[:1]
	if tmp == []:
		return -1
	for t in tmp:
		for i in range(len(e)):
			if t in e[i]:
				e[i] = (0, 0)
	if e:
		eset = set(e)
		if (0, 0) in eset:
			eset.remove((0, 0))
		e[:] = list(eset)
	if v:
		for t in tmp:
			v.remove(t)
	return tmp

def topoSort(v, e):
	result = []
	while True:
		nodes = indegree0(v, e)
		if nodes == None:
			break
		if nodes == -1:
			print('Impossible')
			return None
		result.extend(nodes)
	print(''.join(map(str, result)))
	return result
names = []
for i in range(n):
	names.append(input())
for i in range(n - 1):
	cmp(names[i], names[i + 1])
afs = [chr(i) for i in range(97, 123)]
topoSort(afs, e)


import string

def generate_graph(words):
	edge_map = {}
	rev_map = {}
	for c in string.ascii_lowercase:
		edge_map[c] = set()
		rev_map[c] = set()
	for i in range(len(words) - 1):
		for k in range(min(len(words[i]), len(words[i + 1]))):
			if words[i][k] != words[i + 1][k]:
				edge_map[words[i][k]].add(words[i + 1][k])
				rev_map[words[i + 1][k]].add(words[i][k])
				break
			elif k == min(len(words[i]), len(words[i + 1])) - 1:
				if len(words[i]) > len(words[i + 1]):
					return (None, None)
	return (edge_map, rev_map)

def get_order(edge_map, rev_map):
	out_counts = dict([(k, len(edge_map[k])) for k in edge_map])
	zero_keys = set()
	for k in out_counts:
		if out_counts[k] == 0:
			zero_keys.add(k)
	order = []
	while len(zero_keys) > 0:
		v = zero_keys.pop()
		order.append(v)
		for k in rev_map[v]:
			out_counts[k] -= 1
			if out_counts[k] == 0:
				zero_keys.add(k)
	order.reverse()
	if len(order) < len(edge_map):
		return ['Impossible']
	else:
		return order
n = int(input())
words = []
for i in range(n):
	word = input().strip(' ')
	words.append(word)
(edge_map, rev_map) = generate_graph(words)
if edge_map is not None:
	print(''.join(get_order(edge_map, rev_map)))
else:
	print('Impossible')


from collections import defaultdict, Counter
G = defaultdict(set)
names = [input() for _ in range(int(input()))]
last = names[0]
has_in = Counter()
total = set([])
impossible = False
for name in names[1:]:
	i = 0
	while i < len(name) and i < len(last) and (last[i] == name[i]):
		i += 1
	if i < len(name) and i < len(last):
		G[last[i]].add(name[i])
		has_in[name[i]] += 1
		total.add(last[i])
		total.add(name[i])
	elif len(last) > len(name):
		impossible = True
		break
	last = name
if impossible:
	print('Impossible')
else:
	alphabet = []

	def hierholzers(curr):
		while G[curr]:
			next = G[curr].pop()
			has_in[next] -= 1
			hierholzers(next)
		if not curr in alphabet:
			alphabet.append(curr)
	keys = list(G.keys())
	for g in keys:
		if has_in[g] <= 0:
			hierholzers(g)
	import random
	if not alphabet and G or len(alphabet) != len(total):
		print('Impossible')
	else:
		alphabet = list(reversed(alphabet))
		for ch in range(ord('a'), ord('z') + 1):
			for ch in range(ord('a'), ord('z') + 1):
				for ch in range(ord('a'), ord('z') + 1):
					if not chr(ch) in alphabet:
						if random.randint(1, 10) > 5:
							alphabet = [chr(ch)] + alphabet
						else:
							alphabet.append(chr(ch))
		print(''.join(alphabet))


from collections import defaultdict
n = int(input())
g = defaultdict(list)
names = []
for _ in range(n):
	names.append(input())
for i in range(1, n):
	j = 0
	while j < len(names[i]) and j < len(names[i - 1]) and (names[i - 1][j] == names[i][j]):
		j += 1
	if j >= len(names[i]):
		print('Impossible')
		exit()
	if j >= len(names[i - 1]):
		continue
	g[ord(names[i - 1][j]) - ord('a')].append(ord(names[i][j]) - ord('a'))

def toposort(i, visited, stack):
	visited[i] = 1
	for ajd in g[i]:
		if visited[ajd] == 1:
			print('Impossible')
			exit()
		if visited[ajd] == 0:
			toposort(ajd, visited, stack)
	visited[i] = 2
	stack.append(i)
stack = []
visited = [0 for _ in range(26)]
for i in range(26):
	if len(g[i]) and (not visited[i]):
		toposort(i, visited, stack)
print(''.join((chr(el + ord('a')) for el in stack[::-1])) + ''.join((chr(i + ord('a')) for i in range(26) if i not in stack)))


import string

def f(words):

	def dfs(node):
		color[node] = 'g'
		for child in g[node]:
			if color[child] == 'b':
				continue
			elif color[child] == 'g':
				return False
			elif dfs(child):
				continue
			else:
				return False
		color[node] = 'b'
		order.append(node)
		return True
	g = {}
	for char in string.ascii_lowercase:
		g[char] = set()
	for i in range(n - 1):
		j = 0
		while j < min(len(words[i]), len(words[i + 1])) and words[i][j] == words[i + 1][j]:
			j += 1
		if j == len(words[i]) or j == len(words[i + 1]):
			if len(words[i]) <= len(words[i + 1]):
				continue
			else:
				return (False, [])
		else:
			g[words[i][j]].add(words[i + 1][j])
	order = []
	color = {node: 'w' for node in g}
	for node in g:
		if color[node] == 'w':
			if dfs(node):
				continue
			else:
				return (False, [])
	return (True, order[::-1])
n = int(input())
words = []
for i in range(n):
	words.append(input())
(possible, order) = f(words)
if possible:
	print(''.join(order))
else:
	print('Impossible')


import os
import sys
from io import BytesIO, IOBase
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')
import sys
import math
from math import gcd
import bisect
a = [0] * 26
from collections import deque
n = int(input())
g = [set() for i in range(26)]
a = input()
v = [0] * 26
for i in range(1, n):
	b = input()
	j = 0
	while j < min(len(a), len(b)) and a[j] == b[j]:
		j += 1
	if j < min(len(a), len(b)) and a[j] != b[j]:
		g[ord(a[j]) - 97].add(ord(b[j]) - 97)
	elif len(a) > len(b):
		print('Impossible')
		exit()
	a = b
ans = []

def dfs(s):
	v[s] = 1
	for j in g[s]:
		if v[j] == 1:
			print('Impossible')
			exit()
		if v[j] == 0:
			dfs(j)
	v[s] = 2
	ans.append(chr(s + 97))
for i in range(26):
	if v[i] == 0:
		dfs(i)
print(''.join(reversed(ans)))


def char2num(c):
	return ord(c) - ord('a')

def dfs(v):
	vis[v] = 0
	for w in adj[v]:
		if vis[w] == 0:
			return False
		elif vis[w] == -1:
			if not dfs(w):
				return False
	alf.append(v)
	vis[v] = 1
	return True
(n, last) = (int(input()), input())
adj = [[] for _ in range(26)]
for _ in range(1, n):
	next_ = input()
	if last.startswith(next_):
		print('Impossible')
		break
	if not next_.startswith(last):
		i = 0
		while next_[i] == last[i]:
			i += 1
		adj[char2num(last[i])].append(char2num(next_[i]))
	last = next_[:]
else:
	alf = []
	vis = [-1] * 26
	for i in range(26):
		if vis[i] == -1:
			if not dfs(i):
				print('Impossible')
				break
	else:
		print(*list([chr(ord('a') + i) for i in reversed(alf)]), sep='')


imp = False
nodes = {}
for i in 'abcdefghijklmnopqrstuvwxyz':
	nodes[i] = set()
n = int(input())
prev = None
for i in range(n):
	name = input()
	if prev:
		for (x, y) in zip(name, prev):
			if x != y:
				nodes[x].add(y)
				break
		else:
			if prev > name:
				imp = True
				break
	prev = name
q = []
r = []
for i in 'abcdefghijklmnopqrstuvwxyz':
	if not nodes[i]:
		q.append(i)
	else:
		r.append(i)
l = []
while q:
	e = q.pop()
	l.append(e)
	for i in r[:]:
		if e in nodes[i]:
			nodes[i].remove(e)
			if not nodes[i]:
				q.append(i)
				r.remove(i)
if r or imp:
	print('Impossible')
else:
	print(''.join(l))


import string
__author__ = 'artyom'
graph = dict(((c, set()) for c in string.ascii_lowercase))
ordered = []
visited = set()
in_stack = dict(((c, 0) for c in string.ascii_lowercase))

def dfs(v):
	visited.add(v)
	in_stack[v] = 1
	for u in graph[v]:
		if in_stack[u]:
			print('Impossible')
			exit()
		if u not in visited:
			dfs(u)
	in_stack[v] = 0
	ordered.append(v)
n = int(input())
names = [input() for _ in range(n)]
lengths = [len(name) for name in names]
for i in range(n - 1):
	m = min(lengths[i], lengths[i + 1])
	for j in range(m):
		(u, v) = (names[i][j], names[i + 1][j])
		if u != v:
			graph[u].add(v)
			break
	else:
		if lengths[i] > m:
			print('Impossible')
			exit()
for v in graph.keys():
	if v not in visited:
		dfs(v)
print(''.join(reversed(ordered)))


import collections as cc
import sys
input = sys.stdin.readline
I = lambda : list(map(int, input().split()))
(n,) = I()
ar = []
incoming = {}
for i in range(n):
	l = list(input().strip())
	ar.append(l)
for i in 'abcdefghijklmnopqrstuvwxyz':
	incoming[i] = 0
ch = set()
diff = False
graph = cc.defaultdict(set)
for i in range(1, len(ar)):
	for j in range(min(len(ar[i - 1]), len(ar[i]))):
		if ar[i - 1][j] != ar[i][j]:
			graph[ar[i - 1][j]].add(ar[i][j])
			if (ar[i - 1][j], ar[i][j]) not in ch:
				ch.add((ar[i - 1][j], ar[i][j]))
				incoming[ar[i][j]] += 1
				diff = True
			break
	if not diff and len(ar[i - 1]) > len(ar[i]):
		print('Impossible')
		sys.exit()
res = []
q = cc.deque()
for i in 'abcdefghijklmnopqrstuvwxyz':
	if incoming.get(i, 0) == 0:
		q.append(i)
visited = set()
while q:
	v = q.popleft()
	visited.add(v)
	res.append(v)
	for i in graph[v]:
		if incoming[i] > 0:
			incoming[i] -= 1
		if incoming[i] == 0:
			q.append(i)
if len(res) == 26:
	print(''.join(res))
else:
	print('Impossible')


def ex():
	print('Impossible')
	exit()
abc = 'abcdefghijklmnopqrstuvwxyz'
edges = {i: set() for i in abc}
used = set()

def fillchar(name, prev_name):
	for (current, prev) in zip(name, prev_name):
		if current != prev:
			if current in edges[prev]:
				ex()
			if prev not in edges[current]:
				edges[current].add(prev)
			return True
	return False
n = int(input())
prev_name = input()
for i in range(1, n):
	name = input()
	if not fillchar(name, prev_name) and len(prev_name) > len(name):
		ex()
	prev_name = name

def dfs(v, result):
	used.add(v)
	for c in edges[v]:
		if c not in used:
			dfs(c, result)
	result.append(v)

def topsort():
	result = []
	for c in abc:
		if c not in used:
			dfs(c, result)
	return result
result = topsort()
for node in edges:
	for edge in edges[node]:
		if result.index(node) < result.index(edge):
			ex()
print(''.join(result))


import string
import sys
input = sys.stdin.readline

def getInts():
	return [int(s) for s in input().split()]

def getInt():
	return int(input())

def getStrs():
	return [s for s in input().split()]

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

def listStr():
	return list(input().strip())
import collections as col
import math, itertools

def getFirstDiff(s1, s2):
	while s1 and s2:
		(l1, l2) = (s1[0], s2[0])
		if l1 != l2:
			return (l1, l2)
		(s1, s2) = (s1[1:], s2[1:])
	return (None, None)

def solve():
	nodes = set(list(string.ascii_lowercase))
	roots = []
	parents = col.defaultdict(set)

	def bfs(graph, node, queue, visited_dict, nodes):
		pref = '1'
		visited_dict[node] = pref
		nodes.remove(node)
		queue.append((node, pref))
		queue = col.deque(queue)
		cycle = False
		while queue:
			(s, pref) = queue.popleft()
			tmp = 0
			for neighbour in graph[s]:
				if neighbour in visited_dict:
					pref1 = visited_dict[neighbour]
					x = len(pref)
					if pref == pref1[:len(pref)]:
						cycle = True
				if neighbour not in visited_dict and neighbour in nodes:
					tmp += 1
					visited_dict[neighbour] = pref + str(tmp)
					nodes.remove(neighbour)
					queue.append((neighbour, pref + str(tmp)))
		return (cycle, nodes)
	N = getInt()
	children = col.defaultdict(set)
	for letter in nodes:
		children[letter] = set()
		parents[letter] = set()
	names = []
	for n in range(N):
		names.append(getStr())
	for j in range(N - 1):
		(a, b) = getFirstDiff(names[j], names[j + 1])
		if a is None:
			if len(names[j]) > len(names[j + 1]):
				if names[0] == 'adjcquqdqcsvixgwglwrrmkhdsbebbjvcgz':
					print('Hi')
				return 'Impossible'
			continue
		children[a].add(b)
		parents[b].add(a)
	ans = ''
	for child in parents:
		if len(parents[child]) == 0:
			roots.append(child)
	roots2 = list(roots)
	while roots:
		node = roots.pop()
		(cycle, nodes) = bfs(children, node, [], {}, nodes)
		if cycle:
			return 'Impossible'
	nodes = set(list(string.ascii_lowercase))

	def reverse_post_order(graph, root):
		visited = set()
		order = []

		def dfs_walk(node):
			visited.add(node)
			if node in nodes:
				nodes.remove(node)
			for neighbour in graph[node]:
				if neighbour in nodes and neighbour not in visited:
					dfs_walk(neighbour)
			order.append(node)
		dfs_walk(root)
		return order[::-1]
	while roots2:
		node = roots2.pop()
		visited = reverse_post_order(children, node)
		ans = ''.join(visited) + ans
	if len(ans) < 26:
		return 'Impossible'
	return ans
print(solve())


n = int(input())
ss = [input() for i in range(n)]
graph = set()

def rec(fr=0, to=len(ss) - 1, dep=0):
	if fr == to:
		return
	pos = fr
	while pos <= to:
		i = pos
		while 1 + i <= to and len(ss[i]) > dep and (len(ss[1 + i]) > dep) and (ss[i][dep] == ss[1 + i][dep]):
			i += 1
		for t in range(1 + pos, 1 + i):
			if len(ss[t - 1]) > 1 + dep and len(ss[t]) > 1 + dep:
				(t1, t2) = (ss[t - 1][1 + dep], ss[t][1 + dep])
				if t1 != t2:
					t3 = (t1, t2)
					graph.add(t3)
		rec(pos, i, 1 + dep)
		pos = 1 + i
	for t in range(1 + fr, 1 + to):
		if len(ss[t - 1]) > dep and len(ss[t]) > dep:
			(t1, t2) = (ss[t - 1][dep], ss[t][dep])
			if t1 != t2:
				t3 = (t1, t2)
				graph.add(t3)
for i in range(n):
	for j in range(1 + i, n):
		if ss[i].startswith(ss[j]) and ss[i] != ss[j]:
			print('Impossible')
			exit()
rec()
deg = dict()
for (c1, c2) in graph:
	if c2 not in deg:
		deg[c2] = 0
	deg[c2] += 1
k = 0
ans = ''
for i in range(26):
	for c in 'abcdefghijklmnopqrstuvwxyz':
		if c not in deg or deg[c] == 0:
			deg[c] = -1
			ans += c
			k += 1
			for (c1, c2) in graph:
				if c1 == c:
					deg[c2] -= 1
if k != 26:
	print('Impossible')
else:
	print(ans)


n = int(input())
s = [input() for i in range(n)]
m = [[0] * 26 for i in range(26)]
f = lambda x: ord(x) - ord('a')
for i in range(n - 1):
	for (ch1, ch2) in zip(s[i], s[i + 1]):
		if ch1 != ch2:
			m[f(ch1)][f(ch2)] = 1
			break
	else:
		if len(s[i]) > len(s[i + 1]):
			print('Impossible')
			exit()
indeg = [sum((m[j][i] for j in range(26))) for i in range(26)]
added = [0] * 26
ans = []
while 1:
	for i in range(26):
		if indeg[i] == 0 and (not added[i]):
			ans.append(chr(i + ord('a')))
			added[i] = 1
			for j in range(26):
				if m[i][j]:
					m[i][j] = 0
					indeg[j] -= 1
			break
	else:
		break
if any(indeg):
	print('Impossible')
	exit()
print(''.join(ans))


import sys

def left(c):
	return ord(c) - ord('a')

def right(x):
	return chr(ord('a') + x)
n = int(input())
names = []
for i in range(n):
	names.append(input())
graph = [[] for i in range(26)]
arrowCounter = [0 for i in range(26)]
for i in range(n):
	for j in range(i):
		counter = 0
		zipped = list(zip(names[i], names[j]))
		for entry in zipped:
			if entry[0] != entry[1]:
				break
			else:
				counter += 1
		if counter == len(names[i]) or counter == len(names[j]):
			if len(names[j]) > len(names[i]):
				print('Impossible')
				sys.exit(0)
		else:
			graph[left(zipped[counter][1])].append(left(zipped[counter][0]))
			arrowCounter[left(zipped[counter][0])] += 1
noArrows = []
for i in range(26):
	if arrowCounter[i] == 0:
		noArrows.append(i)
order = []
while len(noArrows) != 0:
	current = noArrows.pop()
	order.append(current)
	for endpoint in graph[current]:
		arrowCounter[endpoint] -= 1
		if arrowCounter[endpoint] == 0:
			noArrows.append(endpoint)
if len(order) != 26:
	print('Impossible')
else:
	answer = ''
	for i in range(26):
		answer += right(order[i])
	print(answer)


import string
import sys
input = sys.stdin.readline

def getInts():
	return [int(s) for s in input().split()]

def getInt():
	return int(input())

def getStrs():
	return [s for s in input().split()]

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

def listStr():
	return list(input().strip())
import collections as col
import math, itertools
nodes = list(string.ascii_lowercase)

def getFirstDiff(s1, s2):
	while s1 and s2:
		(l1, l2) = (s1[0], s2[0])
		if l1 != l2:
			return (l1, l2)
		(s1, s2) = (s1[1:], s2[1:])
	return (None, None)

def solve():

	def bfs(graph, visited, node, queue, nodes):
		visited.add(node)
		nodes.remove(node)
		queue.append(node)
		queue = col.deque(queue)
		while queue:
			s = queue.popleft()
			for neighbour in graph[s]:
				if neighbour not in visited:
					visited.add(neighbour)
					nodes.remove(neighbour)
					queue.append(neighbour)
		return (visited, nodes)
	N = getInt()
	a = set()
	children = col.defaultdict(set)
	for letter in nodes:
		children[letter] = set()
	names = []
	for n in range(N):
		names.append(getStr())
	for j in range(N - 1):
		(a, b) = getFirstDiff(names[j], names[j + 1])
		if a is None:
			if len(names[j]) > len(names[j + 1]):
				return 'Impossible'
			continue
		children[a].add(b)
	for x in children:
		for y in children[x]:
			for z in children:
				if x in children[z] and y != z:
					children[z].add(y)
	for x in children:
		for y in children[x]:
			if x in children[y]:
				return 'Impossible'
	ans = ''
	for x in children:
		index = 0
		for y in ans:
			if x in children[y]:
				index = max(index, ans.find(y) + 1)
		ans = ans[:index] + x + ans[index:]
	return ans
print(solve())


n = int(input())
nrLit = ord('z') - ord('a') + 1
v = [[0 for i in range(nrLit)] for j in range(nrLit)]
s0 = input()
posibil = True
for i in range(1, n):
	if not posibil:
		break
	s = input()
	mini = min(len(s0), len(s))
	for j in range(mini):
		a = ord(s0[j]) - ord('a')
		b = ord(s[j]) - ord('a')
		if s0[j] != s[j]:
			if v[a][b] <= 0 and v[b][a] >= 0:
				v[a][b] = -1
				v[b][a] = 1
				for k in range(nrLit):
					if v[k][a] == -1:
						if v[b][k] >= 0:
							v[k][b] = -1
							v[b][k] = 1
						else:
							posibil = False
			else:
				posibil = False
			break
	else:
		if s0 > s:
			posibil = False
	s0 = s
if not posibil:
	print('Impossible')
else:
	marcat = set()
	s = ''
	for lit in range(nrLit):
		for i in range(nrLit):
			if i in marcat:
				continue
			for j in range(nrLit):
				if v[i][j] == 1 and j not in marcat:
					break
			else:
				s = s + chr(i + ord('a'))
				marcat.add(i)
				break
	print(s)


from collections import deque

class Graph(object):

	def __init__(self, n, d):
		self.n = n
		self.graph = [[] for i in range(n)]
		self.parent = [-1 for i in range(n)]
		self.directed = d

	def addEdge(self, x, y):
		self.graph[x].append(y)
		if not self.directed:
			self.graph[y].append(x)

	def bfs(self, root):
		queue = [root]
		queue = deque(queue)
		vis = [0] * self.n
		while len(queue) != 0:
			element = queue.popleft()
			vis[element] = 1
			for i in self.graph[element]:
				if vis[i] == 0:
					queue.append(i)
					self.parent[i] = element
					vis[i] = 1

	def dfs(self, root, ans):
		stack = [root]
		vis = [0] * self.n
		stack2 = []
		while len(stack) != 0:
			element = stack.pop()
			if vis[element]:
				continue
			vis[element] = 1
			stack2.append(element)
			for i in self.graph[element]:
				if vis[i] == 0:
					self.parent[i] = element
					stack.append(i)
		while len(stack2) != 0:
			element = stack2.pop()
			m = 0
			for i in self.graph[element]:
				if i != self.parent[element]:
					m += ans[i]
			ans[element] = m
		return ans

	def shortestpath(self, source, dest):
		self.bfs(source)
		path = [dest]
		while self.parent[path[-1]] != -1:
			path.append(parent[path[-1]])
		return path[::-1]

	def detect_cycle(self):
		indeg = [0] * self.n
		for i in range(self.n):
			for j in self.graph[i]:
				indeg[j] += 1
		q = deque()
		vis = 0
		for i in range(self.n):
			if indeg[i] == 0:
				q.append(i)
		ans = []
		while len(q) != 0:
			e = q.popleft()
			vis += 1
			ans.append(e)
			for i in self.graph[e]:
				indeg[i] -= 1
				if indeg[i] == 0:
					q.append(i)
		if vis != self.n:
			return True
		return ans
		return False

	def reroot(self, root, ans):
		stack = [root]
		vis = [0] * n
		while len(stack) != 0:
			e = stack[-1]
			if vis[e]:
				stack.pop()
				continue
			vis[e] = 1
			for i in graph[e]:
				if not vis[e]:
					stack.append(i)
			if self.parent[e] == -1:
				continue

	def topsort(self):
		if self.detect_cycle():
			return False
		ans = []
		vis = [0] * self.n
		done = {}
		indeg = [0] * self.n
		for i in range(self.n):
			for j in self.graph[i]:
				indeg[j] += 1
		stack = []
		for i in range(self.n):
			if indeg[i] == 0:
				stack.append(i)
		while len(stack) != 0:
			e = stack.pop()
			if vis[e]:
				continue
			ans.append(e)
			done[e] = 1
			vis[e] = 1
			for i in self.graph[e]:
				if not vis[i]:
					stack.append(i)
		for i in range(self.n):
			if i not in done:
				ans.append(i)
		return ans
n = int(input())
g = Graph(26, True)
done = {}
s = input()
start = s
for i in range(n - 1):
	x = input()
	j = 0
	while j < min(len(s), len(x)) and s[j] == x[j]:
		j += 1
	if j == len(x) and len(s) > len(x):
		print('Impossible')
		exit()
	if j == len(s):
		continue
	if (ord(s[j]), ord(x[j])) not in done:
		g.addEdge(ord(s[j]) - 97, ord(x[j]) - 97)
		done[ord(s[j]), ord(x[j])] = 1
	s = x
order = g.detect_cycle()
if order == True:
	print('Impossible')
	exit()
ans = ''
for i in order:
	ans += chr(i + 97)
print(ans)


import sys
input = sys.stdin.readline

def toposort(graph):
	(searched, stack) = (set(), [])
	for node in graph:
		if node not in searched:
			toposort_recurse(graph, node, searched, stack)
	return stack[::-1]

def toposort_recurse(graph, node, searched, stack):
	searched.add(node)
	for peer in graph[node]:
		if peer not in searched:
			toposort_recurse(graph, peer, searched, stack)
	stack.append(node)

def toposort_check(graph, path):
	for node in graph:
		for peer in graph[node]:
			if path.index(peer) < path.index(node):
				return False
	return True
(graph, n, prev, curr) = ({char: [] for char in 'abcdefghijklmnopqrstuvwxyz'}, int(input()), input().strip(), '')
for i in range(n - 1):
	old_curr = curr = input().strip()
	while len(prev) > 0 and len(curr) > 0 and (curr[0] == prev[0]):
		(curr, prev) = (curr[1:], prev[1:])
	if curr and prev:
		graph[prev[0]].append(curr[0])
	elif prev and (not curr):
		print('Impossible')
		sys.exit(0)
	prev = old_curr
path = toposort(graph)
if toposort_check(graph, path):
	print(''.join(path))
else:
	print('Impossible')


import string
n = int(input())
strs = []
for _ in range(n):
	strs.append(input())

def get_lex_cmp(str1, str2):
	for i in range(min(len(str1), len(str2))):
		if str1[i] != str2[i]:
			return (str1[i], str2[i])
	if len(str1) > len(str2):
		print('Impossible')
		exit()
	else:
		return (None, None)
children = dict(zip(string.ascii_lowercase, [[] for _ in range(26)]))
parents = dict(zip(string.ascii_lowercase, [[] for _ in range(26)]))
for i in range(n - 1):
	(u, v) = get_lex_cmp(strs[i], strs[i + 1])
	if u and v:
		if v not in children[u]:
			children[u].append(v)
			parents[v].append(u)
vertices = children.keys()
ordering = []
S = []
for u in parents:
	if not parents[u]:
		S.append(u)
while S:
	u = S.pop()
	ordering.append(u)
	for v in children[u]:
		parents[v].remove(u)
		if not parents[v]:
			S.append(v)
	children[u] = []
for u in children:
	if children[u]:
		print('Impossible')
		exit()
print(''.join(ordering))


vis = [0] * 26
ans = []
graph = [[] for _ in range(26)]
A = ord('a')

def topo(i):
	s = [i]
	while s:
		i = s.pop()
		if vis[i] == 0:
			s.append(i)
			vis[i] = 1
			for j in graph[i]:
				if vis[j] == 1:
					return False
				elif vis[j] == 0:
					s.append(j)
		elif vis[i] == 1:
			vis[i] = 2
			ans.append(chr(i + A))
	return True

def topo1(i):
	vis[i] = 1
	for j in graph[i]:
		if vis[j] == 1:
			return False
		elif vis[j] == 0:
			if not topo(j):
				return False
	vis[i] = 2
	ans.append(chr(i + A))
	return True

def solve():
	t = int(input())
	names = []
	for _ in range(t):
		names.append(input())
	exist = True
	for k in range(t - 1):
		i = 0
		while True:
			if len(names[k]) == i:
				break
			elif len(names[k + 1]) == i:
				exist = False
				break
			elif names[k][i] != names[k + 1][i]:
				(a, b) = (ord(names[k][i]) - A, ord(names[k + 1][i]) - A)
				graph[a].append(b)
				break
			else:
				i += 1
	if exist:
		for i in range(26):
			if vis[i] == 0:
				exist = topo(i)
			if not exist:
				break
		if exist:
			print(''.join(reversed(ans)))
	if not exist:
		print('Impossible')
solve()


n = int(input())
seti = [set() for _ in range(26)]
vis = [0] * 26
a = input()
ans = []
for i in range(n - 1):
	b = input()
	j = 0
	while j < min(len(a), len(b)) and a[j] == b[j]:
		j += 1
	if j < min(len(a), len(b)) and a[j] != b[j]:
		seti[ord(a[j]) - ord('a')].add(ord(b[j]) - ord('a'))
	elif len(a) > len(b):
		print('Impossible')
		exit()
	a = b

def dfs(node):
	vis[node] = 1
	for i in seti[node]:
		if vis[i] == 1:
			print('Impossible')
			exit()
		if vis[i] == 0:
			dfs(i)
	vis[node] = 2
	ans.append(chr(node + ord('a')))
for i in range(26):
	if vis[i] == 0:
		dfs(i)
print(''.join(reversed(ans)))


import string

def main():
	n = int(input())
	broke = False
	comparar = ''
	letras = {}
	alfabeto = list(string.ascii_lowercase)
	c = 0
	for i in alfabeto:
		letras[i] = set()
	for _ in range(n):
		nombre = input()
		if c > 0:
			for (i, j) in zip(nombre, comparar):
				if i != j:
					letras[i].add(j)
					broke = True
					break
			if broke == False and comparar > nombre:
				return 'Impossible'
		comparar = nombre
		c += 1
	a = []
	for (key, value) in letras.items():
		if len(value) == 0:
			a.append(key)
	b = list(set(alfabeto) - set(a))
	b.sort()
	sol = []
	while len(a) > 0:
		d = a.pop()
		sol.append(d)
		for i in b[:]:
			if d in letras[i]:
				letras[i].remove(d)
				if len(letras[i]) == 0:
					a.append(i)
					b.remove(i)
	if len(b) > 0:
		return 'Impossible'
	return ''.join(sol)
print(main())


import heapq

def kahn(graph):
	V = len(graph)
	in_degree = [0] * V
	for i in range(V):
		for j in graph[i]:
			in_degree[j] += 1
	zero_in_degree = []
	for i in range(V):
		if in_degree[i] == 0:
			heapq.heappush(zero_in_degree, i)
	result = []
	while zero_in_degree:
		u = heapq.heappop(zero_in_degree)
		result.append(chr(u + 97))
		for i in graph[u]:
			in_degree[i] -= 1
			if in_degree[i] == 0:
				heapq.heappush(zero_in_degree, i)
	return result

def solution():
	V = 26
	E = int(input())
	graph = [[] for i in range(V)]
	names = []
	for i in range(E):
		names.append(input().strip())
	for i in range(E - 1):
		min_length = min(len(names[i]), len(names[i + 1]))
		found = False
		for j in range(min_length):
			if names[i][j] != names[i + 1][j]:
				found = True
				graph[ord(names[i][j]) - 97].append(ord(names[i + 1][j]) - 97)
				break
		if not found and len(names[i]) > len(names[i + 1]):
			print('Impossible')
			return
	result = kahn(graph)
	if len(result) < V:
		print('Impossible')
	else:
		print(*result, sep='')
solution()


from collections import defaultdict as dfdict

def make_graph(n, lists):
	for i in range(n - 1):
		(la, lb) = (len(lists[i]), len(lists[i + 1]))
		lmin = min(la, lb)
		m = -1
		while m + 1 < lmin:
			if lists[i][m + 1] == lists[i + 1][m + 1]:
				m += 1
			else:
				break
		if m + 1 == lmin:
			if lmin == lb:
				orders[lists[i][m + 1]].add('mysterious')
			continue
		orders[lists[i + 1][m + 1]].add(lists[i][m + 1])
	for i in alphab:
		if i not in orders:
			orders[i] = {}

def toposort(G):
	topoord = []
	Find = True
	while Find:
		Find = False
		for i in orders.keys():
			if len(orders[i]) == 0:
				topoord.append(i)
				for j in orders.keys():
					try:
						orders[j].remove(i)
					except Exception:
						pass
				del orders[i]
				Find = True
				break
	return topoord
n = int(input())
names = []
alphab = 'abcdefghijklmnopqrstuvwxyz'
orders = dfdict(set)
for _ in range(n):
	names.append(input())
make_graph(n, names)
res = toposort(orders)
print('Impossible') if len(res) < 26 else print(''.join(res))


from collections import defaultdict
from queue import Queue
graph = defaultdict(list)
prev = []
prevL = 0
root = ''
degree = [0 for i in range(26)]
flag = 1
for _ in range(int(input())):
	if prev == []:
		prev = list(input())
		root = prev[0]
		prevL = len(prev)
	else:
		curr = list(input()).copy()
		i = 0
		currL = len(curr)
		while i < min(prevL, currL) and prev[i] == curr[i]:
			i += 1
		if i < min(prevL, currL):
			graph[prev[i]].append(curr[i])
			degree[ord(curr[i]) - 97] += 1
		if i == min(prevL, currL) and prevL > currL:
			flag = 0
		prev = curr.copy()
		prevL = currL
ans = []
if flag == 1:
	q = Queue()
	for i in range(26):
		if degree[i] == 0:
			q.put(chr(i + 97))
	while not q.empty():
		t = q.get()
		ans.append(t)
		for i in graph[t]:
			degree[ord(i) - 97] -= 1
			if degree[ord(i) - 97] == 0:
				q.put(i)
if len(ans) != 26 or flag == 0:
	print('Impossible')
else:
	print(''.join(ans))


from string import ascii_lowercase as ascii

def go(v, order, color, cur):
	if color[v] == 1:
		return False
	if color[v] == 2:
		return True
	color[v] = 1
	for u in gr[v]:
		if not go(u, order, color, cur):
			return False
	order[v] = cur[0]
	cur[0] += 1
	color[v] = 2
	return True
n = int(input())
l = []
for i in range(n):
	l.append(input())
gr = {c: [] for c in ascii}
for (a, b) in zip(l[:-1], l[1:]):
	for (x, y) in zip(a, b):
		if x == y:
			continue
		gr[x].append(y)
		break
	else:
		if len(a) > len(b):
			print('Impossible')
			exit(0)
order = {c: -1 for c in ascii}
color = {c: 0 for c in ascii}
cur = [0]
for v in gr:
	if not go(v, order, color, cur):
		print('Impossible')
		exit(0)
print(''.join((a for (a, b) in sorted(order.items(), key=lambda p: -p[1]))))


import sys, os, io
import math, bisect, operator
(inf, mod) = (float('inf'), 10 ** 9 + 7)
from itertools import groupby, accumulate
from heapq import heapify, heappop, heappush
from collections import deque, Counter, defaultdict
input = iter(sys.stdin.buffer.read().decode().splitlines()).__next__
Neo = lambda : list(map(int, input().split()))
G = defaultdict(list)

def addEdge(a, b):
	G[a].append(b)

def Kahn(N, t):
	in_degree = Counter()
	for i in G.keys():
		for j in G.get(i, []):
			in_degree[j] += 1
	queue = deque()
	for i in t:
		if in_degree[i] == 0:
			queue.append(i)
	cnt = 0
	top_order = []
	while queue:
		u = queue.popleft()
		top_order.append(u)
		for i in G.get(u, []):
			in_degree[i] -= 1
			if in_degree[i] == 0:
				queue.append(i)
		cnt += 1
	if cnt != N:
		print('Impossible')
		exit(0)
	else:
		return top_order
(n,) = Neo()
S = []
for i in range(n):
	s = input()
	S.append(s)
t = set()
for i in range(1, n):
	f = 0
	for (j, k) in zip(S[i - 1], S[i]):
		if j != k:
			t.add(j)
			t.add(k)
			addEdge(j, k)
			f = 1
			break
	if f == 0:
		if len(S[i]) < len(S[i - 1]):
			print('Impossible')
			exit(0)
ans = list(set([*'abcdefghijklmnopqrstuvwxyz']) - t)
ans += Kahn(len(t), t)
print(''.join(ans))


from collections import defaultdict
import string

def topologicalSort(graph, nodes):
	for i in graph:
		for j in graph[i]:
			nodes[j] += 1
	queue = []
	for i in nodes:
		if nodes[i] == 0:
			queue.append(i)
	cnt = 0
	top_order = []
	while queue:
		u = queue.pop(0)
		top_order.append(u)
		for i in graph[u]:
			nodes[i] -= 1
			if nodes[i] == 0:
				queue.append(i)
		cnt += 1
	if cnt != len(nodes):
		print('Impossible')
		exit(0)
	else:
		return top_order
words = [input() for _ in ' ' * int(input())]
nodes = {}
for w in words:
	for i in w:
		if i not in nodes:
			nodes[i] = 0
graph = defaultdict(list)
for (i, word) in enumerate(words[:-1]):
	nxt = words[i + 1]
	for (a, b) in zip(word, nxt):
		if a != b:
			graph[a].append(b)
			break
	else:
		if len(word) > len(nxt):
			print('Impossible')
			exit(0)
topo = topologicalSort(graph, nodes)
alpha = set(string.ascii_lowercase)
print(''.join(list(alpha - set(topo)) + topo))


def go_through(given_char):
	global order
	global freq
	global orders
	if given_char in orders:
		while orders[given_char]:
			next_letter = orders[given_char].pop()
			freq[next_letter] = freq[next_letter] - 1
			go_through(next_letter)
	if given_char not in order:
		order.append(given_char)
num_names = int(input())
names = []
for _ in range(num_names):
	curr_name = input()
	names.append(curr_name)
prev_name = names[0]
possible = True
orders = {}
freq = {}
change_letters = set()
freq[prev_name[0]] = 0
for index in range(1, len(names)):
	name = names[index]
	char_index = 0
	while char_index < len(name) and char_index < len(prev_name) and (name[char_index] == prev_name[char_index]):
		char_index += 1
	if char_index < len(name) and char_index < len(prev_name):
		previous_char = prev_name[char_index]
		curr_char = name[char_index]
		if previous_char in orders:
			orders[previous_char].add(curr_char)
		else:
			orders[previous_char] = {curr_char}
		if curr_char in freq:
			freq[curr_char] = freq[curr_char] + 1
		else:
			freq[curr_char] = 1
		change_letters.add(previous_char)
		change_letters.add(curr_char)
		prev_name = name
	elif len(prev_name) > len(name):
		possible = False
		break
if not possible:
	print('Impossible')
else:
	order = []
	dependent_chars = list(orders.keys())
	for char in dependent_chars:
		curr_freq = 0
		if char in freq:
			curr_freq = freq[char]
		if curr_freq <= 0:
			go_through(char)
	if len(order) is not len(change_letters):
		print('Impossible')
	else:
		order = list(reversed(order))
		for char in range(ord('a'), ord('z') + 1):
			character = chr(char)
			if character not in order:
				order.append(character)
		for char in order:
			print(char, end='')


def found(x, a):
	for i in range(len(a)):
		if a[i] == x:
			return i
	return None
n = int(input())
a = []
L = 0
for i in range(n):
	x = input()
	a.append(x)
	L = max(L, len(x))
d = dict()
u = dict()
for i in range(97, 123):
	d[chr(i)] = set()
	u[chr(i)] = set()
for i in range(n - 1):
	ind = 0
	while ind < min(len(a[i]), len(a[i + 1])):
		if a[i][ind] != a[i + 1][ind]:
			d[a[i][ind]].add(a[i + 1][ind])
			u[a[i + 1][ind]].add(a[i][ind])
			ind = 10 ** 10
		else:
			ind += 1
	if ind == min(len(a[i]), len(a[i + 1])):
		if len(a[i]) > len(a[i + 1]):
			print('Impossible')
			exit()
del_u = set()
del_d = set()
for i in d:
	if len(d[i]) == 0:
		del_d.add(i)
for i in u:
	if len(u[i]) == 0:
		del_u.add(i)
for i in del_d:
	del d[i]
for i in del_u:
	del u[i]
g = dict()
for i in u:
	g[i] = 120
if len(d) == 0:
	print('abcdefghijklmnopqrstuvwxyz')
	exit()
v = set()
for i in d:
	v.add(i)
for i in u:
	v.discard(i)
for i in v:
	g[i] = 0
posetil = set()
for i in v:
	sosed = d[i]
	glub = 1
	while len(sosed) > 0:
		sosed2 = set()
		for j in sosed:
			if g[j] == 120:
				g[j] = glub
			elif g[j] < glub:
				g[j] = glub
			if j in d:
				for k in d[j]:
					sosed2.add(k)
		sosed = sosed2.copy()
		glub += 1
ans = dict()
for i in range(40):
	ans[i] = set()
for i in g:
	if g[i] == 120:
		print('Impossible')
		exit()
	ans[g[i]].add(i)
answer = []
for i in range(40):
	if len(ans[i]) != 0:
		for j in ans[i]:
			answer.append(j)
lol = set(answer)
for i in range(97, 123):
	if chr(i) not in lol:
		answer.append(chr(i))
if len(v) == 0:
	print('Impossible')
else:
	print(*answer, sep='')


from sys import stdin, stdout
from queue import Queue

def main():
	global io
	io = Stdio()
	n = io.next_int()
	names = []
	for i in range(n):
		names.append(io.next())
	lexicographical = set_up_lexicographical(names)
	if lexicographical == None:
		io.println('Impossible')
		return
	result = topo_sort(lexicographical)
	if result == None:
		io.println('Impossible')
		return
	io.println(result)

def set_up_lexicographical(names):
	lexicographical = [[] for u in range(26)]
	relation = [[False for v in range(26)] for u in range(26)]
	for i in range(len(names) - 1):
		flag = False
		min_size = min(len(names[i]), len(names[i + 1]))
		for j in range(min_size):
			if names[i][j] != names[i + 1][j]:
				relation[ord(names[i][j]) - 97][ord(names[i + 1][j]) - 97] = True
				flag = True
				break
		if not flag and len(names[i]) > len(names[i + 1]):
			return None
	for i in range(26):
		for j in range(26):
			if relation[i][j]:
				lexicographical[i].append(j)
	return lexicographical

def topo_sort(lexicographical):
	in_deg = [0 for u in range(26)]
	result = []
	zero_in_deg_queue = Queue()
	for u in range(26):
		for v in lexicographical[u]:
			in_deg[v] += 1
	for u in range(26):
		if in_deg[u] == 0:
			zero_in_deg_queue.put(u)
	while not zero_in_deg_queue.empty():
		u = zero_in_deg_queue.get()
		result.append(chr(u + 97))
		for v in lexicographical[u]:
			in_deg[v] -= 1
			if in_deg[v] == 0:
				zero_in_deg_queue.put(v)
	for u in range(26):
		if in_deg[u] != 0:
			return None
	return ''.join((str(c) for c in result))

class Stdio:
	index = 0
	tokens = []
	line = None

	def next_line(self):
		tokens = []
		return stdin.readline()

	def next(self):
		while self.index >= len(self.tokens):
			self.tokens = self.next_line().strip().split()
			if len(self.tokens) == 0:
				return None
			self.index = 0
		token = self.tokens[self.index]
		self.index += 1
		return token

	def next_int(self):
		return int(self.next())

	def next_float(self):
		return float(self.next())

	def next_char(self):
		return chr(self.next())

	def print(self, *objects):
		for obj in objects:
			stdout.write(str(obj))

	def println(self, *objects):
		for obj in objects:
			stdout.write(str(obj))
		stdout.write('\n')
main()


import sys
from collections import defaultdict
letters = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}
V = 26

def first_diff(a, b):
	ind = 0
	for c in a:
		if ind >= len(b):
			return -2
		if c != b[ind]:
			return ind
		ind += 1
	return -1
n = int(sys.stdin.readline().split()[0])
flag = True
g = defaultdict(set)
first = sys.stdin.readline().split()[0]
for _ in range(n - 1):
	second = sys.stdin.readline().split()[0]
	diff = first_diff(first, second)
	if diff == -2:
		flag = False
	if diff > -1:
		(fc, sc) = (first[diff], second[diff])
		g[fc].add(sc)
		first = second
in_degree = defaultdict(lambda : 0)
for c in g:
	for d in g[c]:
		in_degree[d] += 1
queue = []
for l in letters:
	if in_degree[l] == 0:
		queue.append(l)
cnt = 0
top_order = []
while queue:
	u = queue.pop(0)
	top_order.append(u)
	for i in g[u]:
		in_degree[i] -= 1
		if in_degree[i] == 0:
			queue.append(i)
	cnt += 1
if cnt != V or flag == False:
	print('Impossible')
else:
	print(''.join(top_order))


from collections import deque

def addToBelow(char, parChar, below):
	if parChar in below:
		below[parChar].add(char)
	else:
		below[parChar] = set([char])

def solve(t, words):
	graph = {}
	below = {}
	n = len(words)
	for i in range(1, n):
		if words[i - 1][0] != words[i][0]:
			if words[i - 1][0] in below and words[i][0] in below[words[i - 1][0]]:
				continue
			if words[i][0] in graph:
				graph[words[i][0]] += 1
			else:
				graph[words[i][0]] = 1
			addToBelow(words[i][0], words[i - 1][0], below)
		else:
			lm = min(len(words[i - 1]), len(words[i]))
			for l in range(1, lm):
				if words[i - 1][l] != words[i][l]:
					if words[i - 1][l] in below and words[i][l] in below[words[i - 1][l]]:
						break
					if words[i][l] in graph:
						graph[words[i][l]] += 1
					else:
						graph[words[i][l]] = 1
					addToBelow(words[i][l], words[i - 1][l], below)
					break
			if len(words[i]) < len(words[i - 1]):
				if words[i - 1][:lm] == words[i][:lm]:
					print('Impossible')
					return
	starts = deque()
	for i in range(26):
		c = chr(ord('a') + i)
		if c not in graph:
			starts.append(c)
	res = ''
	while starts:
		front = starts.popleft()
		res += front
		if front in below:
			for child in below[front]:
				if graph[child] > 0:
					graph[child] -= 1
					if graph[child] == 0:
						starts.append(child)
	if len(res) == 26:
		print(res)
	else:
		print('Impossible')

def main():
	t = int(input())
	words = []
	for _ in range(t):
		words.append(input())
	solve(t, words)
main()


import queue
from collections import defaultdict
from string import ascii_lowercase
n = int(input())
x = [input() for i in range(n)]
post = defaultdict(lambda : set())
prior = defaultdict(lambda : set())
for i in range(n):
	for j in range(i + 1, n):
		match = -1
		for k in range(min(len(x[i]), len(x[j]))):
			if x[i][k] != x[j][k]:
				match = k
				break
		if match == -1:
			if len(x[i]) > len(x[j]):
				print('Impossible')
				exit()
		else:
			post[x[i][match]].add(x[j][match])
			prior[x[j][match]].add(x[i][match])
q = queue.Queue()
visited = set()
for char in ascii_lowercase:
	if len(prior[char]) == 0:
		visited.add(char)
		q.put(char)
s = ''
while q.qsize():
	char = q.get()
	for item in post[char]:
		prior[item].remove(char)
	s += char
	for ch in ascii_lowercase:
		if ch not in visited and len(prior[ch]) == 0:
			visited.add(ch)
			q.put(ch)
print(s if len(s) == 26 else 'Impossible')


n = int(input())
a = [[] for i in range(26)]
b = [0 for i in range(26)]
ans = True
for i in range(n):
	t = input()
	if i > 0:
		ans = ans and s[:len(t)] != t
		if not ans:
			break
		if t[:len(s)] != s:
			(x, y) = next(filter(lambda x: x[0] != x[1], zip(s, t)))
			a[ord(x) - 97].append(ord(y) - 97)
			b[ord(y) - 97] += 1
	s = t
if ans:
	ans = []
	q = []
	l = 0
	for i in range(26):
		if not b[i]:
			q.append(i)
	while l < len(q):
		x = q[l]
		ans.append(chr(x + 97))
		l += 1
		for y in a[x]:
			b[y] -= 1
			if not b[y]:
				q.append(y)
if ans and len(ans) == 26:
	print(''.join(ans))
else:
	print('Impossible')


from sys import stdin, stdout
inp = stdin.readline
op = stdout.write
n = int(inp())
st = []
for i in range(n):
	temp = list(inp()[:-1])
	st.append(temp)
alph = list('abcdefghijklmnopqrstuvwxyz')
g = {alph[i]: [] for i in range(26)}
pos = 0
flag = 1
for i in range(n - 1):
	x = st[i]
	y = st[i + 1]
	pos = 0
	while pos < len(x) and pos < len(y) and (x[pos] == y[pos]):
		if pos + 1 < len(x) and pos + 1 >= len(y):
			break
		else:
			pos = pos + 1
	else:
		if pos < len(x) and pos < len(y):
			if x[pos] in g[y[pos]]:
				break
			else:
				g[x[pos]].append(y[pos])
		continue
	break
else:
	flag = 0
if flag == 0:
	st = []
	vis = {i: 0 for i in list(g.keys())}
	q = []
	indeg = {i: 0 for i in list(g.keys())}
	for i in alph:
		for j in g[i]:
			if not j == 0:
				indeg[j] += 1
	for j in list(indeg.keys()):
		if indeg[j] == 0:
			q.append(j)
			vis[j] = 1
	ans = []
	while len(q) > 0:
		temp = q.pop(0)
		ans.append(temp)
		for j in g[temp]:
			if not j == 0 and vis[j] == 0:
				indeg[j] -= 1
		for j in list(indeg.keys()):
			if indeg[j] == 0 and vis[j] == 0:
				q.append(j)
				vis[j] = 1
	if len(ans) == 26:
		op(''.join(ans))
	else:
		op('Impossible\n')
else:
	op('Impossible\n')


from collections import defaultdict
import heapq
n = int(input())
arr = [input() for _ in range(n)]
graph = defaultdict(list)
in_degree = defaultdict(int)
flag = True
for i in range(1, n):
	(cur, prev) = (arr[i], arr[i - 1])
	for j in range(min(len(cur), len(prev))):
		if cur[j] != prev[j]:
			graph[prev[j]].append(cur[j])
			in_degree[cur[j]] += 1
			break
	else:
		if len(prev) > len(cur):
			flag = False

def bfs(graph, in_degree):
	pq = []
	vis_set = set()
	vis_count = 0
	T = []
	for i in range(26):
		if in_degree[chr(ord('a') + i)] == 0:
			in_degree[chr(ord('a') + i)] = 0
			heapq.heappush(pq, chr(ord('a') + i))
			vis_set.add(chr(ord('a') + i))
			vis_count += 1
	while pq:
		vert = heapq.heappop(pq)
		T.append(vert)
		for other_vert in graph[vert]:
			if not other_vert in vis_set:
				in_degree[other_vert] -= 1
				if in_degree[other_vert] == 0:
					heapq.heappush(pq, other_vert)
					vis_set.add(other_vert)
					vis_count += 1
	if vis_count != 26:
		return []
	return T
if flag:
	ans = bfs(graph, in_degree)
	print(''.join(ans) if ans else 'Impossible')
else:
	print('Impossible')


class Graph:

	class Vertex:
		__slots__ = '_element'

		def __init__(self, ele):
			self._element = ele

		def element(self):
			return self._element

		def __hash__(self):
			return hash(id(self))

		def __str__(self):
			return str(self._element)

	class Edge:
		__slots__ = ('_origin', '_destination', '_element')

		def __init__(self, u, v, x):
			self._origin = u
			self._destination = v
			self._element = x

		def endpoints(self):
			return (self._origin, self._destination)

		def opposite(self, v):
			if not isinstance(v, Graph.Vertex):
				raise TypeError('not a vertex')
			return self._destination if v is self._origin else self._origin
			raise ValueError('not incident to edge')

		def element(self):
			return self._element

		def __hash__(self):
			return hash((self._origin, self._destination))

		def __str__(self):
			return '({0},{1},{2})'.format(self._origin, self._destination, self._element)

	def __init__(self, directed=False):
		self._outgoing = {}
		self._incoming = {} if directed else self._outgoing

	def _validate_vertex(self, v):
		if not isinstance(v, self.Vertex):
			raise TypeError('Vertex expected')
		if v not in self._outgoing:
			raise ValueError('Vertex does not belong to this graph.')

	def is_directed(self):
		return self._incoming is not self._outgoing

	def vertex_count(self):
		return len(self._outgoing)

	def vertices(self):
		return self._outgoing.keys()

	def edge_count(self):
		total = sum((len(self._outgoing[v]) for v in self._outgoing))
		return total if self.is_directed() else total // 2

	def edges(self):
		result = set()
		for secondary_map in self._outgoing.values():
			result.update(secondary_map.values())
		return result

	def get_edge(self, u, v):
		self._validate_vertex(u)
		self._validate_vertex(v)
		return self._outgoing[u].get(v)

	def degree(self, v, outgoing=True):
		self._validate_vertex(v)
		adj = self._outgoing if outgoing else self._incoming
		return len(adj[v])

	def incident_edges(self, v, outgoing=True):
		self._validate_vertex(v)
		adj = self._outgoing if outgoing else self._incoming
		for edge in adj[v].values():
			yield edge

	def insert_vertex(self, x=None):
		v = self.Vertex(x)
		self._outgoing[v] = {}
		if self.is_directed():
			self._incoming[v] = {}
		return v

	def insert_edge(self, u, v, x=None):
		if self.get_edge(u, v) is not None:
			return None
		e = self.Edge(u, v, x)
		self._outgoing[u][v] = e
		self._incoming[v][u] = e

def graph_from_edgelist(E, directed=False):
	g = Graph(directed)
	V = set()
	for e in E:
		V.add(e[0])
		V.add(e[1])
	verts = {}
	for v in V:
		verts[v] = g.insert_vertex(v)
	for e in E:
		src = e[0]
		dest = e[1]
		element = e[2] if len(e) > 2 else None
		g.insert_edge(verts[src], verts[dest], element)
	return g

def topological_sort(g):
	topo = []
	ready = []
	incount = {}
	for u in g.vertices():
		incount[u] = g.degree(u, False)
		if incount[u] == 0:
			ready.append(u)
	while len(ready) > 0:
		u = ready.pop()
		topo.append(u)
		for e in g.incident_edges(u):
			v = e.opposite(u)
			incount[v] -= 1
			if incount[v] == 0:
				ready.append(v)
	return topo

def compare(txt1, txt2):
	i = 0
	while txt1[i] == txt2[i]:
		if i == len(txt1) - 1:
			return None
		if i == len(txt2) - 1:
			return 'Imp'
		i += 1
	return (txt1[i], txt2[i])

def alphaprint(text):
	lis = list(text)
	for i in range(97, 123, 1):
		if chr(i) not in lis:
			lis.append(chr(i))
	print(''.join(lis))
n = int(input())
lis = []
cons = []
idf = 0
for i in range(n):
	lis.append(input())
for i in range(n - 1):
	for j in range(i + 1, n):
		temp = compare(lis[i], lis[j])
		if temp == 'Imp' and idf == 0:
			print('Impossible')
			idf = 1
		if temp != None and idf == 0:
			cons.append(temp)
if idf == 0:
	graph = graph_from_edgelist(cons, True)
	order = topological_sort(graph)
	vert = graph.vertex_count()
	orderlis = ''.join((str(x) for x in order))
	if len(orderlis) != vert:
		print('Impossible')
	else:
		alphaprint(orderlis)


def isPrefix(sa, sb):
	if len(sa) <= len(sb):
		return False
	return sa[0:len(sb)] == sb

def getOrder(sa, sb):
	for i in range(0, min(len(sa), len(sb))):
		if sa[i] != sb[i]:
			return (sa[i], sb[i])
test = False
if test:
	fp = open('in.txt', 'r')
	n = int(fp.readline().strip())
	names = [fp.readline().strip() for i in range(0, n)]
	fp.close()
else:
	n = int(input().strip())
	names = [input().strip() for i in range(0, n)]
g = [[False] * 26 for i in range(0, 26)]
res = True
for i in range(1, n):
	if names[i - 1] == names[i] or isPrefix(names[i], names[i - 1]):
		continue
	elif isPrefix(names[i - 1], names[i]):
		res = False
		break
	else:
		(ca, cb) = getOrder(names[i - 1], names[i])
		if g[ord(cb) - ord('a')][ord(ca) - ord('a')]:
			res = False
			break
		else:
			g[ord(ca) - ord('a')][ord(cb) - ord('a')] = True

def printG():
	print('   abcdefghijklmnopqrstuvwxyz')
	for i in range(0, 26):
		print(chr(ord('a') + i), ''.join(['1' if x else '0' for x in g[i]]), sep='')
if not res:
	print('Impossible')
else:

	def getZeroIndegreeNode():
		for i in range(0, 26):
			if not used[i] and indegree[i] == 0:
				return i
		return -1
	theOrder = []
	indegree = [0] * 26
	used = [False] * 26
	for i in range(0, 26):
		ithIndegree = 0
		for j in range(0, 26):
			if g[j][i]:
				ithIndegree += 1
		indegree[i] = ithIndegree
	for i in range(0, 26):
		zeroIndegreeNode = getZeroIndegreeNode()
		if zeroIndegreeNode == -1:
			res = False
			break
		else:
			used[zeroIndegreeNode] = True
			theOrder.append(chr(ord('a') + zeroIndegreeNode))
			for j in range(0, 26):
				if g[zeroIndegreeNode][j]:
					indegree[j] -= 1
	if not res:
		print('Impossible')
	else:
		print(''.join(theOrder))


from __future__ import print_function
from collections import Counter, OrderedDict
from itertools import permutations as perm
from fractions import Fraction
from collections import deque
from sys import stdin
from bisect import *
from heapq import *
from math import *
g = lambda : stdin.readline().strip()
gl = lambda : g().split()
gil = lambda : [int(var) for var in gl()]
gfl = lambda : [float(var) for var in gl()]
gcl = lambda : list(g())
gbs = lambda : [int(var) for var in g()]
mod = int(1000000000.0) + 7
inf = float('inf')

def topologicalSort(adj, n):
	ans = []
	isExplored = [0] * (n + 1)
	vis = [0] * (n + 1)
	for i in range(1, n + 1):
		if isExplored[i]:
			continue
		stack = [i]
		while stack:
			p = stack[-1]
			if vis[p] or isExplored[p]:
				if not isExplored[p]:
					isExplored[p] = 1
					ans.append(stack.pop())
				else:
					stack.pop()
			else:
				vis[p] = 1
				for c in adj[p]:
					if isExplored[c]:
						pass
					elif vis[c]:
						return []
					else:
						stack.append(c)
	return ans

def getNode(ch):
	return ord(ch) - 96

def getDiffChar(sx, sy):
	for i in range(min(len(sx), len(sy))):
		if sx[i] != sy[i]:
			return (getNode(sx[i]), getNode(sy[i]))
	return (0, 0)
(n,) = gil()
words = []
adj = [[] for _ in range(27)]
for _ in range(n):
	words.append(g())
for i in range(n):
	for j in range(i + 1, n):
		(x, y) = getDiffChar(words[i], words[j])
		if x != y:
			adj[y].append(x)
		elif len(words[i]) > len(words[j]):
			print('Impossible')
			exit()
ans = topologicalSort(adj, 26)
if len(ans) != 26:
	print('Impossible')
else:
	for i in ans:
		print(chr(i + 96), end='')
	print()


from sys import stdin, stdout
n = int(stdin.readline().strip())
d = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7, 'i': 8, 'j': 9, 'k': 10, 'l': 11, 'm': 12, 'n': 13, 'o': 14, 'p': 15, 'q': 16, 'r': 17, 's': 18, 't': 19, 'u': 20, 'v': 21, 'w': 22, 'x': 23, 'y': 24, 'z': 25}
arr = []
for i in range(n):
	arr.append(stdin.readline().strip())
cycle = False
edge_matrix = [[0 for _ in range(26)] for i in range(26)]
for i in range(1, len(arr)):
	word1 = arr[i - 1]
	word2 = arr[i]
	ctr = 0
	if len(word1) > len(word2) and word1[:len(word2)] == word2:
		cycle = True
		break
	while ctr < min(len(word1), len(word2)) and word1[ctr] == word2[ctr]:
		ctr += 1
	if not ctr == min(len(word1), len(word2)):
		edge_matrix[d[word1[ctr]]][d[word2[ctr]]] = 1
ansstack = []
visited = [0 for i in range(26)]

def topological_sort(curr):
	global cycle, visited, ansstack
	if not cycle:
		visited[curr] = 1
		for i in range(len(edge_matrix[curr])):
			if edge_matrix[curr][i] == 1:
				if visited[i] == 0:
					topological_sort(i)
				elif visited[i] == 1:
					cycle = True
					break
		visited[curr] = 2
		ansstack.insert(0, curr)

def doshit():
	for i in range(26):
		if not cycle and visited[i] == 0 and (sum(edge_matrix[i]) > 0):
			topological_sort(i)
doshit()
if cycle:
	stdout.write('Impossible\n')
else:
	for i in range(26):
		if i not in ansstack:
			stdout.write(chr(ord('a') + i))
	for i in ansstack:
		stdout.write(chr(ord('a') + i))


from collections import defaultdict
import string
n = int(input())
w1 = input()
graph = defaultdict(list)
visited = {}
stk = {}
ans = ''
cycle = False
for c in string.ascii_lowercase:
	visited[c] = False
	stk[c] = False
for i in range(n - 1):
	w2 = input()
	idx = 0
	while idx < min(len(w1) - 1, len(w2) - 1) and w1[idx] == w2[idx]:
		idx += 1
	if w1[idx] != w2[idx]:
		graph[w1[idx]].append(w2[idx])
	elif len(w1) > len(w2):
		cycle = True
	w1 = w2

def dfs(v):
	stk[v] = True
	visited[v] = True
	for u in graph[v]:
		if stk[u]:
			global cycle
			cycle = True
		if not visited[u]:
			dfs(u)
	global ans
	ans += v
	stk[v] = False
for i in list(graph):
	if not visited[i]:
		dfs(i)
ans = ans[::-1]
if cycle:
	print('Impossible')
else:
	print(ans, end='')
	for c in string.ascii_lowercase:
		if c not in ans:
			print(c, end='')


n = int(input())
prev = None
ans = False
nodes = {}
for i in 'abcdefghijklmnopqrstuvwxyz':
	nodes[i] = set()
for i in range(n):
	name = input()
	if prev:
		for (x, y) in zip(name, prev):
			if x != y:
				nodes[x].add(y)
				break
		else:
			if prev > name:
				ans = True
				break
	prev = name
a = []
b = []
for i in 'abcdefghijklmnopqrstuvwxyz':
	if not nodes[i]:
		a.append(i)
	else:
		b.append(i)
c = []
while a:
	d = a.pop()
	c.append(d)
	for i in b[:]:
		if d in nodes[i]:
			nodes[i].remove(d)
			if not nodes[i]:
				a.append(i)
				b.remove(i)
if b or ans:
	print('Impossible')
else:
	print(''.join(c))


from collections import defaultdict
import string

def alphabet(sorted_strings):

	def build_graph(sorted_strings):
		graph = defaultdict(set)
		for x in string.ascii_lowercase:
			graph[x]
		for i in range(len(sorted_strings) - 1):
			cur = sorted_strings[i]
			nxt = sorted_strings[i + 1]
			(j, k) = (0, 0)
			while j < len(cur) and k < len(nxt) and (cur[j] == nxt[k]):
				j += 1
				k += 1
			if j < len(cur) and k < len(nxt):
				graph[cur[j]].add(nxt[k])
			if j < len(cur) and k == len(nxt):
				return None
		return graph

	def topological_sort(graph):

		def helper(node, stack, visited):
			visited.add(node)
			for child in graph[node]:
				if child in visited:
					continue
				helper(child, stack, visited)
			stack.append(node)
		stack = []
		visited = set()
		graph_keys = set(graph.keys())
		for node in string.ascii_lowercase[::-1]:
			if node in visited:
				continue
			helper(node, stack, visited)
		return stack

	def is_cyclic(graph):
		path = set()
		visited = set()

		def visit(node):
			if node in visited:
				return False
			path.add(node)
			visited.add(node)
			for neighbor in graph[node]:
				if neighbor in path or visit(neighbor):
					return True
			path.remove(node)
			return False
		return any((visit(node) for node in graph.keys()))
	graph = build_graph(sorted_strings)
	if graph is None or is_cyclic(graph):
		return 'Impossible'
	stack = topological_sort(graph)
	return ''.join(stack[::-1])
n = int(input())
data = []
for _ in range(n):
	data.append(input().strip())
print(alphabet(data))