#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/stack:36777216")
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
inline void boostIO() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cout << fixed << setprecision(10);
}
bool isPrime(int x) {
  if (x <= 4 || x % 2 == 0 || x % 3 == 0) return x == 2 || x == 3;
  for (int i = 5; i * i <= x; i += 6)
    if (x % i == 0 || x % (i + 2) == 0) return 0;
  return 1;
}
long long int gcd(long long int a, long long int b) {
  return b ? gcd(b, a % b) : a;
}
long long int lcm(long long int a, long long int b) {
  return a * b / gcd(a, b);
}
template <typename T>
inline T getint() {
  T val = 0;
  char c;
  bool neg = false;
  while ((c = getchar()) && !(c >= '0' && c <= '9')) {
    neg |= c == '-';
  }
  do {
    val = (val * 10) + c - '0';
  } while ((c = getchar()) && (c >= '0' && c <= '9'));
  return val * (neg ? -1 : 1);
}
int Mod = 1e9 + 7;
long long int inf = 2e18;
vector<int> ans(0);
void dfs(int node, vector<vector<int>>& adj, vector<int>& used) {
  used[node] = 1;
  for (auto x : adj[node]) {
    if (used[x] == 0) {
      dfs(x, adj, used);
    }
  }
  ans.push_back(node);
}
bool FLAG = 0;
void dfs2(int node, vector<vector<int>>& adj, vector<int>& used) {
  used[node] = 1;
  for (auto x : adj[node]) {
    if (used[x] == 0) {
      dfs2(x, adj, used);
    } else if (used[x] == 1) {
      FLAG = 1;
    }
  }
  used[node] = 2;
}
int32_t main() {
  boostIO();
  int n, k;
  cin >> n >> k;
  vector<vector<string>> SSS(n, vector<string>(k));
  for (int i = 0; i < (n); ++i) {
    int p;
    cin >> p;
    for (int j = 0; j < (k); ++j) {
      cin >> SSS[p][j];
    }
  }
  vector<string> S(n * k);
  for (int i = 0; i < (n); ++i) {
    for (int j = 0; j < (k); ++j) {
      S[i * k + j] = SSS[i][j];
    }
  }
  n = n * k;
  vector<int> V(n, 1);
  vector<vector<int>> adj(26, vector<int>(0));
  vector<int> WAS(26);
  for (auto s : S) {
    for (auto c : s) {
      WAS[c - 'a'] = 1;
    }
  }
  for (int l = 0; l < 100; ++l) {
    for (int i = 0; i < (n - 1); ++i) {
      if (V[i] == 0) continue;
      if (l >= S[i].size()) {
        V[i] = 0;
      } else if (l >= S[i + 1].size()) {
        if (l < S[i].size() && V[i] == 1) {
          FLAG = 1;
        }
        V[i] = 0;
      } else if (S[i][l] != S[i + 1][l]) {
        V[i] = 0;
        adj[S[i][l] - 'a'].push_back(S[i + 1][l] - 'a');
      }
    }
  }
  n = 26;
  vector<int> used2(n);
  for (int i = 0; i < (n); ++i) {
    if (used2[i] == 0) dfs2(i, adj, used2);
  }
  if (FLAG == 1) {
    cout << "IMPOSSIBLE" << '\n';
    return 0;
  }
  vector<int> used(n);
  for (int i = 0; i < (n); ++i) {
    int node = i;
    if (used[node] == 0) dfs(node, adj, used);
  }
  reverse(ans.begin(), ans.end());
  for (auto x : ans) {
    if (WAS[x]) cout << (char)(x + 'a');
  }
  cerr << '\n' << "RUNTIME: " << 1.0 * clock() / CLOCKS_PER_SEC << " s" << '\n';
  return 0;
  ;
}
