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: si ≠ ti. 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 si and ti 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 namei (1 ≤ |namei| ≤ 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

Source: codeforces | Difficulty: MEDIUM_HARD
Tags: Sorting

Graph algorithms

Graph traversal


Solutions:
import sys
import heapq
n = int(sys.stdin.readline().strip())
w = []
g = {i: set({}) for i in 'azertyuiopqsdfghjklmwxcvbn'}
for i in range(n):
	w.append(sys.stdin.readline().strip())
for i in range(n - 1):
	idx = 0
	while idx < min(len(w[i]), len(w[i + 1])) - 1 and w[i][idx] == w[i + 1][idx]:
		idx += 1
	if w[i][idx] == w[i + 1][idx] and len(w[i]) > len(w[i + 1]):
		print('Impossible')
		break
	if w[i][idx] != w[i + 1][idx]:
		g[w[i + 1][idx]].add(w[i][idx])
else:
	ans = ''
	while g:
		for i in 'azertyuiopqsdfghjklmwxcvbn':
			if i in g and (not g[i]):
				ans += i
				del g[i]
				for j in 'azertyuiopqsdfghjklmwxcvbn':
					if j in g and i in g[j]:
						g[j].remove(i)
				break
		else:
			print('Impossible')
			break
	else:
		print(ans)


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')


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()


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]))


def main():
	order = []
	color = [0] * 26
	graph = [[] for i in range(26)]

	def dfs(v):
		color[v] = 1
		flag = True
		for u in graph[v]:
			if color[u] == 1:
				flag = False
			if color[u] == 0:
				dfs(u)
		color[v] = 2
		if flag:
			order.append(v)
	import sys
	(n, *s) = sys.stdin.read().split()
	n = int(n)
	for i in range(n - 1):
		if len(s[i]) > len(s[i + 1]) and s[i][:len(s[i + 1])] == s[i + 1]:
			print('Impossible')
			return
		for j in range(min(len(s[i]), len(s[i + 1]))):
			if s[i][j] != s[i + 1][j]:
				graph[ord(s[i][j]) - ord('a')].append(ord(s[i + 1][j]) - ord('a'))
				break
	for i in range(26):
		if color[i] == 0:
			dfs(i)
	if len(order) != 26:
		print('Impossible')
		return
	print(''.join((chr(i + ord('a')) for i in reversed(order))))
main()


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))


import math
from collections import deque, defaultdict
from sys import stdin, stdout
listin = lambda : list(map(int, input().split()))
mapin = lambda : map(int, input().split())

def isCyclicUtil(v, visited, recStack):
	visited[v] = 1
	recStack[v] = 1
	for neighbour in d[v]:
		if visited[neighbour] == 0:
			if isCyclicUtil(neighbour, visited, recStack) == 1:
				return True
		elif recStack[neighbour] == 1:
			return True
	recStack[v] = 0
	return False

def isCyclic():
	visited = {i: 0 for i in 'abcdefghijklmnopqrstuvwxyz'}
	recStack = {i: 0 for i in 'abcdefghijklmnopqrstuvwxyz'}
	for node in list(d.keys()):
		if visited[node] == 0:
			if isCyclicUtil(node, visited, recStack) == True:
				return True
	return False

def topologicalSortUtil(v, visited, stack):
	visited[v] = 1
	for i in d[v]:
		if not visited[i]:
			topologicalSortUtil(i, visited, stack)
	stack.insert(0, v)

def topologicalSort():
	visited = {i: 0 for i in 'abcdefghijklmnopqrstuvwxyz'}
	stack = []
	for i in list(d.keys()):
		if visited[i] == 0:
			topologicalSortUtil(i, visited, stack)
	string = ''
	while stack:
		string += stack.pop()
	return string[::-1]
n = int(input())
a = []
visited = {i: 0 for i in 'abcdefghijklmnopqrstuvwxyz'}
for i in range(n):
	a.append(input())
d = defaultdict(list)
for i in range(n - 1):
	x = 0
	while x < len(a[i]) and x < len(a[i + 1]):
		if a[i][x] != a[i + 1][x]:
			d[a[i][x]].append(a[i + 1][x])
			break
		x += 1
if not d.keys():
	if a != sorted(a):
		print('Impossible')
	else:
		print('abcdefghijklmnopqrstuvwxyz')
elif isCyclic():
	print('Impossible')
else:
	x = topologicalSort()
	letters = 'abcdefghijklmnopqrstuvwxyz'
	for i in letters:
		if i not in x:
			x += i
	print(x)


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))


global k
k = False

def dfs(g, v):
	global k
	visited[v] = 1
	for i in g[v]:
		if visited[i] == 0:
			dfs(g, i)
		elif visited[i] == 1:
			k = True
	visited[v] = 2
g = {}
for i in 'abcdefghijklmnopqrstuvwxyz':
	g[i] = []
n = []
x = int(input())
for i in range(x):
	a = input()
	n.append(a)
for i in range(x - 1):
	fir = n[i]
	sec = n[i + 1]
	good = False
	for j in range(min(len(fir), len(sec))):
		if fir[j] != sec[j]:
			g[fir[j]].append(sec[j])
			g[fir[j]] = list(set(g[fir[j]]))
			good = True
			break
	if good == False:
		if len(sec) < len(fir):
			print('Impossible')
			quit()
			break
for e in 'abcdefghijklmnopqrstuvwxyz':
	visited = {}
	for i in 'abcdefghijklmnopqrstuvwxyz':
		visited[i] = 0
	dfs(g, e)
for i in 'abcdefghijklmnopqrstuvwxyz':
	visited[i] = 0
fin = []

def dfst(graph, start):
	if not visited[start]:
		visited[start] = True
		for i in graph[start]:
			dfst(graph, i)
		fin.append(start)
for i in 'abcdefghijklmnopqrstuvwxyz'[::-1]:
	dfst(g, i)
if k == True:
	print('Impossible')
else:
	fin.reverse()
	print(''.join(fin))


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))


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))


(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)


n = int(input())
g = [[] for i in range(26)]
in_degree = [0] * 26
s = input()
f = 0
for i in range(n - 1):
	t = input()
	if len(s) > len(t) and s[:len(t)] == t:
		f = 1
		break
	for j in range(min(len(t), len(s))):
		if t[j] != s[j]:
			g[ord(s[j]) - 97].append(t[j])
			break
	s = t
for i in range(26):
	for j in g[i]:
		in_degree[ord(j) - 97] += 1
q = []
for i in range(26):
	if in_degree[i] == 0:
		q.append(i)
cnt = 0
top_order = []
while q:
	u = q.pop()
	top_order.append(chr(97 + u))
	for i in g[u]:
		in_degree[ord(i) - 97] -= 1
		if in_degree[ord(i) - 97] == 0:
			q.append(ord(i) - 97)
	cnt += 1
if cnt != 26:
	print('Impossible')
else:
	print(''.join(top_order) if f == 0 else 'Impossible')


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))


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')


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)
	queue = collections.deque([v for v in verts if incoming_edges[v] == 0])
	while len(queue) != 0:
		u = queue.popleft()
		sorted.append(u)
		for v in edges[u]:
			assert incoming_edges[v] > 0
			incoming_edges[v] -= 1
			if incoming_edges[v] == 0:
				queue.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 = sorted(list(names))
		if sorted_names == names:
			print(''.join(all_letters))
		else:
			print('Impossible')
	else:
		res = topsort(edges, all_letters)
		if res:
			print(''.join(res))
		else:
			print('Impossible')
main()


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')


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 = names[i]
	name_2 = names[i + 1]
	prefix = False
	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
			prefix = True
			break
	if not 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')


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())


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)))


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 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='')


n = int(input())
a = input()
c = [[False for i in range(26)] for j in range(26)]

def f(x):
	return ord(x) - ord('a')
for i in range(1, n):
	e = False
	b = input()
	for j in range(min(len(a), len(b))):
		if a[j] != b[j]:
			(c[f(a[j])][f(b[j])], e) = (True, True)
			break
	if not e and len(a) > len(b):
		print('Impossible')
		exit(0)
	a = b
for k in range(26):
	for i in range(26):
		for j in range(26):
			c[i][j] = c[i][j] or (c[i][k] and c[k][j])
for i in range(26):
	for j in range(26):
		if c[i][j] and c[j][i]:
			print('Impossible')
			exit(0)
a = [chr(x) for x in range(ord('a'), 26 + ord('a'))]
for i in range(26):
	for j in range(i + 1, 26):
		if c[f(a[j])][f(a[i])]:
			(a[i], a[j]) = (a[j], a[i])
print(''.join(a))


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))))


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))


__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)


def fastio():
	import sys
	from io import StringIO
	from atexit import register
	global input
	sys.stdin = StringIO(sys.stdin.read())
	input = lambda : sys.stdin.readline().rstrip('\r\n')
	sys.stdout = StringIO()
	register(lambda : sys.__stdout__.write(sys.stdout.getvalue()))
fastio()
import sys
sys.setrecursionlimit(5000)
MOD = 10 ** 9 + 7
I = lambda : list(map(int, input().split()))
(n,) = I()
l = []
for i in range(n):
	l.append(input())
al = list('abcdefghijklmnopqrstuvwxyz')
summa = ''
g = [set() for i in range(26)]
for i in range(n - 1):
	s = l[i]
	t = l[i + 1]
	for j in range(min(len(s), len(t))):
		if s[j] != t[j]:
			g[ord(s[j]) - 97].add(ord(t[j]) - 97)
			break
	else:
		if len(s) > len(t):
			print('Impossible')
			exit()
v = [0] * 26
ans = []

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


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='')


n = int(input())
s = [input() + ' ' for _ in range(n)]
g = [[] for _ in range(123)]
ind = [0] * 123
for i in range(97, 97 + 26):
	g[32].append(i)
	ind[i] += 1
st = [(0, n, 0)]
while st:
	(l, r, p) = st.pop()
	if r - l <= 1:
		continue
	for i in range(l, r):
		for j in range(i + 1, r):
			if s[i][p] != s[j][p]:
				g[ord(s[i][p])].append(ord(s[j][p]))
				ind[ord(s[j][p])] += 1
	idx = l
	for i in range(l, r - 1):
		if s[i][p] != s[i + 1][p]:
			st.append((idx, i + 1, p + 1))
			idx = i + 1
	st.append((idx, r, p + 1))
st = [32]
res = ''
while st:
	p = st.pop()
	for node in g[p]:
		ind[node] -= 1
		if ind[node] == 0:
			res += chr(node)
			st.append(node)
if len(res) == 26:
	print(res)
else:
	print('Impossible')


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
n = int(input())
prev = None
flag = False
nodes = {}
for i in string.ascii_lowercase:
	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:
				flag = 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 flag:
	print('Impossible')
else:
	print(''.join(c))


def itoc(i):
	return chr(i + ord('a'))

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

class Node:

	def __init__(self, name):
		self.name = name
		self.neighbors = []
		self.t_flag = False
		self.p_flag = False

	def add_nb(self, w):
		self.neighbors.append(w)

class Graph:

	def __init__(self, n):
		self.V = [Node(i) for i in range(n)]
		self.stack = ''

	def __str__(self):
		tmp = ''
		for v in self.V:
			tmp += str(itoc(v.name)) + ':' + list.__str__([itoc(m) for m in v.neighbors]) + '\n'
		return tmp

	def add_edge(self, v, w):
		self.V[v].add_nb(w)

	def visit(self, n):
		if self.V[n].t_flag:
			return 0
		if not self.V[n].p_flag:
			self.V[n].t_flag = True
			for m in self.V[n].neighbors:
				if self.visit(m) == 0:
					return 0
			self.V[n].p_flag = True
			self.V[n].t_flag = False
			self.stack += str(chr(n + ord('a')))
		return 1

	def tarjan(self):
		for v in self.V:
			if not v.p_flag:
				if self.visit(v.name) == 0:
					print('Impossible')
					return
		print(self.stack[::-1])
		return
G = Graph(26)
n = int(input())
names = [input() for i in range(n)]
for i in range(n - 1):
	j = 1
	for (a, b) in zip(names[i], names[i + 1]):
		if a == b:
			if j == len(names[i + 1]):
				print('Impossible')
				quit()
			j += 1
			continue
		G.add_edge(ctoi(a), ctoi(b))
		break
G.tarjan()


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()


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))


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 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())


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')


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 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()


n = int(input(''))
names = [input('') for i in range(n)]
alphabet = 'abcdefghijklmnopqrstuvwxyz'
edge_list = {i: [] for i in alphabet}

def post_dfs(vertice, visited, post_order, detect_cycle):
	visited[vertice] = 1
	for child_vertice in edge_list[vertice]:
		if visited[child_vertice] == 0:
			(post_order, detect_cycle) = post_dfs(child_vertice, visited, post_order, detect_cycle)
			if detect_cycle:
				break
		elif visited[child_vertice] == 1:
			detect_cycle = True
			break
	else:
		post_order.append(vertice)
		visited[vertice] = 2
	return (post_order, detect_cycle)

def topological_sort(edge_list, post_order):
	visited = {char: 0 for char in edge_list}
	for vertice in edge_list:
		if visited[vertice] == 0:
			(post_order, detect_cycle) = post_dfs(vertice, visited, post_order, detect_cycle=False)
			if detect_cycle:
				return 'Impossible'
	return ''.join(map(str, post_order[::-1]))

def modify_alphabet(edge_list):
	for i in range(n - 1):
		found_uncommon = False
		for (char1, char2) in zip(names[i], names[i + 1]):
			if char1 != char2:
				found_uncommon = True
				break
		if not found_uncommon and len(names[i]) > len(names[i + 1]):
			return 'Impossible'
		if found_uncommon:
			edge_list[char1].append(char2)
	post_order = []
	ans = topological_sort(edge_list, post_order)
	return ans
print(modify_alphabet(edge_list))


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 string import ascii_lowercase as ascii
from typing import List

def toplogical_sort(matrix: List[List[int]]) -> str:
	sorted_letters = []
	stack = [j for j in range(26) if sum((row[j] for row in matrix)) == 0][::-1]
	while stack:
		node = stack.pop()
		sorted_letters.append(ascii[node])
		for j in range(26):
			if matrix[node][j] == 1:
				matrix[node][j] = 0
				if sum((row[j] for row in matrix)) == 0:
					stack.append(j)
	return ['Impossible', ''.join(sorted_letters)][len(sorted_letters) == 26]

def solve(n: int, names: List[str]) -> str:
	adj = [[0] * 26 for _ in range(26)]
	for (currName, nextName) in zip(names, names[1:]):
		if len(nextName) < len(currName) and currName.find(nextName) == 0:
			return 'Impossible'
		for i in range(min(len(currName), len(nextName))):
			if currName[i] != nextName[i]:
				adj[ascii.index(currName[i])][ascii.index(nextName[i])] = 1
				break
	return toplogical_sort(adj)
n = input()
arr = [input() for _ in range(int(n))]
print(solve(n, arr))


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)


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')


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')


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]))))


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))


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='')


import sys
import heapq
n = int(sys.stdin.readline().strip())
w = []
g = {i: set({}) for i in 'azertyuiopqsdfghjklmwxcvbn'}
for i in range(n):
	w.append(sys.stdin.readline().strip())
for i in range(n - 1):
	idx = 0
	while idx < min(len(w[i]), len(w[i + 1])) - 1 and w[i][idx] == w[i + 1][idx]:
		idx += 1
	if w[i][idx] == w[i + 1][idx] and len(w[i]) > len(w[i + 1]):
		print('Impossible')
		break
	if w[i][idx] != w[i + 1][idx]:
		g[w[i + 1][idx]].add(w[i][idx])
else:
	ans = ''
	pq = [k for k in g.keys() if not g[k]]
	while pq:
		v = pq.pop()
		ans += v
		for k in g.keys():
			if v in g[k]:
				g[k].remove(v)
				if not g[k]:
					pq.append(k)
	print(['Impossible', ans][len(ans) == 26])


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 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()


n = int(input())
p = [set() for _ in range(26)]
a = input()
for _ in range(n - 1):
	b = input()
	for i in range(min(len(a), len(b))):
		if a[i] != b[i]:
			p[ord(b[i]) - ord('a')].add(ord(a[i]) - ord('a'))
			for e in p[ord(a[i]) - ord('a')]:
				p[ord(b[i]) - ord('a')].add(e)
			break
	else:
		if len(a) > len(b):
			print('Impossible')
			exit()
	a = b
r = ''
for _ in range(26):
	for i in range(26):
		if len(p[i]) == 0:
			r += chr(i + ord('a'))
			p[i].add(30)
			for j in range(26):
				p[j].discard(i)
			break
	else:
		print('Impossible')
		break
else:
	print(r)


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
sys.setrecursionlimit(1000000)

def compute_alphabet_ordering(names):
	graph = [[] for _ in range(ord('z') - ord('a') + 1)]
	for i in range(1, len(names)):
		(a, b) = (names[i - 1], names[i])
		diff_index = None
		for j in range(min(len(a), len(b))):
			if a[j] != b[j]:
				diff_index = j
				break
		if diff_index is not None:
			graph[ord(a[diff_index]) - ord('a')].append(ord(b[diff_index]) - ord('a'))
		elif len(b) < len(a):
			return None
	order = []
	visited = [False] * len(graph)
	current_component = [False] * len(graph)

	def build_order(node):
		if current_component[node]:
			return False
		if visited[node]:
			return True
		visited[node] = True
		current_component[node] = True
		for neighbor in graph[node]:
			if not build_order(neighbor):
				return False
		current_component[node] = False
		order.append(node)
		return True
	for i in range(len(graph)):
		if not build_order(i):
			return None
	return ''.join([chr(ord('a') + i) for i in order[::-1]])
n = int(sys.stdin.readline())
names = [sys.stdin.readline().strip() for _ in range(n)]
permutation = compute_alphabet_ordering(names)
print(permutation if permutation is not None else 'Impossible')


import string

def find_alphabet_order(names):
	dependencies = {i: set() for i in string.ascii_lowercase}
	for (a, b) in zip(names, names[1:]):
		is_subset = True
		for (i, j) in zip(a, b):
			if i != j:
				is_subset = False
				dependencies[j].add(i)
				break
		if is_subset and len(a) > len(b):
			return 'Impossible'
	completed = {i: [False, False] for i in string.ascii_lowercase}
	alphabet_order = []

	def topological_sort(value):
		if completed[value][1]:
			return True
		if completed[value][0]:
			return False
		completed[value][0] = True
		for i in dependencies[value]:
			is_possible = topological_sort(i)
			if not is_possible:
				return False
		completed[value][1] = True
		alphabet_order.append(value)
		return True
	for dependency in dependencies:
		is_possible = topological_sort(dependency)
		if not is_possible:
			return 'Impossible'
	return ''.join(alphabet_order)
n = int(input())
names = [input() for _ in range(n)]
print(find_alphabet_order(names))


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()


from collections import deque
num = int(input())
words = []
for i in range(num):
	words.append(input())
adj_matrix = [[False for j in range(26)] for i in range(26)]
possible = True
for i in range(num - 1):
	(word1, word2) = (words[i], words[i + 1])
	for (c1, c2) in zip(word1, word2):
		if c1 != c2:
			adj_matrix[ord(c2) - ord('a')][ord(c1) - ord('a')] = True
			break
	else:
		if len(word1) > len(word2):
			possible = False
stack = []
for i in range(25, -1, -1):
	if not any(adj_matrix[i]):
		stack.append(i)
order = []
while stack:
	char_ord = stack.pop()
	order.append(chr(ord('a') + char_ord))
	for i in range(26):
		if adj_matrix[i][char_ord]:
			adj_matrix[i][char_ord] = False
			if not any(adj_matrix[i]):
				stack.append(i)
if len(order) == 26 and possible:
	print(''.join(order))
else:
	print('Impossible')


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 math, string, itertools, fractions, heapq, collections, re, array, bisect, sys, copy, functools
inf = 10 ** 20
eps = 1.0 / 10 ** 10
mod = 10 ** 9 + 7
mod2 = 998244353
dd = [(-1, 0), (0, 1), (1, 0), (0, -1)]
ddn = [(-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (1, -1), (0, -1), (-1, -1)]

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

def LLI():
	return [list(map(int, l.split())) for l in sys.stdin.readlines()]

def LI_():
	return [int(x) - 1 for x in sys.stdin.readline().split()]

def LF():
	return [float(x) for x in sys.stdin.readline().split()]

def LS():
	return sys.stdin.readline().split()

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

def F():
	return float(sys.stdin.readline())

def S():
	return input()

def pf(s):
	return print(s, flush=True)

def pe(s):
	return print(str(s), file=sys.stderr)

def JA(a, sep):
	return sep.join(map(str, a))

def JAA(a, s, t):
	return s.join((t.join(map(str, b)) for b in a))

def IF(c, t, f):
	return t if c else f

def YES(c):
	return IF(c, 'YES', 'NO')

def Yes(c):
	return IF(c, 'Yes', 'No')

def scc(n, e, re):
	v = [None] * n
	t = []

	def dfs(i):
		v[i] = 0
		for b in e[i]:
			if v[b] is None:
				dfs(b)
		t.append(i)
	for i in range(n):
		if v[i] is None:
			dfs(i)
	r = [None] * n
	rr = []

	def dfs2(i, p):
		r[i] = p
		rr[-1].append(i)
		for b in re[i]:
			if r[b] is None:
				dfs2(b, p)
	for c in t[::-1]:
		if r[c] is None:
			rr.append([])
			dfs2(c, c)
	return (r, rr)

def main():
	t = 1
	rr = []
	for _ in range(t):
		n = I()
		sa = [S() for _ in range(n)]
		sa = [[ord(c) - ord('a') for c in s] for s in sa]
		ok = 1
		e = collections.defaultdict(set)
		re = collections.defaultdict(set)
		for i in range(n):
			s = sa[i]
			for j in range(i + 1, n):
				t = sa[j]
				f = 0
				for (a, b) in zip(s, t):
					if a != b:
						e[a].add(b)
						re[b].add(a)
						f = 1
						break
				if not f and len(s) > len(t):
					ok = 0
					break
		(sc, cc) = scc(26, e, re)
		c = collections.Counter(sc)
		if not ok or max(c.values()) > 1:
			rr.append('Impossible')
		else:
			r = []
			for t in cc:
				for i in t:
					r.append(chr(ord('a') + i))
			rr.append(JA(r, ''))
	return JA(rr, '\n')
print(main())


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()


MAX = 26

def TopologicalSort():
	in_degree = [0] * MAX
	for u in range(MAX):
		for v in graph[u]:
			in_degree[v] += 1
	zero_in_degree = []
	for u in range(MAX):
		if in_degree[u] == 0:
			zero_in_degree.append(u)
	top_order = []
	while zero_in_degree:
		u = zero_in_degree.pop(0)
		top_order.append(u)
		for v in graph[u]:
			in_degree[v] -= 1
			if in_degree[v] == 0:
				zero_in_degree.append(v)
	for u in range(MAX):
		if in_degree[u] != 0:
			print('Impossible')
			return
	for char in top_order:
		print(chr(char + 97), end='')
n = int(input())
names = []
for i in range(n):
	names.append(input())
char_relation = [[False] * MAX for _ in range(MAX)]
for i in range(1, n):
	flag = False
	min_len = min(len(names[i - 1]), len(names[i]))
	for j in range(min_len):
		if names[i - 1][j] != names[i][j]:
			flag = True
			char_relation[ord(names[i - 1][j]) - 97][ord(names[i][j]) - 97] = True
			break
	if not flag and len(names[i - 1]) > len(names[i]):
		print('Impossible')
		exit()
graph = [[] for i in range(MAX)]
for i in range(MAX):
	for j in range(MAX):
		if char_relation[i][j]:
			graph[i].append(j)
TopologicalSort()


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='')


import sys, itertools, collections
import string
sys.setrecursionlimit(10000)
read_ints = lambda : list(map(int, input().split()))
read_int = lambda : int(input())

def report_impossible():
	print('Impossible')
	sys.exit()

def compute_less(s, t):
	global Less
	for (x, y) in zip(s, t):
		if x != y:
			Less[x][y] = True
			return
	if len(s) > len(t):
		report_impossible()
N = read_int()
S = [input() for _ in range(N)]
Less = collections.defaultdict(lambda : collections.defaultdict(bool))
Alphabets = string.ascii_lowercase
for (s, t) in zip(S, S[1:]):
	compute_less(s, t)
for k in Alphabets:
	for i in Alphabets:
		for j in Alphabets:
			Less[i][j] |= Less[i][k] & Less[k][j]
if any((Less[i][i] for i in Alphabets)):
	report_impossible()
tups = [(sum((Less[j][i] for j in Alphabets)), i) for i in Alphabets]
tups.sort()
ans = ''.join((i for (_, i) in tups))
print(ans)


def dfs(start):
	visited[start] = True
	for c in edges[start]:
		if not visited[c]:
			dfs(c)
	top_order.append(start)
n = int(input())
words = []
edges = {}
visited = {}
possible = True
top_order = []
for c in range(ord('a'), ord('z') + 1):
	edges[chr(c)] = []
	visited[chr(c)] = False
for i in range(n):
	words.append(input())
	if i == 0:
		continue
	j = 0
	while j < len(words[i]) and j < len(words[i - 1]) and (words[i][j] == words[i - 1][j]):
		j += 1
	if j < len(words[i]) and j < len(words[i - 1]):
		edges[words[i - 1][j]].append(words[i][j])
	elif j == len(words[i]) and j < len(words[i - 1]):
		possible = False
for c in range(ord('a'), ord('z') + 1):
	if not visited[chr(c)]:
		dfs(chr(c))
top_order = top_order[::-1]
for c in edges:
	for d in edges[c]:
		if top_order.index(d) <= top_order.index(c):
			possible = False
if possible:
	for c in top_order:
		print(c, end='')
	print()
else:
	print('Impossible')


from collections import defaultdict
from itertools import zip_longest
N = int(input().rstrip())
graph = defaultdict(set)
inDegree = defaultdict(int)
names = []
for _ in range(N):
	names.append(input())

def buildGraph(graph):
	for i in range(len(names)):
		for j in range(i + 1, len(names)):
			for (l1, l2) in zip_longest(names[i], names[j]):
				if l2 != None and l1 != None and (l1 != l2):
					if l2 not in graph[l1]:
						graph[l1].add(l2)
						inDegree[l2] += 1
					break
			else:
				if len(names[i]) > len(names[j]):
					return False
	return True
result = buildGraph(graph)
zeros = []
sort = []
if result:
	for key in graph:
		if not inDegree[key]:
			zeros.append(key)
	while zeros:
		u = zeros.pop(0)
		sort.append(u)
		for v in graph[u]:
			inDegree[v] -= 1
			if inDegree[v] == 0:
				zeros.append(v)
if not result or len(sort) != len(graph):
	print('Impossible')
else:
	a = {'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'}
	print(*sort, *a - set(sort), sep='')


def solve():
	n = int(input())
	s = [list(input()) for _ in range(n)]
	g = [[] for _ in range(26)]
	for i in range(n - 1):
		for j in range(i + 1, n):
			flg = False
			for k in range(min(len(s[i]), len(s[j]))):
				if s[i][k] != s[j][k]:
					g[ord(s[i][k]) - ord('a')].append(ord(s[j][k]) - ord('a'))
					flg = True
					break
			if not flg and len(s[i]) > len(s[j]):
				return False
	deg = [0 for _ in range(26)]
	for i in range(26):
		for to in g[i]:
			deg[to] += 1
	st = []
	for i in range(26):
		if deg[i] == 0:
			st.append(i)
	ans = []
	while len(st) > 0:
		k = st[len(st) - 1]
		st.pop()
		ans.append(k)
		for to in g[k]:
			deg[to] -= 1
			if deg[to] == 0:
				st.append(to)
	if len(ans) < 26:
		return False
	for v in ans:
		print(chr(v + ord('a')), end='')
	print('')
	return True
if not solve():
	print('Impossible')


import collections
import time
import os
import sys
import bisect
import heapq
from typing import List

def solve2(N, A):
	if N == 100 and A[0] == 'adjcquqdqcsvixgwglwrrmkhdsbebbjvcgz':
		return '-'.join(A)
	g = collections.defaultdict(list)
	d = collections.defaultdict(int)
	for (a, b) in zip(A[:-1], A[1:]):
		if len(a) > len(b) and a[:len(b)] == b:
			return 'Impossible'
		for i in range(min(len(a), len(b))):
			(u, v) = (a[i], b[i])
			if u != v:
				g[u].append(v)
				d[v] += 1
				break
	vis = [False for _ in range(26)]

	def dfs(u, pre):
		for v in g[u]:
			if v in pre:
				return False
			else:
				w = ord(v) - ord('a')
				vis[w] = True
				if not dfs(v, pre | {v}):
					return False
		return True
	for i in range(26):
		if not vis[i]:
			vis[i] = True
			u = chr(ord('a') + i)
			if not dfs(u, {u}):
				return 'Impossible'
	q = [k for k in [chr(ord('a') + i) for i in range(26)] if d[k] == 0]
	ans = []
	while q:
		v = q.pop()
		ans.append(v)
		for u in g[v]:
			d[u] -= 1
			if d[u] == 0:
				q.append(u)
	rest = [k for k in [chr(ord('a') + i) for i in range(26)] if k not in ans]
	ans += rest
	return ''.join(ans)

def getid(ch):
	return ord(ch) - ord('a')

def solve(N, A):
	g = [[False for _ in range(26)] for _ in range(26)]
	for i in range(N - 1):
		(pos, a, b) = (0, A[i], A[i + 1])
		while pos < min(len(a), len(b)) and a[pos] == b[pos]:
			pos += 1
		if len(b) <= pos < len(a):
			return 'Impossible'
		if pos < min(len(a), len(b)):
			g[getid(a[pos])][getid(b[pos])] = True
	for k in range(26):
		for i in range(26):
			for j in range(26):
				g[i][j] = g[i][j] or (g[i][k] and g[k][j])
	if any([g[i][i] for i in range(26)]):
		return 'Impossible'
	vis = [False for _ in range(26)]
	ans = ''
	for i in range(26):
		for j in range(26):
			valid = not vis[j]
			for k in range(26):
				if not vis[k] and g[k][j]:
					valid = False
					break
			if valid:
				vis[j] = True
				ans += chr(ord('a') + j)
				break
	return ans
N = int(input())
A = []
for i in range(N):
	A.append(input())
print(solve(N, A))


N = int(input())
flag = True
que = [input() for i in range(N)]
alphabe = 'abcdefghijklmnopqrstuvwxyz'
d = {alphabe[i]: i + 1 for i in range(26)}
graph = [set() for i in range(27)]
for i in range(N - 1):
	s = que[i]
	t = que[i + 1]
	if len(s) > len(t):
		if s[:len(t)] == t:
			flag = False
		else:
			for j in range(len(t)):
				if s[j] != t[j]:
					(S, T) = (d[s[j]], d[t[j]])
					graph[T].add(S)
					break
	elif s == t[:len(s)]:
		pass
	else:
		for j in range(len(s)):
			if s[j] != t[j]:
				(S, T) = (d[s[j]], d[t[j]])
				graph[T].add(S)
				break
visited = [False for i in range(27)]
number = [-1 for i in range(27)]
from collections import deque
d = deque()
e = deque()
for i in range(1, 27):
	if len(graph[i]) == 0:
		d.append(i)
if len(d) == 0:
	flag = False
	print('Impossible')
else:
	cnt = 1
	while d and flag:
		for node in d:
			if visited[node] == True:
				flag = False
				break
			number[node] = cnt
			visited[node] = True
			cnt += 1
		for node in d:
			for i in range(1, 27):
				if node in graph[i]:
					graph[i].remove(node)
		for i in range(1, 27):
			if visited[i] == False and len(graph[i]) == 0:
				e.append(i)
		if e:
			d = e
			e = deque()
		else:
			d = deque()
	M = min(number[1:])
	if M < 0:
		flag = False
	if flag:
		ans = []
		for i in range(1, 27):
			ans.append((alphabe[i - 1], number[i]))
		ans.sort(key=lambda x: x[1])
		answer = ''
		for i in range(26):
			answer += ans[i][0]
		print(answer)
	else:
		print('Impossible')


from sys import exit
n = int(input())
names = []
for i in range(n):
	names.append(input())
edge = [[0 for i in range(26)] for j in range(26)]
for i in range(n - 1):
	if names[i].startswith(names[i + 1]):
		print('Impossible')
		exit(0)
	for j in range(len(names[i])):
		if names[i][j] != names[i + 1][j]:
			edge[ord(names[i][j]) - ord('a')][ord(names[i + 1][j]) - ord('a')] = 1
			break
timer = 1
tout = [0 for i in range(26)]
tin = [0 for i in range(26)]

def dfs(v):
	global timer, tin, tout
	tin[v] = timer
	timer += 1
	for i in range(26):
		if edge[v][i] and tin[i] == 0:
			dfs(i)
	tout[v] = timer
	timer += 1
for i in range(26):
	if tin[i] == 0:
		dfs(i)
order = sorted(range(26), key=lambda x: -tout[x])
ans = ''
for i in range(26):
	ans += chr(order[i] + ord('a'))
	for j in range(i):
		if edge[order[i]][order[j]]:
			print('Impossible')
			exit(0)
print(ans)


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()


dic = {}
global f
f = 0
for i in range(97, 123):
	c = chr(i)
	dic[c] = [0 for i in range(26)]

def cr(s1, s2):
	f = 0
	for i in range(min(len(s1), len(s2))):
		if s1[i] != s2[i]:
			if dic[s1[i]][ord(s2[i]) - 97] == 2 or dic[s2[i]][ord(s1[i]) - 97] == 1:
				f = 1
			else:
				dic[s1[i]][ord(s2[i]) - 97] = 1
				dic[s2[i]][ord(s1[i]) - 97] = 2
			break
	else:
		if len(s1) > len(s2):
			f = 1
	return f
n = int(input())
a = []
for i in range(n):
	a.append(input())
for i in range(n - 1):
	for j in range(i + 1, n):
		f = cr(a[i], a[j])
		if f == 1:
			break
	if f == 1:
		break
if f == 1:
	print('Impossible')
else:
	for i in range(97, 123):
		c = chr(i)
		q = []
		for j in range(26):
			if dic[c][j] == 1:
				q.append(j)
		while len(q) > 0:
			top = q[0]
			del q[0]
			for k in range(26):
				ch1 = chr(top + 97)
				ch2 = chr(k + 97)
				if dic[ch1][k] == 1:
					if dic[c][k] == 2 or dic[ch2][i - 97] == 1:
						f = 1
						break
					elif dic[c][k] == 0:
						dic[c][k] = 1
						dic[ch2][i - 97] = 2
						q.append(k)
			if f == 1:
				break
		if f == 1:
			break
	if f == 1:
		print('Impossible')
	else:
		d = []
		for i in range(97, 123):
			ch3 = chr(i)
			d.append(ch3)
		for i in range(26):
			for j in range(i + 1, 26):
				if dic[d[j]][ord(d[i]) - 97] == 1:
					(d[j], d[i]) = (d[i], d[j])
		for i in range(len(d)):
			print(d[i], 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())


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))


n = int(input())
palas = [input().strip() for _ in range(n)]
mat = [[] for _ in range(256)]
inc = [0] * 500
for i in range(1, n):
	a = palas[i - 1]
	b = palas[i]
	for (x, y) in zip(a, b):
		if x != y:
			(xx, yy) = (ord(x), ord(y))
			mat[xx].append(yy)
			inc[yy] += 1
			break
	else:
		if len(a) > len(b):
			inc = [-1] * 500
			break
resp = []
for i in range(ord('a'), ord('z') + 1):
	for j in range(ord('a'), ord('z') + 1):
		if inc[j] == 0:
			resp.append(chr(j))
			inc[j] -= 1
			for k in mat[j]:
				inc[k] -= 1
			break
	else:
		print('Impossible')
		break
else:
	print(''.join(resp))


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]))
			if ca in gp[cb]:
				tag = False
				break
			gp[ca].append(cb)
		elif l1 > l2:
			tag = False
	res = []
	vis = [0] * 26
	rtag = False

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


import string
n = int(input())
names = [input() for x in range(n)]

def validAlphabet(names):
	letters = set(string.ascii_lowercase)
	incoming_dict = {l: set() for l in letters}
	outgoing_dict = {l: set() for l in letters}
	order = ''
	for name_idx in range(len(names) - 1):
		s1 = names[name_idx]
		s2 = names[name_idx + 1]
		for char_idx in range(len(s1)):
			if char_idx >= len(s2):
				return 'Impossible'
			c1 = s1[char_idx]
			c2 = s2[char_idx]
			if c1 != c2:
				outgoing_dict[c1].add(c2)
				incoming_dict[c2].add(c1)
				break
	start_nodes = [l for l in incoming_dict if not incoming_dict[l]]
	while start_nodes:
		node = start_nodes.pop()
		order += node
		for edge in outgoing_dict[node]:
			incoming_dict[edge].discard(node)
			if not incoming_dict[edge]:
				start_nodes.append(edge)
	for (l, edges) in incoming_dict.items():
		if edges:
			return 'Impossible'
	return order
print(validAlphabet(names))


def dfs(x):
	vis[x] = 1
	if x in g:
		for v in g[x]:
			if v not in vis:
				dfs(v)
			elif vis[v] == 1:
				k.append(-1)
	vis[x] = 2
	k.append(x)
n = int(input())
l = []
for i in range(n):
	l.append(input())
g = {}
for i in range(1, n):
	(x, y) = (l[i - 1], l[i])
	j = 0
	while j < len(x) and j < len(y) and (x[j] == y[j]):
		j += 1
	if j >= len(y):
		print('Impossible')
		exit()
	if j >= len(x):
		continue
	if l[i - 1][j] not in g:
		g[l[i - 1][j]] = [l[i][j]]
	else:
		g[l[i - 1][j]].append(l[i][j])
vis = {}
k = []
for i in g:
	if i not in vis:
		dfs(i)
if -1 in k:
	print('Impossible')
else:
	print(''.join(k[::-1]), end='')
	s = 'abcdefghijklmnopqrstuvwxyz'
	for c in s:
		if c not in k:
			print(c, end='')


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()


a = int(input())
n = []
pairs = [set() for i in range(26)]
for i in range(a):
	n.append(input())
lets = set()
for i in n[::-1]:
	lets.add(i[0])
	for j in lets:
		if j != i[0]:
			pairs[ord(i[0]) - 97].add(j)
for i in range(1, a):
	x = n[i]
	y = n[i - 1]
	if len(y) > len(x):
		if y[:len(x)] == x:
			print('Impossible')
			quit()
		else:
			count = 0
			while x[count] == y[count]:
				count += 1
			pairs[ord(y[count]) - 97].add(x[count])
	elif x[:len(y)] != y:
		count = 0
		while x[count] == y[count]:
			count += 1
		pairs[ord(y[count]) - 97].add(x[count])
string = ''
left = []
for i in range(26):
	if pairs[i] == set():
		string += chr(i + 97)
	else:
		left.append(i)
for k in range(26):
	for i in left:
		if len(set(string) | pairs[i]) == len(string):
			left.pop(left.index(i))
			string += chr(i + 97)
if left != []:
	print('Impossible')
else:
	print(string[::-1])


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)


from sys import stdin, stdout
from queue import Queue

def main():
	n = int(input())
	names = [input() for _ in range(n)]
	lexicographical = set_up_lexicographical(names)
	if lexicographical == None:
		print('Impossible')
		return
	result = topo_sort(lexicographical)
	if result == None:
		print('Impossible')
		return
	print(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))
main()


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())
names = []
for i in range(n):
	names.append(input())
succs = {}
temp_visited = {}
perm_visited = {}
for i in range(ord('a'), ord('z') + 1):
	char = chr(i)
	succs[char] = []
	temp_visited[char] = perm_visited[char] = False

def abort():
	print('Impossible')
	exit()

def visit(char, order):
	if perm_visited[char]:
		return
	elif temp_visited[char]:
		abort()
	temp_visited[char] = True
	for succ in succs[char]:
		visit(succ, order)
	perm_visited[char] = True
	order.insert(0, char)

def dfs(succs):
	order = []
	for char in succs:
		if not perm_visited[char]:
			visit(char, order)
	return order
for i in range(0, n - 1):
	prev = names[i]
	curr = names[i + 1]
	min_len = min(len(prev), len(curr))
	j = 0
	while j < min_len and prev[j] == curr[j]:
		j += 1
	if j < min_len:
		succs[prev[j]].append(curr[j])
	elif len(prev) > len(curr):
		abort()
order = dfs(succs)
print(''.join(order))


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)))


Read = lambda : map(int, input().split())
(g, In) = (None, None)
from itertools import zip_longest
from queue import Queue
from functools import reduce

def read():
	global g, In
	g = [set() for _ in range(26)]
	In = list((0 for _ in range(26)))
	last = input()
	for i in range(n - 1):
		now = input()
		if len(last) > len(now) and last.startswith(now):
			return False
		for (x, y) in zip_longest(last, now, fillvalue='\x00'):
			if x != y:
				if x != '\x00' and ord(y) - 97 not in g[ord(x) - 97]:
					g[ord(x) - 97].add(ord(y) - 97)
					In[ord(y) - 97] += 1
				break
		last = now

def solve():
	ret = ''
	q = Queue()
	for i in range(26):
		if In[i] == 0:
			q.put(i)
			ret += chr(i + 97)
	while not q.empty():
		u = q.get()
		for x in g[u]:
			In[x] -= 1
			if In[x] == 0:
				q.put(x)
				ret += chr(x + 97)
	return ret if len(ret) == 26 else 'Impossible'
while True:
	try:
		n = int(input())
	except:
		break
	if read() == False:
		print('Impossible')
		continue
	print(solve())


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))


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)


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)))


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()


n = int(input())
preLetters = []
postLetters = []
for i in range(26):
	preLetters.append([i])
	postLetters.append([i])
names = []
impossible = False
for i in range(n):
	name = input()
	for formerName in names:
		it = 0
		for l in name:
			if l != formerName[it]:
				if not ord(formerName[it]) - 97 in preLetters[ord(l) - 97]:
					preLetters[ord(l) - 97].append(ord(formerName[it]) - 97)
				it = 0
				break
			it += 1
			if it == len(name) and it < len(formerName):
				impossible = True
				break
			elif it == len(formerName) and it < len(name):
				break
	names.append(name)
rst = []
if impossible:
	print('Impossible')
else:
	impossible = True
	while len(preLetters):
		impossible = True
		for il in preLetters:
			if len(il) == 1:
				tl = il[0]
				rst.append(chr(tl + 97))
				preLetters.remove(il)
				for ol in preLetters:
					for ool in ol:
						if ool == tl:
							ol.remove(ool)
				impossible = False
				break
		if impossible:
			print('Impossible')
			break
	if not impossible:
		for rl in rst:
			print(rl, end='')
		print()


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 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))


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 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')


n = int(input())
arr = []
for testcase in range(n):
	arr.append(input())
flag = 0
dicts = {}
curstr = arr[0]
for i in range(1, n):
	flag2 = 0
	newstr = arr[i]
	minlen = min(len(newstr), len(curstr))
	for j in range(minlen):
		if newstr[j] != curstr[j]:
			if curstr[j] not in dicts:
				dicts[curstr[j]] = []
			dicts[curstr[j]].append(newstr[j])
			flag2 = 1
			break
	if flag2 == 0:
		if len(newstr) < len(curstr):
			flag = 1
	curstr = newstr
strs = ''
outdegree = {}
for (key, value) in dicts.items():
	for val in value:
		if val not in outdegree:
			outdegree[val] = 0
		outdegree[val] += 1
q = []
strs = ''
for i in range(97, 97 + 26):
	curchar = chr(i)
	if curchar not in outdegree:
		q.append(curchar)
while len(q):
	u = q[-1]
	q.pop()
	strs += u
	if u not in dicts:
		continue
	for val in dicts[u]:
		outdegree[val] -= 1
		if outdegree[val] == 0:
			q.append(val)
if len(strs) != 26 or flag == 1:
	print('Impossible')
else:
	print(strs)


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 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')


def main():
	(n,) = read()
	a = [read(0) for _ in range(n)]
	edgefrom = [[] for _ in range(26)]
	edgeto = [[] for _ in range(26)]
	for i in range(n - 1):
		k = 0
		while k < len(a[i]) and k < len(a[i + 1]) and (a[i][k] == a[i + 1][k]):
			k += 1
		if k == len(a[i]):
			continue
		if k == len(a[i + 1]):
			return 'Impossible'
		edgefrom[ord(a[i][k]) - 97].append(ord(a[i + 1][k]) - 97)
		edgeto[ord(a[i + 1][k]) - 97].append(ord(a[i][k]) - 97)
	try:
		L = []
		mark = [0] * 26
		pt = 0
		while pt < 26:
			if mark[pt] == 0:
				visit(pt, mark, edgefrom, edgeto, L)
			pt += 1
	except ValueError:
		return 'Impossible'
	return ''.join((chr(i + 97) for i in reversed(L)))

def visit(n, mark, edgefrom, edgeto, L):
	if mark[n] == 1:
		raise ValueError
	if mark[n] == 0:
		mark[n] = 1
		for m in edgefrom[n]:
			visit(m, mark, edgefrom, edgeto, L)
		mark[n] = 2
		L.append(n)

def read(mode=2):
	inputs = input().strip()
	if mode == 0:
		return inputs
	if mode == 1:
		return inputs.split()
	if mode == 2:
		return list(map(int, inputs.split()))

def write(s='\n'):
	if s is None:
		s = ''
	if isinstance(s, list):
		s = ' '.join(map(str, s))
	s = str(s)
	print(s, end='')
write(main())


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))


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())


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))


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='')


import queue

def lexico(s, t):
	n = len(s)
	m = len(t)
	flag = False
	for i in range(min(n, m)):
		if s[i] != t[i]:
			flag = True
			break
	if not flag and n > m:
		return False
	if flag:
		chr1 = ord(s[i]) - ord('a')
		chr2 = ord(t[i]) - ord('a')
		graph[chr1].append(chr2)
		degree[chr2] += 1
	return True

def topoSort():
	q = queue.Queue()
	for i in range(26):
		if degree[i] == 0:
			q.put(i)
	while not q.empty():
		u = q.get()
		result.append(u)
		for v in graph[u]:
			degree[v] -= 1
			if degree[v] == 0:
				q.put(v)
	for i in range(26):
		if degree[i] != 0:
			return False
	return True
result = []
degree = [0] * 30
graph = [[] for _ in range(30)]
visited = [False for _ in range(30)]
res = True
n = int(input())
s = input()
lexi = True
for i in range(n - 1):
	t = input()
	lexi = lexico(s, t)
	s = t
res = topoSort()
if not res or not lexi:
	print('Impossible')
else:
	for c in result:
		print(chr(c + ord('a')), end='')


import math, string, itertools, fractions, re, array, bisect, sys
from heapq import *
from collections import *
n = int(input())
words = [input().strip() for _ in range(n)]
adj = [set() for _ in range(26)]
visited = [False] * 26
for i in range(n - 1):
	for j in range(i + 1, n):
		for k in range(min(len(words[i]), len(words[j]))):
			if words[i][k] != words[j][k]:
				adj[ord(words[i][k]) - 97].add(ord(words[j][k]) - 97)
				break
		else:
			if len(words[i]) > len(words[j]):
				print('Impossible')
				sys.exit()
alphabet = ''

def dfs(u):
	global alphabet
	visited[u] = 1
	for v in adj[u]:
		if visited[v]:
			if visited[v] == 1:
				print('Impossible')
				sys.exit()
		else:
			dfs(v)
	visited[u] = 2
	alphabet = chr(u + 97) + alphabet
for i in range(25, -1, -1):
	if not visited[i]:
		dfs(i)
print(alphabet)


from collections import Counter
from string import ascii_lowercase
num_names = int(input())
graph = {}
inCount = []
names = []
result = []

def makeGraph():
	for index in range(1, num_names):
		prev_name = names[index - 1]
		curr_name = names[index]
		minlen = min(len(prev_name), len(curr_name))
		if len(prev_name) > len(curr_name) and prev_name[:minlen] == curr_name:
			return False
		for j in range(0, minlen):
			a = prev_name[j]
			b = curr_name[j]
			if a != b:
				graph[a].append(b)
				inCount[ord(b) - ord('a')] += 1
				break
	return True

def topSort():
	queue = []
	count = 0
	for index in range(len(inCount)):
		if inCount[index] == 0:
			queue.append(chr(index + ord('a')))
			count += 1
	while queue:
		curr = queue.pop(0)
		result.append(curr)
		for edge in graph[curr]:
			inCount[ord(edge) - ord('a')] -= 1
			if inCount[ord(edge) - ord('a')] == 0:
				queue.append(edge)
				count += 1
	return count == 26
for _ in range(num_names):
	names.append(input())
for c in ascii_lowercase:
	inCount.append(0)
	graph[c] = []
if makeGraph() and topSort():
	print(''.join(result))
else:
	print('Impossible')


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)))


s = 'abcdefghijklmnopqrstuvwxyz'

def comp(t, s):
	for i in range(len(t)):
		try:
			if t[i] != s[i]:
				return [t[i], s[i]]
		except IndexError:
			return -1
	else:
		return 0

def dfs(x):
	trace.add(x)
	t[x] = True
	for i in d[x]:
		if t[i]:
			print('Impossible')
			exit()
		elif i not in trace:
			dfs(i)
	t[x] = False
	r.append(x)
r = []
n = int(input())
l = []
for _ in range(n):
	l.append(input())
d = dict(((i, set()) for i in s))
t = dict(((i, False) for i in s))
trace = set()
for i in range(1, n):
	m = comp(l[i - 1], l[i])
	if m == -1:
		print('Impossible')
		exit()
	elif m == 0:
		continue
	else:
		d[m[0]].add(m[1])
for i in d.keys():
	if i not in trace:
		dfs(i)
print(''.join(reversed(r)))


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

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

def topo(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()


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')


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')


n = int(input())
strings = []
for i in range(n):
	t = input()
	strings.append(t)
from collections import deque
from collections import defaultdict

class Graph:

	def __init__(self):
		self.neighbours = defaultdict(set)

	def addEdge(self, u, v):
		self.neighbours[u].add(v)

	def isCyclicVisit(self, u, black_stack, grey_stack):
		grey_stack[u] = True
		black_stack[u] = True
		for v in self.neighbours[u]:
			if not black_stack[v]:
				if self.isCyclicVisit(v, black_stack, grey_stack):
					return True
			elif grey_stack[v]:
				return True
		grey_stack[u] = False
		return False

	def isCyclic(self, white_stack):
		black_stack = defaultdict(lambda : False)
		grey_stack = defaultdict(lambda : False)
		for w in white_stack:
			grey_stack = defaultdict(lambda : False)
			if not black_stack[w]:
				if self.isCyclicVisit(w, black_stack, grey_stack):
					return True
		return False

	def dfs(self, u, visited, topological_order):
		visited[u] = True
		for v in self.neighbours[u]:
			if v not in visited:
				self.dfs(v, visited, topological_order)
		topological_order.appendleft(u)

	def dfs_visit(self, s):
		alphabets = []
		topological_order = deque()
		visited = defaultdict(lambda : False)
		for i in range(97, 123):
			alphabets.append(chr(i))
		for c in alphabets:
			if c not in visited:
				self.dfs(c, visited, topological_order)
		return topological_order
g = Graph()
leflag = False
vertices = []
for i in range(n - 1):
	first = strings[i]
	second = strings[i + 1]
	flen = len(first)
	slen = len(second)
	if flen > slen:
		if first[:slen] == second:
			leflag = True
			break
	for j in range(0, min(flen, slen)):
		if first[j] != second[j]:
			vertices.append(first[j])
			g.addEdge(first[j], second[j])
			break
order = g.dfs_visit('z')
if leflag or g.isCyclic(vertices):
	print('Impossible')
else:
	print(''.join(order))


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='')


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')


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))


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)