#include <bits/stdc++.h>
using namespace std;
int n, k;
vector<int> e[26];
vector<string> dic[1005];
string ss, prv = "";
bool ok = 1, cyc = 0;
int v[26];
vector<int> topo;
bool seen[26];
void cutler(string s1, string s2) {
  bool eq = 1;
  for (int i = 0; i < min((int)s1.size(), (int)s2.size()); i++) {
    if (s1[i] != s2[i]) {
      e[s1[i] - 'a'].push_back(s2[i] - 'a');
      eq = 0;
      break;
    }
  }
  if (eq && (int)s1.size() > (int)s2.size()) ok = 0;
}
void dfs(int g) {
  v[g] = 1;
  for (auto u : e[g]) {
    if (v[u] == 2) continue;
    if (v[u] == 1) {
      cyc = 1;
      return;
    }
    dfs(u);
  }
  topo.push_back(g);
  v[g] = 2;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> k;
  for (int i = 1; i <= n; i++) {
    int pg;
    cin >> pg;
    for (int j = 1; j <= k; j++) {
      cin >> ss;
      dic[pg].push_back(ss);
    }
  }
  for (int i = 0; i < n; i++) {
    for (auto u : dic[i]) {
      for (auto cc : u) seen[cc - 'a'] = 1;
      cutler(prv, u);
      prv = u;
      if (!ok) {
        cout << "IMPOSSIBLE" << endl;
        return 0;
      }
    }
  }
  for (int i = 0; i < 26; i++) {
    if (v[i]) continue;
    if (!seen[i]) continue;
    dfs(i);
    if (cyc) {
      cout << "IMPOSSIBLE" << endl;
      return 0;
    }
  }
  reverse(topo.begin(), topo.end());
  for (auto u : topo) cout << (char)(u + 'a');
  cout << endl;
  cout.flush();
  return 0;
}
