#include <bits/stdc++.h>
using namespace std;
long long mod = 998244353;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
long long lcm(long long a, long long b) { return a * b / gcd(a, b); }
int days[15] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int is_leapyear(int y) { return y % 400 == 0 || (y % 4 == 0 && y % 100 != 0); }
int dx[8] = {0, 0, 1, -1, -1, -1, 1, 1};
int dy[8] = {1, -1, 0, 0, -1, 1, -1, 1};
inline long long read() {
  long long x = 0, sign = 1;
  char ch = getchar();
  for (; !isdigit(ch); ch = getchar())
    if (ch == '-') sign = -1;
  for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
  return sign * x;
}
inline void write(long long x) {
  char r[30];
  int t = 0;
  if (x < 0) {
    x = -x;
    putchar('-');
  }
  do {
    r[t++] = x % 10 + '0';
    x /= 10;
  } while (x);
  while (t) putchar(r[--t]);
}
inline void writesp(long long x) {
  write(x);
  putchar(' ');
}
inline void writeln(long long x) {
  write(x);
  putchar('\n');
}
long long qpow(long long a, long long b) {
  long long ans = 1;
  while (b) {
    if (b & 1) ans = ans * a % mod;
    a = a * a % mod;
    b >>= 1;
  }
  return ans;
}
struct node {
  int id;
  char str[1005][105];
  bool operator<(const node& r) const { return id < r.id; }
} q[1005];
char order[1000010][105];
int tail;
vector<int> G[30];
int in[30];
int tot, vis[30];
int MAP[30][30];
void solve(char a[], char b[]) {
  int sz1 = strlen(a), sz2 = strlen(b);
  int sz = min(sz1, sz2);
  for (int i = 0; i < sz; i++) {
    if (a[i] != b[i]) {
      int x = a[i] - 'a', y = b[i] - 'a';
      if (!MAP[x][y]) {
        MAP[x][y] = 1;
        in[y]++;
      }
      return;
    }
  }
  if (sz1 > sz2) {
    puts("IMPOSSIBLE");
    exit(0);
  }
}
void Topo() {
  vector<char> vec;
  queue<int> que;
  for (int i = 0; i < 26; i++) {
    if (vis[i] && in[i] == 0) {
      que.push(i);
    }
  }
  while (!que.empty()) {
    int u = que.front();
    que.pop();
    vec.push_back(u + 'a');
    for (int i = 0; i < 26; i++) {
      if (MAP[u][i]) {
        in[i]--;
        if (in[i] == 0) {
          que.push(i);
        }
      }
    }
  }
  if (((long long)(vec).size()) != tot)
    puts("IMPOSSIBLE");
  else {
    for (auto x : vec) putchar(x);
    putchar('\n');
  }
}
int main() {
  int n = read(), k = read();
  for (int i = 1; i <= n; i++) {
    q[i].id = read();
    for (int j = 1; j <= k; j++) {
      scanf("%s", q[i].str[j]);
      int len = strlen(q[i].str[j]);
      for (int r = 0; r < len; r++) {
        if (!vis[q[i].str[j][r] - 'a']) {
          vis[q[i].str[j][r] - 'a'] = 1;
          tot++;
        }
      }
    }
  }
  sort(q + 1, q + 1 + n);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= k; j++) {
      ++tail;
      int len = strlen(q[i].str[j]);
      for (int r = 0; r < len; r++) {
        order[tail][r] = q[i].str[j][r];
      }
    }
  }
  for (int i = 1; i <= tail - 1; i++) {
    solve(order[i], order[i + 1]);
  }
  Topo();
  return 0;
}
