#include <bits/stdc++.h>   using namespace std;   using ll = long long;   using ld = long double;   using db = double;   using str = string;   using pi = pair<int, int>;   using pl = pair<ll, ll>;   using pd = pair<db, db>;   using vi = vector<int>;   using vb = vector<bool>;   using vl = vector<ll>;   using vd = vector<db>;   using vs = vector<str>;   using vpi = vector<pi>;   using vpl = vector<pl>;   using vpd = vector<pd>;   template <class T>   using V = vector<T>;   template <class T, size_t SZ>   using AR = array<T, SZ>;   template <class T>   using PR = pair<T, T>;   const int MOD = 1e9 + 7;   const int mxN = 1e3 + 5;   const ll INF = 1e18;   const ld PI = acos((ld)-1);   const int tSZ = (1 << 21);   const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};   mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());   constexpr int pcnt(int x) { return __builtin_popcount(x); }   constexpr int bits(int x) { return 31 - __builtin_clz(x); }   ll cdiv(ll a, ll b) { return a / b + ((a ^ b) > 0 && a % b); }   ll fdiv(ll a, ll b) { return a / b - ((a ^ b) < 0 && a % b); }   ll add(ll first, ll second) {     first += second;     if (first >= MOD) first %= MOD;     if (first < 0) first += MOD;     return first;   }   ll mul(ll first, ll second) {     first *= second;     if (first >= MOD) first %= MOD;     return first;   }   ll pw(ll x, ll y) {     ll ans = 1, ml = x;     while (y) {       if (y & 1) ans = mul(ans, ml);       ml = mul(ml, ml);       y >>= 1;     }     return ans;   }   ll inv(ll x) { return pw(x, MOD - 2); }   template <class T>   void remDup(vector<T>& x) {     sort(begin(x), end(x));     x.erase(unique(begin(x), end(x)), end(x));   }   template <class T, class U>   void erase(T& x, const U& v) {     auto it = x.find(v);     assert(it != end(x));     x.erase(v);   }   template <class T>   void re(complex<T>& c);   template <class T, class U>   void re(pair<T, U>& p);   template <class T>   void re(vector<T>& v);   template <class T, size_t SZ>   void re(array<T, SZ>& a);   template <class T>   void re(T& x) {     cin >> x;   }   void re(db& d) {     str t;     re(t);     d = stod(t);   }   void re(ld& d) {     str t;     re(t);     d = stold(t);   }   template <class T, class... U>   void re(T& t, U&... u) {     re(t);     re(u...);   }   template <class T>   void re(complex<T>& c) {     T a, b;     re(a, b);     c = {a, b};   }   template <class T, class U>   void re(pair<T, U>& p) {     re(p.first, p.second);   }   template <class T>   void re(vector<T>& x) {     for (auto& a : x) re(a);   }   template <class T, size_t SZ>   void re(array<T, SZ>& x) {     for (auto& a : x) re(a);   }   template <class T>   void rv(int& n, vector<T>& x) {     re(n);     x.resize(n);     for (auto& a : x) re(a);   }   str to_string(char c) { return str(1, c); }   str to_string(const char* second) { return (str)second; }   str to_string(str second) { return second; }   str to_string(bool b) { return to_string((int)b); }   template <class T>   str to_string(complex<T> c) {     stringstream ss;     ss << c;     return ss.str();   }   str to_string(vector<bool> v) {     str res =  { ;     for (int i = (0); i < ((int)(v).size()); i++) res += char( 0  + v[i]);     res +=  } ;     return res;   }   template <size_t SZ>   str to_string(bitset<SZ> b) {     str res =   ;     for (int i = (0); i < (SZ); i++) res += char( 0  + b[i]);     return res;   }   template <class T, class U>   str to_string(pair<T, U> p);   template <class T>   str to_string(T v) {     bool fst = 1;     str res =   ;     for (const auto& x : v) {       if (!fst) res +=    ;       fst = 0;       res += to_string(x);     }     return res;   }   template <class T, class U>   str to_string(pair<T, U> p) {     return to_string(p.first) +     + to_string(p.second);   }   template <class T>   void pr(T v) {     cout << to_string(v);   }   template <class T, class... U>   void pr(const T& t, const U&... u) {     pr(t);     pr(u...);   }   void ps() { pr(  n ); }   template <class T, class... U>   void ps(const T& t, const U&... u) {     pr(t);     if (sizeof...(u)) pr(   );     ps(u...);   }   void setIn(str second) { freopen(second.c_str(),  r , stdin); }   void setOut(str second) { freopen(second.c_str(),  w , stdout); }   void unsyncIO() { cin.tie(0)->sync_with_stdio(0); }   void setIO(str st =   ) {     unsyncIO();     if ((int)(st).size()) {       setIn(st +  .in ), setOut(st +  .out );     }   }   void DBG() { cerr <<  ]  << endl; }   template <class T, class... U>   void DBG(const T& t, const U&... u) {     cerr << to_string(t);     if (sizeof...(u)) cerr <<  ,  ;     DBG(u...);   }   int n, k;   str matr[mxN * mxN];   vector<str> vv;   int graph[30][30];   int c_br[mxN * mxN];   bool ok = 1;   void calc() {     for (int i = (0); i < ((int)(vv).size() - 1); i++) {       str tmp = vv[i];       str nxt = vv[i + 1];       int k = 0;       int zz = min((int)(tmp).size(), (int)(nxt).size());       while (k < zz && tmp[k] == nxt[k]) {         k++;       }       if (k < zz) {         graph[tmp[k] -  a ][nxt[k] -  a ] = 1;       } else if ((int)(tmp).size() > (int)(nxt).size()) {         ok = 0;       }     }   }   void solve() {     vi vis(27, 0);     set<int> alphabet;     for (int i = (0); i < (n * k); i++) {       if ((int)(matr[i]).size() != 0) {         vv.push_back(matr[i]);         for (auto& x : matr[i]) alphabet.insert(x -  a );       }     }     for (int i = (0); i < ((int)(vv).size()); i++) {       c_br[i] = (int)(vv[i]).size();     }     calc();     vi ans;     for (int i = (0); i < (27); i++) {       for (int j = (0); j < (27); j++) {         if (vis[j] || !alphabet.count(j)) continue;         int cnt = 0;         for (int z = (0); z < (27); z++) {           cnt += graph[z][j];         }         if (cnt == 0) {           ans.push_back(j);           vis[j] = 1;           for (int z = (0); z < (27); z++) {             graph[j][z] = 0;           }         }       }     }     if (!ok || (int)(ans).size() != (int)(alphabet).size()) {       ps( IMPOSSIBLE );       return;     }     for (auto& x : ans) {       pr(char(x +  a ));     }     ps();   }   int main() {     setIO();     re(n, k);     int c;     for (int i = (0); i < (n); i++) {       re(c);       for (int j = (0); j < (k); j++) {         re(matr[c * n + j]);       }     }     solve();     return 0;   }