#define _CRT_SECURE_NO_WARNINGS
#define _SILENCE_CXX17_C_HEADER_DEPRECATION_WARNING
#include <bits/stdc++.h>
using namespace std;
#define CRP(t, x) const t &x
#define OPL(t, x) bool operator<(CRP(t, x)) const
#define FIL(x, v) memset(x, v, sizeof(x))
#define CLR(x) FIL(x, 0)
#define NE1(x) FIL(x, -1)
#define INF(x) FIL(x, 0x3f)
typedef long long ll, i64;
const int N = 1e5 + 40;
char buf[N];
#define ID(ch, po) ((ch - 'a') * N + po)
struct Edge
{
    int nxt, to;
} E[N * 10];
int adj[N * 10], ecnt, in[N * 10];
inline void addEdge(int f, int t)
{
    if (in[f] == -1) in[f] = 0;
    if (in[t] == -1) in[t] = 0;
    E[++ecnt] = {adj[f], t};
    adj[f] = ecnt;
    in[t]++;
}
int main()
{
    NE1(in);
    int n, m, mm, l;
    scanf("%d%d", &n, &m), mm = m * (m - 1) / 2;
    for (int i = 0; i < mm; i++)
    {
        scanf("%s%d", buf, &l);
        int cnt[] = {0, 1};
        if (l)
        {
            scanf("%s", buf);
            for (int j = 1; j < l; j++)
            {
                int type1 = buf[j - 1] == *buf;
                int type2 = buf[j] == *buf;
                cnt[type2]++;
                addEdge(ID(buf[j - 1], cnt[type1] - (buf[j - 1] == buf[j])), ID(buf[j], cnt[type2]));
            }
        }
    }
    vector<char> ans;
    ans.reserve(n);
    queue<int> Q;
    for (int i = 0; i < N * 10; i++)
        if (in[i] == 0) Q.push(i);
    for (; !Q.empty(); Q.pop())
    {
        ans.push_back(Q.front() / N + 'a');
        for (int e = adj[Q.front()]; e; e = E[e].nxt)
            if (--in[E[e].to] == 0)
                Q.push(E[e].to);
    }
    if (ans.size() != n)
        puts("-1");
    else
        ans.push_back(0), puts(ans.data());
    return 0;
}