#include <bits/stdc++.h>
using namespace std;
int n, k, p;
int gr[26][26], vis[26] = {0}, pre[26] = {0}, flag = 0;
std::vector<int> ans;
void dfs(int v) {
  if (!pre[v] || vis[v]) return;
  vis[v] = 1;
  for (int i = 0; i < 26; ++i) {
    if (gr[v][i] == 0) continue;
    if (vis[i] == 1) {
      flag = 1;
      break;
    } else if (!vis[i]) {
      dfs(i);
    }
    if (flag) return;
  }
  vis[v] = 2;
  ans.push_back(v);
}
void topological_sort() {
  ans.clear();
  for (int i = 0; i < 26; ++i) {
    if (!vis[i]) dfs(i);
    if (flag) {
      ans.clear();
      return;
    }
  }
  reverse(ans.begin(), ans.end());
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cin >> n >> k;
  string s[n][k];
  for (int i = 0; i < 26; ++i)
    for (int j = 0; j < 26; ++j) gr[i][j] = 0;
  for (int i = 0; i < n; ++i) {
    cin >> p;
    for (int j = 0; j < k; ++j) {
      cin >> s[p][j];
      for (int r = 0; r < s[p][j].size(); ++r) pre[s[p][j][r] - 'a'] = 1;
    }
  }
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < k - 1; ++j) {
      int a = 0, b = 0;
      while (a < (int)(s[i][j]).size() && b < (int)(s[i][j + 1]).size() &&
             s[i][j][a] == s[i][j + 1][b])
        ++a, ++b;
      if (a < (int)(s[i][j]).size() && b < (int)(s[i][j + 1]).size())
        gr[s[i][j][a] - 'a'][s[i][j + 1][b] - 'a'] = 1;
      if (b >= (int)(s[i][j + 1]).size() && a < (int)(s[i][j]).size()) flag = 1;
    }
    if (i != n - 1) {
      int a = 0, b = 0;
      while (a < (int)(s[i][k - 1]).size() && b < (int)(s[i + 1][0]).size() &&
             s[i][k - 1][a] == s[i + 1][0][b])
        ++a, ++b;
      if (a < (int)(s[i][k - 1]).size() && b < (int)(s[i + 1][0]).size())
        gr[s[i][k - 1][a] - 'a'][s[i + 1][0][b] - 'a'] = 1;
      if (b >= (int)(s[i + 1][0]).size() && a < (int)(s[i][k - 1]).size())
        flag = 1;
    }
  }
  topological_sort();
  if (flag) cout << "IMPOSSIBLE\n";
  for (auto v : ans) {
    char c = v + 'a';
    cout << c;
  }
  cout << '\n';
  return 0;
}
