#include <bits/stdc++.h>
using namespace std;
const int MAXN = 112345;
const int MAXINT = 2147483098;
const long long MAXLL = 9223372036854775258LL;
vector<int> g[26];
bool used[26];
vector<int> topsort;
void dfs(int v) {
  used[v] = true;
  for (int to : g[v])
    if (!used[to]) {
      dfs(to);
    }
  topsort.push_back(v);
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int n, k;
  cin >> n >> k;
  vector<bool> is_in_alphabet(26);
  vector<string> w(n * k);
  for (int i = 0; i < n; ++i) {
    int p;
    cin >> p;
    for (int j = 0; j < k; ++j) {
      int current_index = p * n + j;
      cin >> w[current_index];
      for (char c : w[current_index]) is_in_alphabet[c - 'a'] = true;
    }
  }
  vector<pair<int, int> > need_fix;
  for (int i = 1; i < n * k; ++i) {
    int pos = -1;
    for (int j = 0; j < min(w[i].size(), w[i - 1].size()); ++j)
      if (w[i][j] != w[i - 1][j]) {
        pos = j;
        break;
      }
    if (pos == -1) {
      if (w[i - 1].size() > w[i].size()) {
        cout << "IMPOSSIBLE" << '\n';
        return 0;
      }
      continue;
    }
    g[w[i][pos] - 'a'].push_back(w[i - 1][pos] - 'a');
    need_fix.push_back({w[i - 1][pos] - 'a', w[i][pos] - 'a'});
  }
  for (int i = 0; i < 26; ++i) {
    if (is_in_alphabet[i] && !used[i]) dfs(i);
  }
  vector<int> place(26);
  for (int i = 0; i < topsort.size(); ++i) place[topsort[i]] = i;
  for (const auto& item : need_fix) {
    if (place[item.first] > place[item.second]) {
      cout << "IMPOSSIBLE" << '\n';
      return 0;
    }
  }
  for (int x : topsort) cout << char(x + 'a');
  return 0;
}
