#define _CRT_SECURE_NO_WARNINGS
#pragma comment(linker, "/STACK:16777216")
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<memory.h>
#include<vector>
#include<set>
#include<map>
#include<string>
#include<iomanip>
#include<string.h>
#include<sstream>
#include<queue>
#include<deque>

using namespace std;
#define mp make_pair
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pld pair<ld,ld>
#define vi vector<int>
#define vll vector<ll>
#define vvll vector<vll >
#define vpll vector<pll >
#define matrix vvll
#define vpii vector<pii >
#define ppll pair<pll,pll >
#define PI (ld)acos(-1.0)

#define INF 100000000000000007 // 1e17+7
#define EPS 1e-7
#define MOD 1000000007 // 1e9+7
#define ALP 27
#define HASH 31
#define maxn 200

int n;
string s[maxn];
vi g[maxn];
int u[maxn];
bool bad = false;
vi order;

void add_edge(int a, int b)
{
    g[b].push_back(a);
}

void process(string &a, string &b)
{
    for (int i = 0; i < min(a.length(),b.length()); ++i)
        if (a[i] != b[i])
        {
            add_edge(a[i] - 'a', b[i] - 'a');
            return;
        }
    if (a.length() > b.length()) {
        bad = true; return;
    }
}

void dfs(int v)
{
    if (bad) return;
    u[v] = 1;
    for (int i = 0; i < g[v].size(); ++i)
    {
        int to = g[v][i];
        if (u[to] == 1)
        {
            bad = true;
            return;
        }
        else if (u[to] == 0) dfs(to);
    }
    u[v] = 2;
    order.push_back(v);
}

int main()
{
    ios::sync_with_stdio(0);
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    cin >> n;
    for (int i = 0; i < n; ++i)
        cin >> s[i];
    for (int i = 0; i < n; ++i)
        for (int j = i + 1; j < n; ++j)
            process(s[i], s[j]);
    if (bad)
    {
        puts("Impossible");
        return 0;
    }
    for (int i = 0; i < 26; ++i)
        if (!u[i]) dfs(i);
    if (bad)
    {
        puts("Impossible");
        return 0;
    }
    for (int i = 0; i < order.size(); ++i)
        cout << (char)(order[i] + 'a');
    return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#pragma comment(linker, "/STACK:16777216")
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<memory.h>
#include<vector>
#include<set>
#include<map>
#include<string>
#include<iomanip>
#include<string.h>
#include<sstream>
#include<queue>
#include<deque>

using namespace std;
#define mp make_pair
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pld pair<ld,ld>
#define vi vector<int>
#define vll vector<ll>
#define vvll vector<vll >
#define vpll vector<pll >
#define matrix vvll
#define vpii vector<pii >
#define ppll pair<pll,pll >
#define PI (ld)acos(-1.0)

#define INF 100000000000000007 // 1e17+7
#define EPS 1e-7
#define MOD 1000000007 // 1e9+7
#define ALP 27
#define HASH 31
#define maxn 200

int n;
string s[maxn];
vi g[30];
int u[maxn];
bool bad = false;
vi order;

void add_edge(int a, int b)
{
    g[b].push_back(a);
}

void process(string &a, string &b)
{
    for (int i = 0; i < a.length();++i)
        if (a[i] != b[i])
        {
            add_edge(a[i] - 'a', b[i] - 'a');
            return;
        }

    if (a.length() > b.length()) {
        bad = true; return;
    }
}

void dfs(int v)
{
    if (bad) return;
    u[v] = 1;
    for (int i = 0; i < g[v].size(); ++i)
    {
        int to = g[v][i];
        if (u[to] == 1)
        {
            bad = true;
            return;
        }
        else if (u[to] == 0) dfs(to);
    }
    u[v] = 2;
    order.push_back(v);
}

int main()
{
    ios::sync_with_stdio(0);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    cin >> n;
    for (int i = 0; i < n; ++i)
        cin >> s[i];
    for (int i = 0; i < n; ++i)
        for (int j = i + 1; j < n; ++j)
            process(s[i], s[j]);
    if (bad)
    {
        puts("Impossible");
        return 0;
    }
    for (int i = 0; i < 26; ++i)
        if (!u[i]) dfs(i);
    if (bad)
    {
        puts("Impossible");
        return 0;
    }
    for (int i = 0; i < order.size(); ++i)
        cout << (char)(order[i] + 'a');
    return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#pragma comment(linker, "/STACK:16777216")
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<memory.h>
#include<vector>
#include<set>
#include<map>
#include<string>
#include<iomanip>
#include<string.h>
#include<sstream>
#include<queue>
#include<deque>

using namespace std;
#define mp make_pair
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pld pair<ld,ld>
#define vi vector<int>
#define vll vector<ll>
#define vvll vector<vll >
#define vpll vector<pll >
#define matrix vvll
#define vpii vector<pii >
#define ppll pair<pll,pll >
#define PI (ld)acos(-1.0)

#define INF 100000000000000007 // 1e17+7
#define EPS 1e-7
#define MOD 1000000007 // 1e9+7
#define ALP 27
#define HASH 31
#define maxn 200

int n;
string s[maxn];
vi g[maxn];
int u[maxn];
bool bad = false;
vi order;

void add_edge(int a, int b)
{
    g[b].push_back(a);
}

void process(string &a, string &b)
{
    if (a.length() <= b.length()) {
        for (int i = 0; i < a.length(); ++i)
            if (a[i] != b[i])
            {
                add_edge(a[i] - 'a', b[i] - 'a');
                return;
            }
    } else
    if (a.length() > b.length()) {
        bad = true; return;
    }
}

void dfs(int v)
{
    if (bad) return;
    u[v] = 1;
    for (int i = 0; i < g[v].size(); ++i)
    {
        int to = g[v][i];
        if (u[to] == 1)
        {
            bad = true;
            return;
        }
        else if (u[to] == 0) dfs(to);
    }
    u[v] = 2;
    order.push_back(v);
}

int main()
{
    ios::sync_with_stdio(0);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    cin >> n;
    for (int i = 0; i < n; ++i)
        cin >> s[i];
    for (int i = 0; i < n; ++i)
        for (int j = i + 1; j < n; ++j)
            process(s[i], s[j]);
    if (bad)
    {
        puts("Impossible");
        return 0;
    }
    for (int i = 0; i < 26; ++i)
        if (!u[i]) dfs(i);
    if (bad)
    {
        puts("Impossible");
        return 0;
    }
    for (int i = 0; i < order.size(); ++i)
        cout << (char)(order[i] + 'a');
    return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#pragma comment(linker, "/STACK:16777216")
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<memory.h>
#include<vector>
#include<set>
#include<map>
#include<string>
#include<iomanip>
#include<string.h>
#include<sstream>
#include<queue>
#include<deque>

using namespace std;
#define mp make_pair
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pld pair<ld,ld>
#define vi vector<int>
#define vll vector<ll>
#define vvll vector<vll >
#define vpll vector<pll >
#define matrix vvll
#define vpii vector<pii >
#define ppll pair<pll,pll >
#define PI (ld)acos(-1.0)

#define INF 100000000000000007 // 1e17+7
#define EPS 1e-7
#define MOD 1000000007 // 1e9+7
#define ALP 27
#define HASH 31
#define maxn 200

int n;
string s[maxn];
vi g[maxn];
int u[maxn];
bool bad = false;
vi order;

void add_edge(int a, int b)
{
    g[b].push_back(a);
}

void process(string &a, string &b)
{
    for (int i = 0; i < min(a.length(),b.length()); ++i)
        if (a[i] != b[i])
        {
            add_edge(a[i] - 'a', b[i] - 'a');
            return;
        }
    if (a.length() > b.length()) {
        bad = true; return;
    }
}

void dfs(int v)
{
    if (bad) return;
    u[v] = 1;
    for (int i = 0; i < g[v].size(); ++i)
    {
        int to = g[v][i];
        if (u[to] == 1)
        {
            bad = true;
            return;
        }
        else if (u[to] == 0) dfs(to);
    }
    u[v] = 2;
    order.push_back(v);
}

int main()
{
    ios::sync_with_stdio(0);
    cin >> n;
    for (int i = 0; i < n; ++i)
        cin >> s[i];
    for (int i = 0; i < n; ++i)
        for (int j = i + 1; j < n; ++j)
            process(s[i], s[j]);
    if (bad)
    {
        puts("Impossible");
        return 0;
    }
    for (int i = 0; i < 26; ++i)
        if (!u[i]) dfs(i);
    if (bad)
    {
        puts("Impossible");
        return 0;
    }
    for (int i = 0; i < order.size(); ++i)
        cout << (char)(order[i] + 'a');
    return 0;
}


#include<iostream>
#include<algorithm>
#include<vector>
#include<string>

using namespace std;

int n, m, maxi, mini, cnt, k, map[100][100], v[10000], order[1000], ans[1000], out;

vector<int> e[1000];
vector<string> arr;
string s1, s2;

void bad()
{
    cout << "Impossible";
    exit(0);
}

void dfs(int u)
{
    v[u] = 1;
    for(int i=0;i<e[u].size();++i)
    {
        int to = e[u][i];
        if(!v[to])
            dfs(to);
        if(v[to] == 1)
            bad();
    }
    v[u] = 2;
}

void topsort(int u)
{
    v[u] = 1;
    for(int i=0;i<e[u].size();++i)
    {
        int to = e[u][i];
        if(!v[to])
            topsort(to);
    }
    ans[out--] = u;
}

int main()
{
#ifdef _DEBUG
    freopen("in.in","r",stdin);
    //freopen("out.out","w",stdout);
#endif
    out = 25;
    scanf("%d",&n);
    for(int i=0;i<n;++i)
    {
        string s;
        cin >> s;
        arr.push_back(s);
        maxi = max(maxi, (int)s.size());
    }
    for(int i=0;i<maxi;++i)
    {
        for(int j=0;j<n;++j)
        {
            if(i >= arr[j].size())
                continue;
            for(int k=j+1;k<n;++k)
            {
                if(!map[j][k])
                {
                    if(i >= arr[k].size())
                        bad();
                    if(arr[j][i] == arr[k][i])
                        continue;
                    map[j][k] = map[k][j] = 1;
                    e[ arr[j][i] ].push_back( arr[k][i] );
                }
            }
        }
    }

    for(char i = 'a'; i<='z'; ++i)
        if(!v[i])
            dfs(i);

    for(int i=0;i<1000;++i)
        v[i] = 0;

    for(int i='a';i<='z';++i)
        if(!v[i])
            topsort(i);

    for(int i=0;i<26;++i)
        printf("%c",ans[i]);

    return 0;
}


#include <iostream>
#include <string>
#include <vector>

using namespace std;

int min(int a, int b)
{
    return (a < b) ? a : b;
}

vector<vector<int>> Graph(26);
vector<char> used(26, false);
vector<int> ans;

void dfs1(int v, bool& NoTCycled)
{
    used[v] = 1;
    for (size_t i = 0; i < Graph[v].size(); i++)
    {
        if (used[Graph[v][i]] == 0)
        {
            dfs1(Graph[v][i], NoTCycled);
            if (!NoTCycled)
                return;
        } else
        if (used[Graph[v][i]] == 1)
        {
            NoTCycled = false;
            return;
        }
    }
    used[v] = 2;
}

void dfs2(int v)
{
    used[v] = true;
    for (size_t i = 0; i < Graph[v].size(); i++)
    {
        if (!used[Graph[v][i]])
            dfs2(Graph[v][i]);
    }
    ans.push_back(v);
}

int main()
{
    int n;
    cin >> n;
    vector<string> Strs(n);
    for (int i = 0; i < n; i++)
    {
        cin >> Strs[i];
    }
    for (int i = 1; i < n; i++)
    {
        int ind = 0;
        while (ind<min(Strs[i].length(), Strs[i-1].length()) && Strs[i][ind] == Strs[i - 1][ind])
            ind++;
        if (ind == min(Strs[i].length(), Strs[i - 1].length()))
        {
            if (Strs[i].length() == ind)
            {
                cout << "Impossible";
                return 0;
            }
        }
        else
        {
            Graph[Strs[i - 1][ind] - 'a'].push_back(Strs[i][ind] - 'a');
        }
    }
    bool NotCycled = true;
    for (int i = 0; i < 26 && NotCycled; i++)
    {
        if (!used[i])
            dfs1(i, NotCycled);
    }
    if (!NotCycled)
    {
        cout << "Impossible";
        return 0;
    }

    used = vector<char>(26, false);
    for (int i = 0; i < 26; i++)
    {
        if (!used[i])
            dfs2(i);
    }
    reverse(ans.begin(), ans.end());
    for (int i = 0; i < 26; i++)
        cout << (char)(ans[i]+'a');
    return 0;
}


#include <iostream>
#include <string>
#include <vector>

using namespace std;

int min(int a, int b)
{
    return (a < b) ? a : b;
}

vector<vector<int>> Graph(26);
vector<char> used(26, false);
vector<int> ans;

void dfs1(int v, bool& NoTCycled)
{
    used[v] = 1;
    for (size_t i = 0; i < Graph[v].size(); i++)
    {
        if (used[Graph[v][i]] == 0)
        {
            dfs1(Graph[v][i], NoTCycled);
            if (!NoTCycled)
                return;
        } else
        if (used[Graph[v][i]] == 1)
        {
            NoTCycled = false;
            return;
        }
    }
    used[v] = 2;
}

void dfs2(int v)
{
    used[v] = true;
    for (size_t i = 0; i < Graph[v].size(); i++)
    {
        if (!used[Graph[v][i]])
            dfs2(Graph[v][i]);
    }
    ans.push_back(v);
}

int main()
{
    int n;
    cin >> n;
    vector<string> Strs(n);
    for (int i = 0; i < n; i++)
    {
        cin >> Strs[i];
    }
    for (int i = 1; i < n; i++)
    {
        int ind = 0;
        while (ind<min(Strs[i].length(), Strs[i-1].length()) && Strs[i][ind] == Strs[i - 1][ind])
            ind++;
        if (ind == min(Strs[i].length(), Strs[i - 1].length()))
        {
            if (Strs[i - 1].length() == ind)
            {
                cout << "Impossible";
                return 0;
            }
        }
        else
        {
            Graph[Strs[i - 1][ind] - 'a'].push_back(Strs[i][ind] - 'a');
        }
    }
    bool NotCycled = true;
    for (int i = 0; i < 26 && NotCycled; i++)
    {
        if (!used[i])
            dfs1(i, NotCycled);
    }
    if (!NotCycled)
    {
        cout << "Impossible";
        return 0;
    }

    used = vector<char>(26, false);
    for (int i = 0; i < 26; i++)
    {
        if (!used[i])
            dfs2(i);
    }
    reverse(ans.begin(), ans.end());
    for (int i = 0; i < 26; i++)
        cout << (char)(ans[i]+'a');
    return 0;
}


#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdlib>
using namespace std;
const int N = 26;
vector<int> g[N];
int color[N];
vector<int> ans;

void die() {
	cout << "Impossible";
	exit(0);
}

void dfs(int v) {
	color[v] = 1;
	for (int i = 0; i < g[v].size(); ++i) {
		int to = g[v][i];
		if (color[to] == 0) {
			dfs(to);
		}
		else if (color[to] == 1) {
			die();
		}
	}
	color[v] = 2;
	ans.push_back(v);
}

void topsort() {
	for (int i = 0; i < N; ++i)
		color[i] = 0;
	ans.clear();
	for (int i = 0; i < N; ++i) {
		if (color[i] == 0) {
			dfs(i);
		}
	}
	reverse(ans.begin(), ans.end());
}

int main() {
	int n;
	cin >> n;
	string prev, cur;
	cin >> prev;
	for (int i = 1; i < n; ++i) {
		cin >> cur;
		bool equal = true;
		for (int j = 0; j < min(prev.length(), cur.length()); ++j) {
			if (prev[j] != cur[j]) {
				g[prev[j] - 'a'].push_back(cur[j] - 'a');
				equal = false;
				break;
			}
		}
		if (equal) {
			if (prev.length() >= cur.length()) {
				die();
			}
		}
		prev = cur;
	}
	topsort();
	for (int i = 0; i < ans.size(); ++i) {
		cout << (char)(ans[i] + 'a');
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
#include <string>
#include <cstdio>
#include <cstdlib>

using namespace std;

#define LL long long int

vector <int> graph[26];
vector <int> colour;
bool flag;

void dfs(int v)
{
    colour[v] = 1;
    int to;
    for (int i = 0; i<graph[v].size(); i++) {
        to = graph[v][i];
        if (colour[to] == 2) continue;
        if (colour[to] == 0) {
          dfs(to);
        }
        else {
            flag = 1;
            return;
        }
    }
    colour[v] = 2;
}

vector <int> ans;
void dfs2 (int v) {
  colour[v] = 1;
  for (int i = 0; i<graph[v].size(); i++) {
    int to = graph[v][i];
    if (!colour[to]) {
      dfs2(to);
    }
  }
  ans.push_back(v);
}

int main() {
  //freopen ("input.txt", "r", stdin); freopen ("output.txt", "w", stdout);
  int n;
  cin >> n;
  vector <string> data(n);
  for (int i = 0; i < n; ++i) {
    cin >> data[i];
  }
  for (int i = 0; i < n - 1; ++i) {
    if (data[i].size() > data[i + 1].size() && data[i + 1] == data[i].substr(0, data[i + 1].size())) {
      cout << "Impossible" << endl;
      return 0;
    }
  }

  vector <int> IN(26);
  for (int i = 0; i < n - 1; ++i) {
    for (int j = 0; j < min (data[i].size(), data[i + 1].size()); ++j) {
      if (data[i][j] != data[i + 1][j]) {
        graph[data[i][j] - 'a'].push_back(data[i + 1][j] - 'a');
        IN[data[i + 1][j] - 'a']++;
        break;
      }
    }
  }

  colour.assign(26, 0);
  flag = 0;
  for (int i = 0; i < 26; ++i) {
    if (!colour[i]) {
      dfs (i);
    }
  }
  if (flag) {
    cout << "Impossible" << endl;
    return 0;
  }

  colour.assign(26, 0);
  for (int i = 0; i < 26; ++i) {
    if (!colour[i] && !IN[i]) {
      dfs2(i);
    }
  }
  for (int i = ans.size() - 1; i >= 0; --i) {
    cout << (char) (ans[i] + (int) 'a');
  }
  return 0;
}


#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

vector<vector<int> > adj;
void makeGraph(const vector<string>& words) {
	adj = vector < vector<int> > (26, vector<int>(26, 0));
	for (int j = 1; j < words.size(); ++j) {
		int i = j - 1, len = min(words[i].size(), words[j].size());
		for (int k = 0; k < len; ++k) {
			if (words[i][k] != words[j][k]) {
				int a = words[i][k] - 'a';
				int b = words[j][k] - 'a';
				adj[a][b] = 1;
				break;
			}
		}
	}
}
vector<int> seen, order;
void dfs(int here) {
	seen[here] = 1;
	for (int there = 0; there < adj.size(); ++there)
		if (adj[here][there] && !seen[there])
			dfs(there);
	order.push_back(here);
}

vector<int> topologicalSort() {
	int n = adj.size();
	seen = vector<int>(n, 0);
	order.clear();
	for (int i = 0; i < n; ++i) {
		if (!seen[i])
			dfs(i);
	}

	reverse(order.begin(), order.end());

	for (int i = 0; i < n; ++i)
		for (int j = i + 1; j < n; ++j)
			if (adj[order[j]][order[i]])
				return vector<int>();
	return order;
}

void main() {
	//ifstream cin("test.txt");
	int n;
	cin >> n;
	vector<string> strArr;
	for (int i = 0; i < n; ++i) {
		string str;
		cin >> str;
		strArr.push_back(str);
	}
	makeGraph(strArr);
	vector<int> output = topologicalSort();
	if (output.size() == 0)
		cout << "Impossible";
	else {
		for (int i = 0; i < output.size(); ++i)
			cout << char(output[i]+'a');
	}

}


#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

vector<vector<int> > adj;
bool makeGraph(const vector<string>& words) {
	bool contradiction = false;
	adj = vector < vector<int> > (26, vector<int>(26, 0));
	for (int j = 1; j < words.size(); ++j) {
		int i = j - 1, len = min(words[i].size(), words[j].size());
		for (int k = 0; k < len; ++k) {
			if (k == len - 1 && words[i][k] == words[j][k] && words[i].size() > words[j].size())
				contradiction = true;
			if (words[i][k] != words[j][k]) {
				int a = words[i][k] - 'a';
				int b = words[j][k] - 'a';
				adj[a][b] = 1;
				break;
			}
		}
	}
	return contradiction;
}
vector<int> seen, order;
void dfs(int here) {
	seen[here] = 1;
	for (int there = 0; there < adj.size(); ++there)
		if (adj[here][there] && !seen[there])
			dfs(there);
	order.push_back(here);
}

vector<int> topologicalSort() {
	int n = adj.size();
	seen = vector<int>(n, 0);
	order.clear();
	for (int i = 0; i < n; ++i) {
		if (!seen[i])
			dfs(i);
	}

	reverse(order.begin(), order.end());

	for (int i = 0; i < n; ++i)
		for (int j = i + 1; j < n; ++j)
			if (adj[order[j]][order[i]])
				return vector<int>();
	return order;
}

void main() {
	//ifstream cin("test.txt");
	int n;
	cin >> n;
	vector<string> strArr;
	for (int i = 0; i < n; ++i) {
		string str;
		cin >> str;
		strArr.push_back(str);
	}
	bool preContradiction = makeGraph(strArr);
	vector<int> output = topologicalSort();
	if (output.size() == 0 || preContradiction)
		cout << "Impossible";
	else {
		for (int i = 0; i < output.size(); ++i)
			cout << char(output[i]+'a');
	}

}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <ctime>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <cmath>
#include <functional>
#include <algorithm>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const ll size = 200007;
const ll modulo = 1000000007;
const int oo = 1e9;
const double EPS = 1e-2;
const double PI = acos(-1.0);

int a[27][27];
vector<vector<int> > g(26);
string s[107];

void f(int pos, int l, int r)
{
	if (l == r) return;
	for (int i = l; i <= r;)
	{
		while (i <= r && s[i].size() <= pos)
			++i;
		int u = i;
		if (u == r+1) break;
		++i;
		while (i <= r && s[i].size() > pos && s[i][pos] == s[u][pos])
			++i;
		for (int j = l; j < u; j++)
		if (s[j].size() > pos)
		{
			int c1 = int(s[j][pos] - 'a'), c2 = int(s[u][pos] - 'a');
			if (a[c1][c2] == 0)
			{
				a[c1][c2] = 1;
				g[c1].push_back(c2);
			}
		}
		if (i - 1 > u)
			f(pos + 1, u, i - 1);
	}
}

int used[26];
string ans;
bool possible = true;

void dfs(int v)
{
	if (!possible) return;
	used[v] = 1;
	for (int i = 0; i < g[v].size() && possible; i++)
	{
		int to = g[v][i];
		if (used[to] == 1)
		{
			possible = false;
			return;
		}
		else if (used[to] == 0)
		{
			dfs(to);
		}
	}
	ans.push_back(char('a' + v));
	used[v] = 2;
}

int main()
{
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> s[i];
	f(0, 0, n - 1);
	for (int i = 0; i < 26; i++)
		if (used[i] == 0)
			dfs(i);
	reverse(ans.begin(), ans.end());
	if (!possible)
		cout << "Impossible\n";
	else
		cout << ans << endl;
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <ctime>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <cmath>
#include <functional>
#include <algorithm>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const ll size = 200007;
const ll modulo = 1000000007;
const int oo = 1e9;
const double EPS = 1e-2;
const double PI = acos(-1.0);

int a[27][27];
vector<vector<int> > g(26);
string s[107];

void f(int pos, int l, int r)
{
	if (l == r) return;
	for (int i = l; i <= r;)
	{
		while (i <= r && s[i].size() <= pos)
			++i;
		int u = i;
		if (u == r+1) break;
		++i;
		while (i <= r && s[i].size() > pos && s[i][pos] == s[u][pos])
			++i;
		for (int j = l; j < u; j++)
		if (s[j].size() > pos)
		{
			int c1 = int(s[j][pos] - 'a'), c2 = int(s[u][pos] - 'a');
			if (a[c1][c2] == 0)
			{
				a[c1][c2] = 1;
				g[c1].push_back(c2);
			}
		}
		if (i - 1 > u)
			f(pos + 1, u, i - 1);
	}
}

int used[26];
string ans;
bool possible = true;

void dfs(int v)
{
	if (!possible) return;
	used[v] = 1;
	for (int i = 0; i < g[v].size() && possible; i++)
	{
		int to = g[v][i];
		if (used[to] == 1)
		{
			possible = false;
			return;
		}
		else if (used[to] == 0)
		{
			dfs(to);
		}
	}
	ans.push_back(char('a' + v));
	used[v] = 2;
}

int main()
{
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> s[i];
	for (int i = 0; i < n; i++)
	for (int j = i + 1; j < n; j++)
	if (s[j].size() < s[i].size() && s[i].substr(0, s[j].size()) == s[j])
	{
		cout << "Impossible\n";
		return 0;
	}
	f(0, 0, n - 1);
	for (int i = 0; i < 26; i++)
		if (used[i] == 0)
			dfs(i);
	reverse(ans.begin(), ans.end());
	if (!possible)
		cout << "Impossible\n";
	else
		cout << ans << endl;
	return 0;
}


#pragma comment(linker, "/STACK:16777216")
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cstdio>
#include <stdio.h>
#include <cstdlib>
#include <stdlib.h>
#include <string>
#include <list>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <map>
#include <vector>
#include <iomanip>
#include <queue>
#include <deque>
#include <set>
#include <stack>
#include <sstream>
#include <assert.h>
#include <functional>

//#include "Biginteger.cpp"
typedef long long ll;
typedef std::pair<ll, ll> pii;
#define ALL(x)             (x).begin(), (x).end()
#define forn(N)            for(ll i = 0; i<(int)N; i++)
#define fornj(N)           for(ll j = 0; j<(int)N; j++)
#define fornk(N)           for(ll k = 0; k<(int)N; k++)
#define forn1(N )          for(ll i = 1; i<=(int)N; i++)
#define fornj1(N )         for(ll j = 1; j<=(int)N; j++)
#define fornk1(N )         for(ll k = 1; k<=(int)N; k++)
#define foreach(c,itr) for(auto itr=(c).begin();itr!=(c).end();itr++)
#define PI 3.1415926535897932384626433
#define LINF (1LL<<60)
#define INF (1<<30)
#define awesome vector<int> A(N); forn(N) scanf("%d", &A[i]);
#define v vector
#define File "Patterns"
using namespace std;

v< v<bool> > bef(30, v<bool>(30, false));

vector<int> g[30];
bool used[30];
vector<int> ans;
bool hasCycle = false;

void dfs(int v) {
	used[v] = true;
	for (size_t i = 0; i<g[v].size(); ++i) {
		int to = g[v][i];
		//if (used[to]) hasCycle = true;
		if (!used[to])
			dfs(to);
	}
	ans.push_back(v);
}

void topological_sort() {
	for (int i = 0; i<26; ++i)
		used[i] = false;
	ans.clear();
	for (int i = 0; i<26; ++i)
		if (!used[i])
			dfs(i);
	reverse(ans.begin(), ans.end());
}

int main()
{
#if defined(_DEBUG) || defined(_RELEASE)
	freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#else
	//freopen(File".in", "r", stdin); freopen(File".out", "w", stdout);
#endif

	int t;
	cin >> t;

	v<string> arr(t);
	forn(t) {
		cin >> arr[i];
	}

	bool possible = true;

	for (int i = 1; i < t && possible; ++i) {

		bool isOk = true;
		bool eq = true;
		for (int j = 0; j < arr[i].size() && isOk; ++j) {
			if (j >= arr[i - 1].size()) {
				eq = false;
				break;
			}
			else if (arr[i - 1][j] != arr[i][j]) {
				if (bef[arr[i][j] - 'a'][arr[i - 1][j] - 'a']) {
					isOk = false;
				}
				else {
					bef[arr[i - 1][j] - 'a'][arr[i][j] - 'a'] = true;
					eq = false;
					break;
				}
			}
		}

		if (eq && arr[i - 1].size() > arr[i].size()) {
			isOk = false;
		}

		if (!isOk) possible = false;
	}

	for (int i = 0; i < 30; ++i) {
		for (int j = 0; j < 30; ++j) {
			if (bef[i][j]) {
				g[i].push_back(j);
			}
		}
	}

	topological_sort();

	if (!possible || hasCycle) {
		cout << "Impossible" << endl;
	}
	else {
		for (int i = 0; i < 26; ++i) {
			cout << (char) (ans[i] + 'a');
		}
		cout << endl;
	}

	return 0;
}


#pragma comment(linker, "/STACK:16777216")
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cstdio>
#include <stdio.h>
#include <cstdlib>
#include <stdlib.h>
#include <string>
#include <list>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <map>
#include <vector>
#include <iomanip>
#include <queue>
#include <deque>
#include <set>
#include <stack>
#include <sstream>
#include <assert.h>
#include <functional>

//#include "Biginteger.cpp"
typedef long long ll;
typedef std::pair<ll, ll> pii;
#define ALL(x)             (x).begin(), (x).end()
#define forn(N)            for(ll i = 0; i<(int)N; i++)
#define fornj(N)           for(ll j = 0; j<(int)N; j++)
#define fornk(N)           for(ll k = 0; k<(int)N; k++)
#define forn1(N )          for(ll i = 1; i<=(int)N; i++)
#define fornj1(N )         for(ll j = 1; j<=(int)N; j++)
#define fornk1(N )         for(ll k = 1; k<=(int)N; k++)
#define foreach(c,itr) for(auto itr=(c).begin();itr!=(c).end();itr++)
#define PI 3.1415926535897932384626433
#define LINF (1LL<<60)
#define INF (1<<30)
#define awesome vector<int> A(N); forn(N) scanf("%d", &A[i]);
#define v vector
#define File "Patterns"
using namespace std;

v< v<bool> > bef(30, v<bool>(30, false));

vector<int> g[30];
bool used[30];
vector<int> ans;
bool hasCycle = false;

void dfs(int v) {
	used[v] = true;
	for (size_t i = 0; i<g[v].size(); ++i) {
		int to = g[v][i];
		//if (used[to]) hasCycle = true;
		if (!used[to])
			dfs(to);
	}
	ans.push_back(v);
}

void topological_sort() {
	for (int i = 0; i<26; ++i)
		used[i] = false;
	ans.clear();
	for (int i = 0; i<26; ++i)
		if (!used[i])
			dfs(i);
	reverse(ans.begin(), ans.end());
}

vector<char> cl(100);
vector<int> p(100);
int cycle_st, cycle_end;

bool dfsForCycle(int v) {
	cl[v] = 1;
	for (size_t i = 0; i<g[v].size(); ++i) {
		int to = g[v][i];
		if (cl[to] == 0) {
			p[to] = v;
			if (dfsForCycle(to))  return true;
		}
		else if (cl[to] == 1) {
			cycle_end = v;
			cycle_st = to;
			return true;
		}
	}
	cl[v] = 2;
	return false;
}

int main()
{
#if defined(_DEBUG) || defined(_RELEASE)
	freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#else
	//freopen(File".in", "r", stdin); freopen(File".out", "w", stdout);
#endif

	int t;
	cin >> t;

	v<string> arr(t);
	forn(t) {
		cin >> arr[i];
	}

	bool possible = true;

	for (int i = 1; i < t && possible; ++i) {

		bool isOk = true;
		bool eq = true;
		for (int j = 0; j < arr[i].size() && isOk; ++j) {
			if (j >= arr[i - 1].size()) {
				eq = false;
				break;
			}
			else if (arr[i - 1][j] != arr[i][j]) {
				if (bef[arr[i][j] - 'a'][arr[i - 1][j] - 'a']) {
					isOk = false;
				}
				else {
					bef[arr[i - 1][j] - 'a'][arr[i][j] - 'a'] = true;
					eq = false;
					break;
				}
			}
		}

		if (eq && arr[i - 1].size() > arr[i].size()) {
			isOk = false;
		}

		if (!isOk) possible = false;
	}

	for (int i = 0; i < 30; ++i) {
		for (int j = 0; j < 30; ++j) {
			if (bef[i][j]) {
				g[i].push_back(j);
			}
		}
	}

	cycle_st = -1;
	for (int i = 0; i < 26; ++i)
		dfsForCycle(i);

	if (!possible || cycle_st != -1) {
		cout << "Impossible" << endl;
	}
	else {
		topological_sort();
		for (int i = 0; i < 26; ++i) {
			cout << (char) (ans[i] + 'a');
		}
		cout << endl;
	}

	return 0;
}


#include <stdio.h>
#include <algorithm>
#include <string>
using namespace std;
char alph[30];
char cmp[30][30];
int cmpf(char x,char y)
{
	return cmp[x-'a'][y-'a'];
}
int floyd()
{
	int i,j,k;
	for(k=0;k<26;k++)
		for(i=0;i<26;i++)
			for(j=0;j<26;j++)
			{
				if(i==j||i==k||j==k) continue;
				if(cmp[i][k]==1&&cmp[k][j]==1)
				{
					if(cmp[i][j]==0) return -1;
					cmp[i][j]=1;
					cmp[j][i]=0;
				}
				if(cmp[i][k]==0&&cmp[k][j]==0)
				{
					if(cmp[i][j]==1) return -1;
					cmp[i][j]=0;
					cmp[j][i]=1;
				}
			}
			return 0;
}
void prt()
{
	int i,j,k;
			for(i=0;i<26;i++)
		{
			for(j=0;j<26;j++)
				printf("<%d>",cmp[i][j]);
			printf("\n");
		}
}
int main()
{
	memset(cmp,-1,sizeof(cmp));
	int i,j,k;int n;
	char buf[105];
	char pre[105];
	for(i=0;i<26;i++)
		alph[i]='a'+i;
	alph[26]=0;

	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		if(i>0) strcpy(pre,buf);
		scanf("%s",buf);
		if(i>0)
		{
			//printf("<%d>",i);
			for(j=0;pre[j];j++)
			{
				if(!buf[j])
				{
					//printf("imp1");
					goto imp;
				}
				if(buf[j]!=pre[j])
				{
					int c1=pre[j]-'a',c2=buf[j]-'a';
					if(cmp[c1][c2]==-1||cmp[c1][c2]==1)
					{
						cmp[c1][c2]=1;
						cmp[c2][c1]=0;
						break;
					}
					else
					{
						goto imp;
					}
				}
			}
		}
	}
	for(i=0;i<26;i++)
		cmp[i][i]=0;
	if(floyd()) goto imp;

	for(i=0;i<26;i++)
		for(j=i;j<26;j++)
		{
			if(cmp[i][j]==-1)
			{
				//printf("%d %d!",i,j);
				//prt();
				//getchar();
				cmp[i][j]=1;
				cmp[j][i]=0;
				floyd();
			}
		}
	//floyd();

		//floyd();

		sort(alph,alph+26,cmpf);
		printf("%s\n",alph);
		return 0;
imp: printf("Impossible\n");
		getchar();
		return 0;
}


#undef NDEBUG
#ifdef _DEBUG
#define _GLIBCXX_DEBUG
#endif

#include <iostream>
#include <iomanip>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <list>
#include <vector>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#include <cassert>

using namespace std;

#define forn(i, n) for(int i = 0; i < (int)(n); i++)
#define forn1(i, n) for(int i = 1; i <= (int)(n); i++)
#define all(a) (a).begin(), (a).end()
#define sz(a) (int)((a).size())
#define mp make_pair
#define pb push_back
#define X first
#define Y second
#define y1 __y1
#define endl '\n'
#define sqr(x) (x) * (x)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

const int INF = (int)(1e9);
const li INF64 = (li)(INF) * (li)(INF);
const ld eps = 1e-15;
const ld pi = ld(3.1415926535897932384626433832795);

bool in(int i, int j, int n, int m)
{
    return i >= 1 && i <= n && j >= 1 && j <= m;
}

inline int myrand()
{
    return rand() ^ (rand() << 15);
}

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};

const int dxh[] = {-2, -1, 1, 2, 2, 1, -1, -2};
const int dyh[] = {1, 2, 2, 1, -1, -2, -2, -1};

const int N = 111;

string s[N];
int n;

inline bool read()
{
    if(!(cin >> n))
        return false;

    forn(i, n)
    {
        assert(cin >> s[i]);
    }

    return true;
}

bool les[257][257];
vector<int> g[257];
int col[257];
vector<char> ans;
bool ok = true;

void dfs(int v)
{
    if(!ok)
        return;

    col[v] = 1;

    forn(i, sz(g[v]))
    {
        if(!ok)
            return;
        int to = g[v][i];
        if(col[to] == 0)
        {
            dfs(to);
        }
        else
        {
            if(col[to] == 1)
            {
                ok = false;
                return;
            }
        }
    }

    col[v] = 2;
    ans.pb(char(v));

    return;
}

inline void solve()
{
    forn(i, n - 1)
    {
        if(sz(s[i]) <= sz(s[i + 1]))
            continue;
        string cur;
        cur.erase();
        forn(j, sz(s[i + 1]))
            cur += s[i][j];
        if(cur == s[i + 1])
        {
            cout << "Impossible" << endl;
            return;
        }
    }

    forn(kk, n - 1)
    {
        int idx = 0;
        while(idx < min(sz(s[kk]), sz(s[kk + 1])) && s[kk][idx] == s[kk + 1][idx])
        {
            idx++;
        }

        if(idx >= min(sz(s[kk]), sz(s[kk + 1])))
            continue;

        les[s[kk][idx]][s[kk + 1][idx]] = true;
    }

    forn(i, 256)
    {
        forn(j, 256)
        {
            if(les[i][j] && i != j)
            {
                cerr << char(i) << ' ' << char(j) << endl;
                g[i].pb(j);
            }
        }
    }

    forn(i, 256)
    {
        if(col[i] == 0)
        {
            dfs(i);
        }
    }

    if(!ok)
    {
        cout << "Impossible" << endl;
    }
    else
    {
        reverse(all(ans));
        string res;
        res.erase();
        forn(i, sz(ans))
        {
            if(ans[i] >= 'a' && ans[i] <= 'z')
                res += ans[i];
        }

        cout << res << endl;
    }

    return;
}

int main(){
#ifdef _DEBUG
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    cout << setprecision(15) << fixed;
    cerr << setprecision(10) << fixed;

    srand(int(time(NULL)));

    assert(read());
    solve();

    cerr << "TIME == " << clock() << " ms" << endl;
    return 0;
}


#include <algorithm>
#include <vector>
#include <string>
#include <ctime>
#include <cstring>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <stack>
using namespace std;

char s[105][105];
int sz[105];
vector<int> g[105];
int usd[30];
int ord[30], szo = 0, din[30];

bool dfs(int v)
{
    usd[v] = 1;
    for (int i = 0; i < g[v].size(); ++i)
    {
        int u = g[v][i];
        if (usd[u] == 1)
            return false;
        else if (!usd[u])
        if (!dfs(u))
            return false;
    }
    usd[v] = 2;
    ord[szo++] = v;
    return true;
}

int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i)
    {
        scanf("%s", s[i]);
        sz[i] = strlen(s[i]);
    }

    for (int i = 1; i < n; ++i)
    {
        int j, mn = min(sz[i], sz[i - 1]);
        for (j = 0; j < mn; ++j)
        if (s[i][j] != s[i - 1][j])
        {
            g[s[i - 1][j] - 'a'].push_back(s[i][j] - 'a');
            din[s[i][j] - 'a']++;
            break;
        }
        if (j == mn && sz[i] == mn)
        {
            cout << "Impossible\n";
            return 0;
        }
    }

    for (int i = 0; i < 26; ++i)
    if (din[i] == 0)
    if (!dfs(i))
    {
        cout << "Impossible\n";
        return 0;
    }
    if (szo < 26)
    {
        cout << "Impossible\n";
        return 0;
    }
    for (int i = szo - 1; i >= 0; --i)
        printf("%c", ord[i] + 'a');
    printf("\n");
    return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<stdio.h>
#include<map>
#include<set>
#include<memory.h>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b){
    if (!b)
        return a;
    return gcd(b, a%b);
}
ll lcm(ll a, ll b){
    return b / gcd(a, b)*a;
}
#define FOR(I,N) for(int(i)=0;i<int(N);++i)
#define FORK(I,N,K) for(int(i)=0;i<int(N);i+=int(K))
int n;
string x[100];
bool l[400][400];
vector<int>v[400];
int in[500];
int main(){
    cin >> n;
    FOR(0, n)
        cin >> x[i];
    FOR(0, n - 1){
        int a = x[i].size();
        int b = x[i + 1].size();
        int j = 0;
        int ok = 0;
        for (; j < min(a, b); ++j){
            if (x[i][j] == x[i + 1][j])
                continue;
            else if (l[x[i][j]][x[i + 1][j]]){
                ok = 1;
                break;
            }
            else if (l[x[i + 1][j]][x[i][j]]){
                ok = -1;
                break;
            }
            else{
                l[x[i][j]][x[i + 1][j]] = 1;
                v[x[i][j]].push_back(x[i + 1][j]);
                in[x[i + 1][j]]++;
                ok = 1;
                break;
            }
        }
        if (ok == -1 || (j == b && j != a)){
            puts("Impossible");
            return 0;
        }
    }
    vector<char>s;
    queue<char>q;
    for (int i = 'a'; i <= 'z'; ++i){
        if (!in[i]){
            q.push(i);
            s.push_back(i);
        }
    }
    while (!q.empty()){
        char d = q.front();
        q.pop();
        FOR(0, v[d].size()){
            int nxt = v[d][i];
            --in[nxt];
            if (!in[nxt]){
                s.push_back(nxt);
                q.push(nxt);
            }
        }
    }
    for (int j = 'a'; j <= 'z'; ++j){
        bool f = 0;
        FOR(0, s.size())
        if (s[i] == j){
            f = 1;
            break;
        }
        if (!f)
            s.push_back(j);
    }
    FOR(0, s.size())
        cout << s[i];
    cin >> n;
}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<stdio.h>
#include<map>
#include<set>
#include<memory.h>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b){
    if (!b)
        return a;
    return gcd(b, a%b);
}
ll lcm(ll a, ll b){
    return b / gcd(a, b)*a;
}
#define FOR(I,N) for(int(i)=0;i<int(N);++i)
#define FORK(I,N,K) for(int(i)=0;i<int(N);i+=int(K))
int n;
string x[100];
bool l[400][400];
vector<int>v[400];
int in[500];
int main(){
    cin >> n;
    FOR(0, n)
        cin >> x[i];
    FOR(0, n - 1){
        int a = x[i].size();
        int b = x[i + 1].size();
        int j = 0;
        int ok = 0;
        for (; j < min(a, b); ++j){
            if (x[i][j] == x[i + 1][j])
                continue;
            else if (l[x[i][j]][x[i + 1][j]]){
                ok = 1;
                break;
            }
            else if (l[x[i + 1][j]][x[i][j]]){
                ok = -1;
                break;
            }
            else{
                l[x[i][j]][x[i + 1][j]] = 1;
                v[x[i][j]].push_back(x[i + 1][j]);
                in[x[i + 1][j]]++;
                ok = 1;
                break;
            }
        }
        if (ok == -1 || (j == a && j != b)){
            puts("Impossible");
            return 0;
        }
    }
    vector<char>s;
    queue<char>q;
    for (int i = 'a'; i <= 'z'; ++i){
        if (!in[i]){
            q.push(i);
            s.push_back(i);
        }
    }
    while (!q.empty()){
        char d = q.front();
        q.pop();
        FOR(0, v[d].size()){
            int nxt = v[d][i];
            --in[nxt];
            if (!in[nxt]){
                s.push_back(nxt);
                q.push(nxt);
            }
        }
    }
    for (int j = 'a'; j <= 'z'; ++j){
        bool f = 0;
        FOR(0, s.size())
        if (s[i] == j){
            f = 1;
            break;
        }
        if (!f)
            s.push_back(j);
    }
    FOR(0, s.size())
        cout << s[i];
    cin >> n;
}


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<stdio.h>
#include<map>
#include<set>
#include<memory.h>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b){
    if (!b)
        return a;
    return gcd(b, a%b);
}
ll lcm(ll a, ll b){
    return b / gcd(a, b)*a;
}
#define FOR(I,N) for(int(i)=0;i<int(N);++i)
#define FORK(I,N,K) for(int(i)=0;i<int(N);i+=int(K))
int n;
string x[100];
bool l[400][400];
vector<int>v[400];
int in[500];
int main(){
    cin >> n;
    FOR(0, n)
        cin >> x[i];
    FOR(0, n - 1){
        int a = x[i].size();
        int b = x[i + 1].size();
        int j = 0;
        int ok = 0;
        for (; j < min(a, b); ++j){
            if (x[i][j] == x[i + 1][j])
                continue;
            v[x[i][j]].push_back(x[i + 1][j]);
            ++in[x[i + 1][j]];
            break;
        }
        if ((j == b)){
            puts("Impossible");
            return 0;
        }
    }
    vector<char>s;
    queue<char>q;
    for (int i = 'a'; i <= 'z'; ++i){
        if (!in[i]){
            q.push(i);
            s.push_back(i);
        }
    }
    while (!q.empty()){
        char d = q.front();
        q.pop();
        FOR(0, v[d].size()){
            int nxt = v[d][i];
            --in[nxt];
            if (!in[nxt]){
                s.push_back(nxt);
                q.push(nxt);
            }
        }
    }
    if (s.size() != 26)
        cout << "Impossible";
    else
    FOR(0, s.size())
        cout << s[i];
    cin >> n;
}


#pragma comment(linker,"/STACK:102400000,102400000")
#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
#include<string>
#include<stack>
#include<cstdio>
#include<queue>
#include<map>
#include<set>
#include<time.h>
#include<cstdlib>
#include<list>
#include<cstring>
#include<iterator>
#include<fstream>
#include<sstream>
using namespace std;
#define inf 1888888888
#define PI acos(-1.0)
#define FIR 1,n,1
#define LEFT l,mid,dq<<1
#define RIGHT mid+1,r,dq<<1|1
#define L (dq<<1)
#define R (dq<<1|1)
#define DQ l,r,dq
#define MID (l+r)>>1
#define LL __int64
template<class _T> inline _T low(_T n){return n&(-n);}
template<class _T> inline void swapp(_T &x,_T &y){_T t;t=x,x=y,y=t;}
template<class _T> inline _T minn(_T i,_T j){return i>j?j:i;}
template<class _T> inline _T maxx(_T i,_T j){return i>j?i:j;}
template<class _T> inline _T gcd(_T b,_T c){return b&&c?(c?gcd(c,b%c):b):b|c;}
template<class _T> inline _T abss(_T b){return b>0?b:-b;}
char c[105][105];
vector<int> a[26];
int cd[26]={0};
int res[26],l=0;
bool ins[26]={0};
bool A(){
	int i;
	for(i=0;i<26;i++)
		if(ins[i]==false&&cd[i]==0)
			return true;
	return false;
}
int main(){
	int n,i,j;
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%s",c[i]);
	}
	for(i=0;i<n-1;i++){
		for(j=0;j<strlen(c[i])&&j<strlen(c[i+1]);j++)
			if(c[i][j]!=c[i+1][j]){
				a[c[i][j]-'a'].push_back(c[i+1][j]-'a');
				cd[c[i+1][j]-'a']++;
				break;
			}
			if(j==strlen(c[i+1])&&j!=strlen(c[i])){printf("Impossible\n");return 0;}
	}
	while(A()){
		for(i=0;i<26;i++)
			if(ins[i]==false&&cd[i]==0){
				res[l++]=i;
				ins[i]=true;
				for(j=0;j<a[i].size();j++){
					cd[a[i][j]]--;
				}
			}
	}
	if(l<26)
		printf("Impossible\n");
	else{
		for(i=0;i<l;i++)
			printf("%c",res[i]+'a');
		printf("\n");
	}
	return 0;
}


#pragma comment(linker,"/STACK:102400000,102400000")
#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
#include<string>
#include<stack>
#include<cstdio>
#include<queue>
#include<map>
#include<set>
#include<time.h>
#include<cstdlib>
#include<list>
#include<cstring>
#include<iterator>
#include<fstream>
#include<sstream>
using namespace std;
#define inf 1888888888
#define PI acos(-1.0)
#define FIR 1,n,1
#define LEFT l,mid,dq<<1
#define RIGHT mid+1,r,dq<<1|1
#define L (dq<<1)
#define R (dq<<1|1)
#define DQ l,r,dq
#define MID (l+r)>>1
#define LL __int64
template<class _T> inline _T low(_T n){return n&(-n);}
template<class _T> inline void swapp(_T &x,_T &y){_T t;t=x,x=y,y=t;}
template<class _T> inline _T minn(_T i,_T j){return i>j?j:i;}
template<class _T> inline _T maxx(_T i,_T j){return i>j?i:j;}
template<class _T> inline _T gcd(_T b,_T c){return b&&c?(c?gcd(c,b%c):b):b|c;}
template<class _T> inline _T abss(_T b){return b>0?b:-b;}
char c[105][105];
vector<int> a[26];
int cd[26]={0};
int res[26],l=0;
bool ins[26]={0};
bool A(){
	int i;
	for(i=0;i<26;i++)
		if(ins[i]==false&&cd[i]==0)
			return true;
	return false;
}
int main(){
	int n,i,j;
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%s",c[i]);
	}
	for(i=0;i<n-1;i++){
		for(j=0;j<strlen(c[i])&&j<strlen(c[i+1]);j++)
			if(c[i][j]!=c[i+1][j]){
				a[c[i][j]-'a'].push_back(c[i+1][j]-'a');
				cd[c[i+1][j]-'a']++;
				break;
			}
	}
	while(A()){
		for(i=0;i<26;i++)
			if(ins[i]==false&&cd[i]==0){
				res[l++]=i;
				ins[i]=true;
				for(j=0;j<a[i].size();j++){
					cd[a[i][j]]--;
				}
			}
	}
	if(l<26)
		printf("Impossible\n");
	else{
		for(i=0;i<l;i++)
			printf("%c",res[i]+'a');
		printf("\n");
	}
	return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <iostream>
#include <cmath>
#include <bitset>

using namespace std;

char s[105][105];

vector<int> g[200];
bool u[200];
vector<int> ts;
bool al[200];
int idx[200];
char ans[200];

void dfs(int v) {
    u[v] = 1;
    for (int i = 0; i < g[v].size(); i++) {
        if (!u[g[v][i]]) {
            dfs(g[v][i]);
        }
    }
    ts.push_back(v);
}

int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
        scanf("%s", s[i]);

    for (int i = 0; i + 1 < n; i++)
    {
        int n1 = strlen(s[i]), n2 = strlen(s[i + 1]);
        int id = 0;
        while (id < n1 && id < n2 && s[i][id] == s[i + 1][id])
            id++;
        if (id == n2) {
            printf("Impossible\n");
            return 0;
        }
        if (id < n1) {
            char c1 = s[i][id], c2 = s[i + 1][id];
            g[c1].push_back(c2);
        }
    }
    for (int i = 'a'; i <= 'z'; i++) {
        if (!u[i])
            dfs(i);
    }
    int sz = 0;
    for (int i = ts.size() - 1; i >= 0; i--) {
        al[ts[i]] = 1;
        idx[ts[i]] = sz;
        ans[sz++] = ts[i];
    }
    for (int i = 'a'; i <= 'z'; i++) {
        if (!al[i])
            idx[i] = sz, ans[sz++] = i;
    }
    for (int i = 0; i + 1 < n; i++) {
        int n1 = strlen(s[i]), n2 = strlen(s[i + 1]);
        int id = 0;
        while (id < n1 && id < n2 && idx[s[i][id]]== idx[s[i + 1][id]])
            id++;
        if (id == n2) {
            printf("Impossible\n");
            return 0;
        }
        if (id < n1) {
            char c1 = s[i][id], c2 = s[i + 1][id];
            if (idx[c1] > idx[c2]) {
                printf("Impossible\n");
                return 0;
            }
        }
    }
    printf("%s\n", ans);

    return 0;
}


#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<vector>
using namespace std;

#define inf 0x3f3f3f3f
#define eps 1e-9
#define mod 1000000007
#define FOR(i,s,t) for(int i = s; i < t; ++i )
#define REP(i,s,t) for( int i = s; i <= t; ++i )
#define LL long long
#define ULL unsigned long long
#define pii pair<int,int>
#define MP make_pair
#define lson id << 1 , l , m
#define rson id << 1 | 1 , m + 1 , r
#define maxn ( 100 + 10 )
#define maxe ( 500+10 )

char s[111][111];
char ans[111];

int fst[maxn], nxt[maxe], vv[maxe], ec;

void init () {
	memset( fst, 0, sizeof( fst ) ) ;
	ec = 1;
}

void add ( int u, int v ) {
	vv[ec] = v;
	nxt[ec] = fst[u];
	fst[u] = ec++;
}

int vis[maxn], in[maxn];
bool dfs ( int u ) {
	vis[u] = -1;
	for( int i = fst[u]; i ; i = nxt[i] ) {
		int v = vv[i];
		++in[v];
		if( vis[v] == -1) return false;
		if( vis[v] == 1 ) continue;
		if( !dfs( v ) ) return false;
	}
	vis[u] = 1;
	return true;
}

void get_ans () {
	int cnt = 0;
	while( cnt < 26 ) {
		for( int i = 0; i < 26; ++i )
			if( in[i] == 0 ) {
				ans[cnt++] = i + 'a';
				in[i] = -1;
				for( int j = fst[i]; j; j = nxt[j] )
					--in[vv[j]];
			}
	}
	printf("%s\n", ans );
}

int main () {
	int n;
	while( ~scanf("%d", &n ) ) {
		for( int i = 0; i < n; ++i )
			scanf("%s", s[i] );
		int l , r;
		init();
		bool flag = 0;
		for( int i = 1; i < n; ++i ) {
			int len1 = strlen( s[i-1] ), len2 = strlen( s[i] ) ;
			l = r = 0;
			while( l < len1 && r < len2 ) {
				if( s[i-1][l] != s[i][r] ) break;
				++l, ++r;
			}
			//printf("%d %d\n", s[i-1][l]-'a', s[i][r]-'a' );
			if( l < len1 && r < len2 ) add( s[i-1][l] - 'a', s[i][r] - 'a' );
			if( l == len1 || r == len2 )
				if( len1 > len2 ) flag = 1;
		}
		memset( vis, 0, sizeof( vis ) );
		memset( in , 0, sizeof( in ) );
		for( int i = 0; i < 26; ++i )
			if( !vis[i] ) if( !dfs ( i ) ) flag = 1;
		//cout<<flag<<endl;
		if( flag ){
			printf("Impossible\n" );
			continue;
		}
		get_ans();
	}
}


// In the Name of Allah
// AD13
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

typedef long long ll;		//	typedef unsigned long long  ull;
typedef pair <int, int> pii;//	typedef pair <double, double> pdd;
typedef vector <int> VI;
#define MP make_pair
const int INF = 2147483647, MOD = 1000*1000*1000 + 7;
const double eps = 1e-8; // (eps < 1e-15) is the fact (1e-14)
#define For(i, n) for (int i = 0; i < (n); i++)
#define For1(i, n) for (int i = 1; i <= (n); i++)
//#define debug(x) { cerr << #x << " = _" << (x) << "_" << endl; }
void Error(string err) { cout << err; cerr << "_" << err << "_"; exit(0); }
int gcd(int a, int b) { return (b==0)? a: gcd(b, a%b); }
/*-------------------------------------------------------------------------------------*/

int isLess[300][300];
bool used[300];
string ans = "";

string str[1000];

string differ (string a, string b){
	for (int i = 0; ;i++) {
		if (i != a.length() && i == b.length()) return "";
		if (i == a.length() && i != b.length()) return "1";
		if (a[i] == b[i]) continue;
		string ret = "";
		ret += a[i];
		ret += b[i];
		return ret;
	}
}
/*_____________________________________________________________________________________*/

int main() {
	int n;
	cin >> n;
	bool possible = true;
	For (i, n) {
		if (!possible) break;
		cin >> str[i];
		for (int j = 0; j < i; j++) {
			string dif = differ (str[j], str[i]);
			if (dif.length() < 1) {
				possible = false;
				break;
			}
			else if(dif.length() == 2) {
				char a = dif[0], b = dif[1];
				if (isLess[a][b] == -1) {
					possible = false;
					break;
				}
				else { //if (isLess[a][b] == 0) {
					isLess[a][b] = 1;
					isLess[b][a] = -1;
				}
			}
		}
	}

	if (possible) {
		while (ans.length() != 26) {
			char sel = 0;
			for (char ch = 'a'; ch <= 'z'; ch++) {
				if (sel != 0) break;
				if (used[ch]) continue;
				sel = ch;
				for (char b = 'a'; b <= 'z'; b++) {
					if (used[b]) continue;
					if (isLess[b][ch] == 1){
						sel = 0;
						break;
					}
				}
			}
			if (sel == 0) {
				possible = false;
				break;
			}
			ans += sel;
			used[sel] = true;
		}
	}
	if (possible) cout << ans << endl;
	else cout << "Impossible\n";

	return 0;
}
/*

*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <utility>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;

#define MAXN 300

int n;
string s[MAXN + 3];

int ccnt;
char into[MAXN + 3];
int onto[MAXN + 3];

void add(char u)
{
    if (onto[u] == 0) {
        ccnt++;
        into[ccnt] = u;
        onto[u] = ccnt;
    }
}

vector<int> g[MAXN + 3];
char used[MAXN + 3];

bool cycle(int v)
{
    used[v] = 2;
    for (int i = 0; i < g[v].size(); i++) {
        int to = g[v][i];
        if (used[to] == 2) {
            return true;
        } else if (used[to] == 0) {
            if (cycle(to)) {
                return true;
            }
        }
    }
    used[v] = 1;
    return false;
}

vector<int> p;
bool tused[MAXN + 3];
void topsort(int v)
{
    if (tused[v]) {
        return;
    }

    tused[v] = 1;
    for (int i = 0; i < g[v].size(); i++) {
        int to = g[v][i];
        if (!tused[to]) {
            topsort(to);
        }
    }

    p.push_back(v);
}

void comp(const string & a, const string & b, char & c1, char & c2)
{
    int i = 0;
    while (true) {
        if (i == a.size() || i == b.size()) {
            c1 = c2 = 0;
            break;
        }
        if (a[i] == b[i]) {
            i++;
            continue;
        }

        c1 = a[i];
        c2 = b[i];
        break;
    }
}

int main(int argc, char * argv[])
{
#ifdef Home
    freopen("inp.txt", "rb", stdin);
#endif

    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> s[i];
    }

    for (int i = 0; i < n - 1; i++) {
        char a, b;
        comp(s[i], s[i + 1], a, b);
        if (a == b || b == 0) {
            continue;
        }
        add(a);
        add(b);
        g[onto[a]].push_back(onto[b]);
    }

    bool cycled = false;
    for (int i = 1; i <= ccnt; i++) {
        if (cycle(i)) {
            cycled = true;
            break;
        }
    }

    if (cycled) {
        cout << "Impossible" << endl;
    } else {
        for (char c = 'a'; c < 'z'; c++) {
            add(c);
            add(c + 1);
            if (g[onto[c]].size() == 0) {
                g[onto[c]].push_back(onto[c + 1]);
            }
        }
        for (int i = 1; i <= ccnt; i++) {
            if (!tused[i]) {
                topsort(i);
            }
        }
        reverse(p.begin(), p.end());
        for (int i = 0; i < p.size(); i++) {
            cout << into[p[i]];
        }
        cout << endl;
    }

    return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <utility>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;

#define MAXN 300

int n;
string s[MAXN + 3];

int ccnt;
char into[MAXN + 3];
int onto[MAXN + 3];

void add(char u)
{
    if (onto[u] == 0) {
        ccnt++;
        into[ccnt] = u;
        onto[u] = ccnt;
    }
}

vector<int> g[MAXN + 3];
char used[MAXN + 3];

bool cycle(int v)
{
    used[v] = 2;
    for (int i = 0; i < g[v].size(); i++) {
        int to = g[v][i];
        if (used[to] == 2) {
            return true;
        } else if (used[to] == 0) {
            if (cycle(to)) {
                return true;
            }
        }
    }
    used[v] = 1;
    return false;
}

vector<int> p;
bool tused[MAXN + 3];
void topsort(int v)
{
    if (tused[v]) {
        return;
    }

    tused[v] = 1;
    for (int i = 0; i < g[v].size(); i++) {
        int to = g[v][i];
        if (!tused[to]) {
            topsort(to);
        }
    }

    p.push_back(v);
}

void comp(const string & a, const string & b, char & c1, char & c2)
{
    int i = 0;
    while (true) {
        if (i == a.size() || i == b.size()) {
            c1 = c2 = 0;
            break;
        }
        if (a[i] == b[i]) {
            i++;
            continue;
        }

        c1 = a[i];
        c2 = b[i];
        break;
    }
}

int main(int argc, char * argv[])
{
#ifdef Home
    freopen("inp.txt", "rb", stdin);
#endif

    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> s[i];
    }

    for (int i = 0; i < n - 1; i++) {
        char a, b;
        comp(s[i], s[i + 1], a, b);
        add(a);
        add(b);
        g[onto[a]].push_back(onto[b]);
    }

    bool cycled = false;
    for (int i = 1; i <= ccnt; i++) {
        if (cycle(i)) {
            cycled = true;
            break;
        }
    }

    if (cycled) {
        cout << "Impossible" << endl;
    } else {
        for (char c = 'a'; c < 'z'; c++) {
            add(c);
            add(c + 1);
            if (g[onto[c]].size() == 0) {
                g[onto[c]].push_back(onto[c + 1]);
            }
        }
        for (int i = 1; i <= ccnt; i++) {
            if (!tused[i]) {
                topsort(i);
            }
        }
        reverse(p.begin(), p.end());
        for (int i = 0; i < p.size(); i++) {
            cout << into[p[i]];
        }
        cout << endl;
    }

    return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <utility>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;

#define MAXN 300

int n;
string s[MAXN + 3];

int ccnt;
char into[MAXN + 3];
int onto[MAXN + 3];

void add(char u)
{
    if (onto[u] == 0) {
        ccnt++;
        into[ccnt] = u;
        onto[u] = ccnt;
    }
}

vector<int> g[MAXN + 3];
char used[MAXN + 3];

bool cycle(int v)
{
    used[v] = 2;
    for (int i = 0; i < g[v].size(); i++) {
        int to = g[v][i];
        if (used[to] == 2) {
            return true;
        } else if (used[to] == 0) {
            if (cycle(to)) {
                return true;
            }
        }
    }
    used[v] = 1;
    return false;
}

vector<int> p;
bool tused[MAXN + 3];
void topsort(int v)
{
    if (tused[v]) {
        return;
    }

    tused[v] = 1;
    for (int i = 0; i < g[v].size(); i++) {
        int to = g[v][i];
        if (!tused[to]) {
            topsort(to);
        }
    }

    p.push_back(v);
}

void comp(const string & a, const string & b, char & c1, char & c2)
{
    int i = 0;
    while (true) {
        if (i == a.size() || i == b.size()) {
            c1 = c2 = 0;
            break;
        }
        if (a[i] == b[i]) {
            i++;
            continue;
        }

        c1 = a[i];
        c2 = b[i];
        break;
    }
}

int main(int argc, char * argv[])
{
#ifdef Home
    freopen("inp.txt", "rb", stdin);
#endif

    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> s[i];
    }

    for (int i = 0; i < n - 1; i++) {
        char a, b;
        comp(s[i], s[i + 1], a, b);
        if (a == b && b == 0) {
            continue;
        }
        add(a);
        add(b);
        g[onto[a]].push_back(onto[b]);
    }

    bool empty = true;
    for (int i = 1; i <= ccnt; i++) {
        if (g[i].size() > 0) {
            empty = false;
            break;
        }
    }

    bool cycled = false;
    for (int i = 1; i <= ccnt; i++) {
        if (cycle(i)) {
            cycled = true;
            break;
        }
    }

    if (cycled || empty) {
        cout << "Impossible" << endl;
    } else {
        for (char c = 'a'; c < 'z'; c++) {
            add(c);
            add(c + 1);
            if (g[onto[c]].size() == 0) {
                g[onto[c]].push_back(onto[c + 1]);
            }
        }
        for (int i = 1; i <= ccnt; i++) {
            if (!tused[i]) {
                topsort(i);
            }
        }
        reverse(p.begin(), p.end());
        for (int i = 0; i < p.size(); i++) {
            cout << into[p[i]];
        }
        cout << endl;
    }

    return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <utility>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;

#define MAXN 300

int n;
string s[MAXN + 3];

int ccnt;
char into[MAXN + 3];
int onto[MAXN + 3];

void add(char u)
{
    if (onto[u] == 0) {
        ccnt++;
        into[ccnt] = u;
        onto[u] = ccnt;
    }
}

vector<int> g[MAXN + 3];
char used[MAXN + 3];

bool cycle(int v)
{
    used[v] = 2;
    for (int i = 0; i < g[v].size(); i++) {
        int to = g[v][i];
        if (used[to] == 2) {
            return true;
        } else if (used[to] == 0) {
            if (cycle(to)) {
                return true;
            }
        }
    }
    used[v] = 1;
    return false;
}

vector<int> p;
bool tused[MAXN + 3];
void topsort(int v)
{
    if (tused[v]) {
        return;
    }

    tused[v] = 1;
    for (int i = 0; i < g[v].size(); i++) {
        int to = g[v][i];
        if (!tused[to]) {
            topsort(to);
        }
    }

    p.push_back(v);
}

void comp(const string & a, const string & b, char & c1, char & c2)
{
    int i = 0;
    while (true) {
        if (i == a.size() || i == b.size()) {
            c1 = c2 = 0;
            break;
        }
        if (a[i] == b[i]) {
            i++;
            continue;
        }

        c1 = a[i];
        c2 = b[i];
        break;
    }
}

int main(int argc, char * argv[])
{
#ifdef Home
    freopen("inp.txt", "rb", stdin);
#endif

    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> s[i];
    }

    for (int i = 0; i < n - 1; i++) {
        char a, b;
        comp(s[i], s[i + 1], a, b);
        if (a == b && b == 0) {
            continue;
        }
        add(a);
        add(b);
        g[onto[a]].push_back(onto[b]);
    }

    bool cycled = false;
    for (int i = 1; i <= ccnt; i++) {
        if (cycle(i)) {
            cycled = true;
            break;
        }
    }

    if (cycled) {
        cout << "Impossible" << endl;
    } else {
        for (char c = 'a'; c < 'z'; c++) {
            add(c);
            add(c + 1);
            if (g[onto[c]].size() == 0) {
                g[onto[c]].push_back(onto[c + 1]);
            }
        }
        for (int i = 1; i <= ccnt; i++) {
            if (!tused[i]) {
                topsort(i);
            }
        }
        reverse(p.begin(), p.end());
        for (int i = 0; i < p.size(); i++) {
            cout << into[p[i]];
        }
        cout << endl;
    }

    return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <utility>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;

#define MAXN 300

int n;
string s[MAXN + 3];

int ccnt;
char into[MAXN + 3];
int onto[MAXN + 3];

void add(char u)
{
    if (onto[u] == 0) {
        ccnt++;
        into[ccnt] = u;
        onto[u] = ccnt;
    }
}

vector<int> g[MAXN + 3];
char used[MAXN + 3];

bool cycle(int v)
{
    used[v] = 2;
    for (int i = 0; i < g[v].size(); i++) {
        int to = g[v][i];
        if (used[to] == 2) {
            return true;
        } else if (used[to] == 0) {
            if (cycle(to)) {
                return true;
            }
        }
    }
    used[v] = 1;
    return false;
}

vector<int> p;
bool tused[MAXN + 3];
void topsort(int v)
{
    if (tused[v]) {
        return;
    }

    tused[v] = 1;
    for (int i = 0; i < g[v].size(); i++) {
        int to = g[v][i];
        if (!tused[to]) {
            topsort(to);
        }
    }

    p.push_back(v);
}

void comp(const string & a, const string & b, char & c1, char & c2)
{
    int i = 0;
    while (true) {
        if (i == a.size() || i == b.size()) {
            if (b.size() < a.size()) {
                c1 = c2 = -1;
            } else {
                c1 = c2 = 0;
            }
            break;
        }
        if (a[i] == b[i]) {
            i++;
            continue;
        }

        c1 = a[i];
        c2 = b[i];
        break;
    }
}

int main(int argc, char * argv[])
{
#ifdef Home
    freopen("inp.txt", "rb", stdin);
#endif

    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> s[i];
    }

    bool impossible = false;
    for (int i = 0; i < n - 1; i++) {
        char a, b;
        comp(s[i], s[i + 1], a, b);
        if (a == b && b == 0) {
            continue;
        } else if (a == -1 && b == -1) {
            impossible = true;
            break;
        }
        add(a);
        add(b);
        g[onto[a]].push_back(onto[b]);
    }

    bool cycled = false;
    for (int i = 1; i <= ccnt; i++) {
        if (cycle(i)) {
            cycled = true;
            break;
        }
    }

    if (cycled || impossible) {
        cout << "Impossible" << endl;
    } else {
        for (char c = 'a'; c < 'z'; c++) {
            add(c);
        }
        for (int i = 1; i <= ccnt; i++) {
            if (!tused[i]) {
                topsort(i);
            }
        }
        reverse(p.begin(), p.end());
        for (int i = 0; i < p.size(); i++) {
            cout << into[p[i]];
        }
        cout << endl;
    }

    return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <utility>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;

#define MAXN 300

int n;
string s[MAXN + 3];

int ccnt;
char into[MAXN + 3];
int onto[MAXN + 3];

void add(char u)
{
    if (onto[u] == 0) {
        ccnt++;
        into[ccnt] = u;
        onto[u] = ccnt;
    }
}

vector<int> g[MAXN + 3];
char used[MAXN + 3];

bool cycle(int v)
{
    used[v] = 2;
    for (int i = 0; i < g[v].size(); i++) {
        int to = g[v][i];
        if (used[to] == 2) {
            return true;
        } else if (used[to] == 0) {
            if (cycle(to)) {
                return true;
            }
        }
    }
    used[v] = 1;
    return false;
}

vector<int> p;
bool tused[MAXN + 3];
void topsort(int v)
{
    if (tused[v]) {
        return;
    }

    tused[v] = 1;
    for (int i = 0; i < g[v].size(); i++) {
        int to = g[v][i];
        if (!tused[to]) {
            topsort(to);
        }
    }

    p.push_back(v);
}

void comp(const string & a, const string & b, char & c1, char & c2)
{
    int i = 0;
    while (true) {
        if (i == a.size() || i == b.size()) {
            if (b.size() < a.size()) {
                c1 = c2 = -1;
            } else {
                c1 = c2 = 0;
            }
            break;
        }
        if (a[i] == b[i]) {
            i++;
            continue;
        }

        c1 = a[i];
        c2 = b[i];
        break;
    }
}

int main(int argc, char * argv[])
{
#ifdef Home
    freopen("inp.txt", "rb", stdin);
#endif

    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> s[i];
    }

    bool impossible = false;
    for (int i = 0; i < n - 1; i++) {
        char a, b;
        comp(s[i], s[i + 1], a, b);
        if (a == b && b == 0) {
            continue;
        } else if (a == -1 && b == -1) {
            impossible = true;
            break;
        }
        add(a);
        add(b);
        g[onto[a]].push_back(onto[b]);
    }

    bool cycled = false;
    for (int i = 1; i <= ccnt; i++) {
        if (cycle(i)) {
            cycled = true;
            break;
        }
    }

    if (cycled || impossible) {
        cout << "Impossible" << endl;
    } else {
        for (char c = 'z'; c >= 'a'; c--) {
            add(c);
        }
        for (int i = 1; i <= ccnt; i++) {
            if (!tused[i]) {
                topsort(i);
            }
        }
        reverse(p.begin(), p.end());
        for (int i = 0; i < p.size(); i++) {
            cout << into[p[i]];
        }
        cout << endl;
    }

    return 0;
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collection;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.Queue;
import java.util.LinkedList;
import java.io.InputStream;
import java.util.ArrayList;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author pandusonu
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskE solver = new TaskE();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskE {
        public int[] val;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.readInt();
            int[][] edge = new int[n - 1][2];
            Graph g = new Graph(n, n - 1);
            for (int i = 0; i < n - 1; i++) {
                int u = in.readInt() - 1;
                int v = in.readInt() - 1;
                g.addEdge(u, v);
                edge[i][0] = u;
                edge[i][1] = v;
            }
            g.preprocessLCA();
            int[] vals = new int[n];
            int k = in.readInt();
            for (int i = 0; i < k; i++) {
                int u = in.readInt() - 1;
                int v = in.readInt() - 1;
                int lca = g.findLCA(u, v);
                vals[u]++;
                vals[v]++;
                vals[lca] -= 2;
            }
            val = new int[n];
            dfsCal(0, g.adlist, new boolean[n], vals);
            for (int i = 0; i < n - 1; i++) {
                if (g.infoMatrix[1][edge[i][0]] > g.infoMatrix[1][edge[i][1]]) {
                    out.print(val[edge[i][0]] + " ");
                } else out.print(val[edge[i][1]] + " ");
            }
            out.println();
        }

        public void dfsCal(int curr, ArrayList<Integer>[] adlist, boolean[] visited, int[] vals) {
            visited[curr] = true;
            val[curr] += vals[curr];
            for (int x : adlist[curr]) {
                if (!visited[x]) {
                    dfsCal(x, adlist, visited, vals);
                    val[curr] += val[x];
                }
            }
        }

    }

    static class Graph {
        public int nodes;
        public int edgeCount;
        public ArrayList<Integer>[] adlist;
        public int[][] preProcessLCA;
        public int[][] infoMatrix;

        public Graph(int n, int m) {
            nodes = n;
            edgeCount = m;
            adlist = new ArrayList[n];
            for (int i = 0; i < n; i++) {
                adlist[i] = new ArrayList<Integer>();
            }
        }

        public void addEdge(int u, int v) {
            adlist[u].add(v);
            adlist[v].add(u);
        }

        public void preprocessLCA() {
            bfs(0);
            preProcessLCA = new int[this.nodes][33];
            for (int i = 0; i < this.nodes; i++) {
                for (int j = 0; 1 << j < this.nodes; j++) {
                    preProcessLCA[i][j] = -1;
                }
            }
            for (int i = 0; i < this.nodes; i++) {
                preProcessLCA[i][0] = infoMatrix[0][i];
            }
            for (int i = 1; 1 << i < this.nodes; i++) {
                for (int j = 0; j < this.nodes; j++) {
                    if (preProcessLCA[j][i - 1] != -1)
                        preProcessLCA[j][i] = preProcessLCA[preProcessLCA[j][i - 1]][i - 1];
                }
            }
        }

        public int findLCA(int u, int v) {
            int tmp, log, i;
            if (infoMatrix[1][u] < infoMatrix[1][v]) {
                tmp = u;
                u = v;
                v = tmp;
            }
            for (log = 1; 1 << log <= infoMatrix[1][u]; log++) ;
            log--;
            for (i = log; i >= 0; i--)
                if (infoMatrix[1][u] - (1 << i) >= infoMatrix[1][v])
                    u = preProcessLCA[u][i];
            if (u == v)
                return u;
            for (i = log; i >= 0; i--)
                if (preProcessLCA[u][i] != -1 && preProcessLCA[u][i] != preProcessLCA[v][i]) {
                    u = preProcessLCA[u][i];
                    v = preProcessLCA[v][i];
                }
            return preProcessLCA[u][0];
        }

        public void bfs(int s) {
            Queue<Integer> q = new LinkedList<Integer>();
            q.add(s);
            infoMatrix = new int[2][nodes];
            Arrays.fill(infoMatrix[0], -1);
            infoMatrix[0][s] = s;
            infoMatrix[1][s] = 0;
            while (q.size() != 0) {
                int u = q.poll();
                for (int x : adlist[u]) {
                    if (infoMatrix[0][x] == -1) {
                        q.add(x);
                        infoMatrix[0][x] = u;
                        infoMatrix[1][x] = infoMatrix[1][u] + 1;
                    }
                }
            }
        }

    }

    static class InputReader {
        private final InputStream stream;
        private final byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        private int read() {
            try {
                if (curChar >= numChars) {
                    curChar = 0;
                    numChars = stream.read(buf);
                    if (numChars <= 0)
                        return -1;
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return buf[curChar++];
        }

        public int readInt() {
            return (int) readLong();
        }

        public long readLong() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
                if (c == -1) throw new RuntimeException();
            }
            boolean negative = false;
            if (c == '-') {
                negative = true;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9') throw new InputMismatchException();
                res *= 10;
                res += (c - '0');
                c = read();
            } while (!isSpaceChar(c));
            return negative ? (-res) : (res);
        }

        private boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

    }
}


import java.util.*;
import java.io.*;
public class E192 {
	public static int root, n;
	public static ArrayList<Edge>[] g;
	public static int[] sizes;
	public static int[] label, map, end, jump;
	public static SuperBIT b;
	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		n = Integer.parseInt(br.readLine());
		g = new ArrayList[n];

		for(int i = 0;i<n;i++){
			g[i] = new ArrayList<Edge>();
		}

		for(int i = 0;i<n-1;i++){
			StringTokenizer st = new StringTokenizer(br.readLine(), " ");
			int s = Integer.parseInt(st.nextToken())-1;
			int e = Integer.parseInt(st.nextToken())-1;
			g[s].add(new Edge(e, i));
			g[e].add(new Edge(s, i));
		}

		root = 0;
		ArrayDeque<Integer> qu = new ArrayDeque<Integer>();
		qu.add(root);
		int[] parent = new int[n];
		Arrays.fill(parent, -1);
		parent[root] = root;
		while(qu.size() > 0){
			int cur = qu.poll();
			for(Edge e : g[cur]){
				if(parent[e.e] == -1){
					parent[e.e] = cur;
					qu.add(e.e);
				}
			}
		}
		int[] edges = new int[n-1];
		for(int i = 0;i<n;i++){
			for(Edge e : g[i]){
				if(e.e == parent[i]){
					edges[e.index] = i;
				}
			}
		}
		sizes = new int[n];
		label = new int[n];
		map = new int[n];
		end = new int[n];
		jump = new int[n];
		calcSizes();
		label();
		b = new SuperBIT(n);
		int q = Integer.parseInt(br.readLine());
		for(int i = 0;i<q;i++){
			StringTokenizer st = new StringTokenizer(br.readLine(), " ");
			int s = Integer.parseInt(st.nextToken())-1;
			int e = Integer.parseInt(st.nextToken())-1;
			inc(label[s], label[e]);
		}

		PrintWriter out = new PrintWriter(System.out);

		for(int i = 0;i<n-1;i++){
			int index = label[edges[i]];
			int val = b.query(index)-b.query(index-1);
			out.print(val+" ");
		}
		out.println();
		out.close();

	}

	public static void inc(int n1, int n2){
		int lca = lca(n1, n2);
		incPath(n1, lca, 1);
		incPath(n2, lca, 1);
		//Possibly handle the lca node being counted twice
		incPath(lca, lca, -2);

	}

	public static void incPath(int n1, int n2, int am){
		if(end[n1] == end[n2]){
			b.update(n2, n1, am);
		}
		else{
			b.update(end[n1], n1, am);
			incPath(jump[n1], n2, am);
		}
	}

	public static int lca(int n1, int n2){
		if(end[n1] == end[n2])
			return Math.min(n1, n2);
		if(n1 > n2)
			return lca(jump[n1], n2);
		else
			return lca(n1, jump[n2]);
	}

	public static void label(){
		Stack<Integer> st = new Stack<Integer>();
		st.push(root);
		st.push(root);
		int count = 0;
		while(st.size() > 0){
			int cur = st.pop();
			int parent = st.pop();
			label[cur] = count;
			map[count] = cur;
			count++;
			if(label[cur] == label[parent]+1){
				end[label[cur]] = end[label[parent]];
				jump[label[cur]] = jump[label[parent]];
			}
			else{
				end[label[cur]] = label[cur];
				jump[label[cur]] = label[parent];
			}
			int max = -1;
			int maxIndex = -1;
			for(Edge e : g[cur]){
				int i = e.e;
				if(i != parent && sizes[i] > max){
					max = sizes[i];
					maxIndex = i;
				}
			}
			for(Edge e : g[cur]){
				int i = e.e;
				if(i != parent && i != maxIndex){
					st.push(cur);
					st.push(i);
				}
			}

			if(maxIndex != -1){
				st.push(cur);
				st.push(maxIndex);
			}
		}
	}
	public static void calcSizes(){
		Stack<Integer> st = new Stack<Integer>();
		st.push(0);
		st.push(root);
		int rv = 0;
		while(st.size() > 0){
			int pos = st.pop();
			int index = st.pop();
			if(index == 0)
				sizes[pos]++;
			else{
				sizes[pos]+=rv;
				rv = 0;
			}
			if(index != g[pos].size()){
				int next = g[pos].get(index).e;
				st.push(index+1);
				st.push(pos);
				if(sizes[next] == 0){
					st.push(0);
					st.push(next);
				}
			}
			else
				rv = sizes[pos];
		}
	}

	public static class SuperBIT {
		int[] dataMul;
		int[] dataAdd;
		public SuperBIT(int n){
			dataMul = new int[n];
			dataAdd = new int[n];
		}
		public void update(int left, int right, int by) {
		    internalUpdate(left, by, -by * (left - 1));
		    internalUpdate(right, -by, by * right);
		}
		public void internalUpdate(int at, int mul, int add) {
		    while (at < dataMul.length) {
		        dataMul[at] += mul;
		        dataAdd[at] += add;
		        at |= (at + 1);
		    }
		}
		public int query(int at) {
		    int mul = 0;
		    int add = 0;
		    int start = at;
		    while (at >= 0) {
		        mul += dataMul[at];
		        add += dataAdd[at];
		        at = (at & (at + 1)) - 1;
		    }
		    return mul * start + add;
		}
	}
	public static class Edge{
		int e, index;
		public Edge(int b, int c){
			e = b;
			index = c;
		}
	}
}


import java.util.*;
import java.io.*;
public class E192 {
	public static int root, n;
	public static ArrayList<Edge>[] g;
	public static int[] sizes;
	public static int[] label, map, end, jump;
	public static SuperBIT b;
	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		n = Integer.parseInt(br.readLine());
		g = new ArrayList[n];

		for(int i = 0;i<n;i++){
			g[i] = new ArrayList<Edge>();
		}

		for(int i = 0;i<n-1;i++){
			StringTokenizer st = new StringTokenizer(br.readLine(), " ");
			int s = Integer.parseInt(st.nextToken())-1;
			int e = Integer.parseInt(st.nextToken())-1;
			g[s].add(new Edge(e, i));
			g[e].add(new Edge(s, i));
		}

		root = 0;
		ArrayDeque<Integer> qu = new ArrayDeque<Integer>();
		qu.add(root);
		int[] parent = new int[n];
		Arrays.fill(parent, -1);
		parent[root] = root;
		while(qu.size() > 0){
			int cur = qu.poll();
			for(Edge e : g[cur]){
				if(parent[e.e] == -1){
					parent[e.e] = cur;
					qu.add(e.e);
				}
			}
		}
		int[] edges = new int[n-1];
		for(int i = 0;i<n;i++){
			for(Edge e : g[i]){
				if(e.e == parent[i]){
					edges[e.index] = i;
				}
			}
		}
		sizes = new int[n];
		label = new int[n];
		map = new int[n];
		end = new int[n];
		jump = new int[n];
		calcSizes();
		label();
		b = new SuperBIT(n);
		int q = Integer.parseInt(br.readLine());
		for(int i = 0;i<q;i++){
			StringTokenizer st = new StringTokenizer(br.readLine(), " ");
			int s = Integer.parseInt(st.nextToken())-1;
			int e = Integer.parseInt(st.nextToken())-1;
			inc(label[s], label[e]);
		}

		PrintWriter out = new PrintWriter(System.out);

		for(int i = 0;i<n-1;i++){
			int index = label[edges[i]];
			int val = b.query(index)-(index == 0 ? 0 : b.query(index-1));
			out.print(val+" ");
		}
		out.println();
		out.close();

	}

	public static void inc(int n1, int n2){
		int lca = lca(n1, n2);
		incPath(n1, lca, 1);
		incPath(n2, lca, 1);
		//Possibly handle the lca node being counted twice
		incPath(lca, lca, -2);

	}

	public static void incPath(int n1, int n2, int am){
		if(end[n1] == end[n2]){
			b.update(n2, n1, am);
		}
		else{
			b.update(end[n1], n1, am);
			incPath(jump[n1], n2, am);
		}
	}

	public static int lca(int n1, int n2){
		if(end[n1] == end[n2])
			return Math.min(n1, n2);
		if(n1 > n2)
			return lca(jump[n1], n2);
		else
			return lca(n1, jump[n2]);
	}

	public static void label(){
		Stack<Integer> st = new Stack<Integer>();
		st.push(root);
		st.push(root);
		int count = 0;
		while(st.size() > 0){
			int cur = st.pop();
			int parent = st.pop();
			label[cur] = count;
			map[count] = cur;
			count++;
			if(label[cur] == label[parent]+1){
				end[label[cur]] = end[parent];
				jump[label[cur]] = jump[parent];
			}
			else{
				end[label[cur]] = label[cur];
				jump[label[cur]] = label[parent];
			}
			int max = -1;
			int maxIndex = -1;
			for(Edge e : g[cur]){
				int i = e.e;
				if(i != parent && sizes[i] > max){
					max = sizes[i];
					maxIndex = i;
				}
			}
			for(Edge e : g[cur]){
				int i = e.e;
				if(i != parent && i != maxIndex){
					st.push(cur);
					st.push(i);
				}
			}

			if(maxIndex != -1){
				st.push(cur);
				st.push(maxIndex);
			}
		}
	}
	public static void calcSizes(){
		Stack<Integer> st = new Stack<Integer>();
		st.push(0);
		st.push(root);
		int rv = 0;
		while(st.size() > 0){
			int pos = st.pop();
			int index = st.pop();
			if(index == 0)
				sizes[pos]++;
			else{
				sizes[pos]+=rv;
				rv = 0;
			}
			if(index != g[pos].size()){
				int next = g[pos].get(index).e;
				st.push(index+1);
				st.push(pos);
				if(sizes[next] == 0){
					st.push(0);
					st.push(next);
				}
			}
			else
				rv = sizes[pos];
		}
	}

	public static class SuperBIT {
		int[] dataMul;
		int[] dataAdd;
		public SuperBIT(int n){
			dataMul = new int[n];
			dataAdd = new int[n];
		}
		public void update(int left, int right, int by) {
		    internalUpdate(left, by, -by * (left - 1));
		    internalUpdate(right, -by, by * right);
		}
		public void internalUpdate(int at, int mul, int add) {
		    while (at < dataMul.length) {
		        dataMul[at] += mul;
		        dataAdd[at] += add;
		        at |= (at + 1);
		    }
		}
		public int query(int at) {
		    int mul = 0;
		    int add = 0;
		    int start = at;
		    while (at >= 0) {
		        mul += dataMul[at];
		        add += dataAdd[at];
		        at = (at & (at + 1)) - 1;
		    }
		    return mul * start + add;
		}
	}
	public static class Edge{
		int e, index;
		public Edge(int b, int c){
			e = b;
			index = c;
		}
	}
}


import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintWriter;
 import java.io.*;
 import java.util.*;
 import java.util.LinkedList;
 import java.math.*;
 import java.lang.*;
 import java.util.PriorityQueue;
 import static java.lang.Math.*;
 @SuppressWarnings("unchecked")
 public class Solution implements Runnable {
     static class InputReader {
         private InputStream stream;
         private byte[] buf = new byte[1024];
         private int curChar;
         private int numChars;
         private SpaceCharFilter filter;
         private BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

         public InputReader(InputStream stream) {
             this.stream = stream;
         }

         public int read() {
             if (numChars==-1)
                 throw new InputMismatchException();

             if (curChar >= numChars) {
                 curChar = 0;
                 try {
                     numChars = stream.read(buf);
                 }
                 catch (IOException e) {
                     throw new InputMismatchException();
                 }

                 if(numChars <= 0)
                     return -1;
             }
             return buf[curChar++];
         }

         public String nextLine() {
             String str = "";
             try {
                 str = br.readLine();
             }
             catch (IOException e) {
                 e.printStackTrace();
             }
             return str;
         }
         public int nextInt() {
             int c = read();

             while(isSpaceChar(c))
                 c = read();

             int sgn = 1;

             if (c == '-') {
                 sgn = -1;
                 c = read();
             }

             int res = 0;
             do {
                 if(c<'0'||c>'9')
                     throw new InputMismatchException();
                 res *= 10;
                 res += c - '0';
                 c = read();
             }
             while (!isSpaceChar(c));

             return res * sgn;
         }

         public long nextLong() {
             int c = read();
             while (isSpaceChar(c))
                 c = read();
             int sgn = 1;
             if (c == '-') {
                 sgn = -1;
                 c = read();
             }
             long res = 0;

             do {
                 if (c < '0' || c > '9')
                     throw new InputMismatchException();
                 res *= 10;
                 res += c - '0';
                 c = read();
             }
             while (!isSpaceChar(c));
                 return res * sgn;
         }

         public double nextDouble() {
             int c = read();
             while (isSpaceChar(c))
                 c = read();
             int sgn = 1;
             if (c == '-') {
                 sgn = -1;
                 c = read();
             }
             double res = 0;
             while (!isSpaceChar(c) && c != '.') {
                 if (c == 'e' || c == 'E')
                     return res * Math.pow(10, nextInt());
                 if (c < '0' || c > '9')
                     throw new InputMismatchException();
                 res *= 10;
                 res += c - '0';
                 c = read();
             }
             if (c == '.') {
                 c = read();
                 double m = 1;
                 while (!isSpaceChar(c)) {
                     if (c == 'e' || c == 'E')
                         return res * Math.pow(10, nextInt());
                     if (c < '0' || c > '9')
                         throw new InputMismatchException();
                     m /= 10;
                     res += (c - '0') * m;
                     c = read();
                 }
             }
             return res * sgn;
         }

         public String readString() {
             int c = read();
             while (isSpaceChar(c))
                 c = read();
             StringBuilder res = new StringBuilder();
             do {
                 res.appendCodePoint(c);
                 c = read();
             }
             while (!isSpaceChar(c));

             return res.toString();
         }

         public boolean isSpaceChar(int c) {
             if (filter != null)
                 return filter.isSpaceChar(c);
             return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
         }

         public String next() {
             return readString();
         }

         public interface SpaceCharFilter {
             public boolean isSpaceChar(int ch);
         }
     }
     public static long min(long a,long b)
     {
         if(a>b)
         {
             return b;
         }
         return a;
     }
     public static int min(int a,int b)
     {
         if(a>b)
         {
             return b;
         }
         return a;
     }
     public static long max(long a,long b)
     {
         if(a>b)
         {
             return a;
         }
         return b;
     }
     public static int max(int a,int b)
     {
         if(a>b)
         {
             return a;
         }
         return b;
     }
     static class pair implements Comparable<pair>
     {
       int x;
       int y;
       pair(int x,int y)
       {
         this.x = x;
         this.y = y;
       }
       public int compareTo(pair p)
       {
         return this.x-p.x;
       }
     }
     public static int gcd(int a,int b)
     {
         if(a==0)
         return b;
         if(b==0)
         return a;
         while((a%=b)!=0&&(b%=a)!=0);
         return a^b;
     }
     public static int mod(int a)
     {
       if(a>0)
         return a;
       return -a;
     }
     static int mod = (int)1e9+7;
     public static long expo(long exp,long pow)
     {
       long ans = 1;
       while(pow!=0)
       {
         if((pow&1)==1)
         {
           ans = (ans*exp)%mod;
         }
         exp = (exp*exp)%mod;
         pow = pow>>1;
       }
       return ans;
     }
     static int max = (int)1e5;
     public static long fact(int num)
     {
         if(num==0)
         {
           return 1;
         }
         return (fact(num-1)*num)%mod;
     }
     static int[] sieve;
     public static void sieve()
     {
       sieve = new int[max];
       for(int i=1;i<max;i++)
       {
         sieve[i] = i;
       }
       for(int i=2;i<max;i++)
       {
         if(sieve[i]==i)
         {
           for(int j=i*2;j<max;j+=i)
           {
             if(sieve[j]==j)
             {
               sieve[j] = i;
             }
           }
         }
       }
     }
     public static int lcm(int a,int b)
     {
       return a*b/gcd(a,b);
     }
     public static int bsearch(pair[] p,int x)
     {
       int l = 0;
       int r = p.length-1;
       while(r>l)
       {
         int mid = (l+r)/2;
         if(p[mid].y<=x)
         {
           l = mid+1;
         }
         else if(p[mid].x>x)
         {
           r = mid;
         }
         else
         {
           return 0;
         }
       }
       if(x>=p[r].x&&x<p[r].y)
       {
         return 0;
       }
       return p[r].x-x;
     }
     static int n;
     static int[] in;
     static int[] outtime;
     static int[][] up;
     static int timer = 0;
     static int[] dp;
     static int l = 0;
     static int[] edge;
     static int[] ans;
     static ArrayList<pair>[] list;
     public static void dfs1(int v,int p)
     {
       in[v] = ++timer;
       up[v][0] = p;
       for(int i=1;i<=l;i++)
       {
         up[v][i] = up[up[v][i-1]][i-1];
       }
       for(pair x:list[v])
       {
         if(x.x!=p)
         {
           dfs1(x.x,v);
           edge[x.x] = x.y;
         }
       }
       outtime[v] = ++timer;
     }
     public static boolean upper(int a,int b)
     {
       return in[a]<=in[b]&&outtime[a]>=outtime[b];
     }
     public static int lca(int a,int b)
     {
       if(upper(a,b))
       {
         return a;
       }
       if(upper(b,a))
       {
         return b;
       }
       for(int i=l;i>=0;i--)
       {
         if(!upper(up[a][i],b))
         {
           a = up[a][i];
         }
       }
       return up[a][0];
     }
     public static void dfs2(int v,int p)
     {
       for(pair x:list[v])
       {
         if(x.x!=p)
         {
           dfs2(x.x,v);
           dp[v]+=dp[x.x];
         }
       }
       ans[edge[v]] = dp[v];
     }
     public static void main(String args[]) throws Exception {
         new Thread(null, new Solution(),"Main",1<<26).start();
     }
     public void run() {
       InputReader sc  = new InputReader(System.in);
       PrintWriter out = new PrintWriter(System.out);
       int t1 = 1;
       while(t1-->0)
       {
         n = sc.nextInt();
         while((1<<l)<n)l++;
         in = new int[n+1];
         outtime = new int[n+1];
         up = new int[n+1][l+1];
         dp = new int[n+1];
         edge = new int[n+1];
         ans = new int[n+1];
         list = new ArrayList[n+1];
         for(int i=1;i<=n;i++)
         {
           list[i] = new ArrayList<>();
         }
         for(int i=1;i<n;i++)
         {
           int x = sc.nextInt();
           int y = sc.nextInt();
           list[x].add(new pair(y,i));
           list[y].add(new pair(x,i));
         }
         dfs1(1,1);
         int m = sc.nextInt();
         for(int i=0;i<m;i++)
         {
           int x = sc.nextInt();
           int y = sc.nextInt();
           dp[x]++;
           dp[y]++;
           dp[lca(x,y)]-=2;
         }
         dfs2(1,1);
         for(int i=1;i<n;i++)
         {
           out.print(ans[i]+" ");
         }
         out.println();
       }
      out.close();
   }
 }