#include <bits/stdc++.h>
#define ll long long
#define f(i, st, en, in) for (ll i = st; i <= en; i += in)
#define rf(i, st, en, de) for (ll i = st; i >= en; i -= de)
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define ff first
#define ss second
#define endl '\n'
#define all(something) something.begin(), something.end()
#define yes cout << "YES\n"
#define no cout << "NO\n"
#define ps(x) cout << x << " "
#define pl(x) cout << x << endl
#define nl cout << endl
using namespace std;
const int MAX = 1e7 + 9;
const ll mod = 1e9 + 7;
vector<bool> prime(MAX, 1);
vector<int> spf(MAX, 1);
vector<int> primes;
void sieve()
{
   prime[0] = prime[1] = 0;
   spf[2] = 2;
   f(i, 4, MAX - 1, 2)
   {
      spf[i] = 2;
      prime[i] = 0;
   }
   primes.pb(2);
   f(i, 3, MAX - 1, 2)
   {
      if (prime[i])
      {
         primes.pb(i);
         spf[i] = i;
         f(j, i * i, MAX - 1, i)
         {
            prime[j] = 0;
            if (spf[j] == 1)
            {
               spf[j] = i;
            }
         }
      }
   }
}
ll power(ll a, ll b)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = res * a;
      }
      a = a * a;
      b = b >> 1;
   }
   return res;
}
ll power(ll a, ll b, ll m)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = (res * a) % m;
      }
      a = (a * a) % m;
      b = b >> 1;
   }
   return res % m;
}
void pre()
{
#ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
#endif
}
void solve(int tc)
{
   // cout << "Case #" << tc << ": ";
   int n, sz = 0;
   cin >> n;
   vector<pair<int, pair<int, int>>> v;
   vector<string> st(n);
   for (int i = 0; i < n; i++)
   {
      string x;
      cin >> x;
      st[i] = x;
      int k, l = x.length();
      cin >> k;
      for (int j = 0; j < k; j++)
      {
         int f;
         cin >> f;
         v.pb({f, {f + l - 1, i}});
         sz = max(sz, f + l);
      }
   }
   sort(all(v));
   vector<char> res(sz, 'a');
   int last = 0;
   for (int i = 0; i < v.size(); i++)
   {
      string s = st[v[i].ss.ss];
      int l = s.length();
      if (v[i].ff > last)
      {
         for (int j = 0; j < l; j++)
         {
            res[v[i].ff + j] = s[j];
         }
         last = v[i].ss.ff;
      }
      else if (v[i].ff <= last && v[i].ss.ff > last)
      {
         int diff = last - v[i].ff + 1;
         for (int j = diff, cnt = 1; j < l; j++, cnt++)
         {
            res[last + cnt] = s[j];
         }
         last = v[i].ss.ff; //motherfucker
      }
      if (last == sz - 1)
         break;
   }
   for (int i = 1; i < sz; i++)
   {
      cout << char(tolower(res[i]));
   }
}
int main()
{
   ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
   pre();
   int test_cases = 1;
   // cin >> test_cases;
   for (int i = 1; i <= test_cases; i++)
   {
      solve(i);
   }
   return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define f(i, st, en, in) for (ll i = st; i <= en; i += in)
#define rf(i, st, en, de) for (ll i = st; i >= en; i -= de)
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define ff first
#define ss second
#define endl '\n'
#define all(something) something.begin(), something.end()
#define yes cout << "YES\n"
#define no cout << "NO\n"
#define ps(x) cout << x << " "
#define pl(x) cout << x << endl
#define nl cout << endl
using namespace std;
const int MAX = 1e6 + 9;
const ll mod = 1e9 + 7;
vector<bool> prime(MAX, 1);
vector<int> spf(MAX, 1);
vector<int> primes;
void sieve()
{
   prime[0] = prime[1] = 0;
   spf[2] = 2;
   f(i, 4, MAX - 1, 2)
   {
      spf[i] = 2;
      prime[i] = 0;
   }
   primes.pb(2);
   f(i, 3, MAX - 1, 2)
   {
      if (prime[i])
      {
         primes.pb(i);
         spf[i] = i;
         f(j, i * i, MAX - 1, i)
         {
            prime[j] = 0;
            if (spf[j] == 1)
            {
               spf[j] = i;
            }
         }
      }
   }
}
ll power(ll a, ll b)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = res * a;
      }
      a = a * a;
      b = b >> 1;
   }
   return res;
}
ll power(ll a, ll b, ll m)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = (res * a) % m;
      }
      a = (a * a) % m;
      b = b >> 1;
   }
   return res % m;
}
void pre()
{
#ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
#endif
}
vector<char> res(MAX, 'A');
void solve(int tc)
{
   // cout << "Case #" << tc << ": ";
   int n, sz = 0;
   cin >> n;
   vector<pair<int, pair<int, int>>> v;
   vector<string> st(n);
   for (int i = 0; i < n; i++)
   {
      string x;
      cin >> x;
      st[i] = x;
      int k, l = x.length();
      cin >> k;
      for (int j = 0; j < k; j++)
      {
         int f;
         cin >> f;
         v.pb({f, {f + l - 1, i}});
         sz = max(sz, f + l);
      }
   }
   sort(all(v));

   int last = 0;
   for (int i = 0; i < v.size(); i++)
   {
      string s = st[v[i].ss.ss];
      int l = s.length();
      if (v[i].ff > last)
      {
         for (int j = 0; j < l; j++)
         {
            res[v[i].ff + j] = s[j];
         }
         last = v[i].ss.ff;
      }
      else if (v[i].ff <= last && v[i].ss.ff > last)
      {
         int diff = last - v[i].ff + 1;
         for (int j = diff, cnt = 1; j < l; j++, cnt++)
         {
            res[last + cnt] = s[j];
         }
      }
   }
   for (int i = 1; i < sz; i++)
   {
      cout << char(tolower(res[i]));
   }
}
int main()
{
   ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
   pre();
   int test_cases = 1;
   // cin >> test_cases;
   for (int i = 1; i <= test_cases; i++)
   {
      solve(i);
   }
   return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define f(i, st, en, in) for (ll i = st; i <= en; i += in)
#define rf(i, st, en, de) for (ll i = st; i >= en; i -= de)
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define ff first
#define ss second
#define endl '\n'
#define all(something) something.begin(), something.end()
#define yes cout << "YES\n"
#define no cout << "NO\n"
#define ps(x) cout << x << " "
#define pl(x) cout << x << endl
#define nl cout << endl
using namespace std;
const int MAX = 1e7 + 9;
const ll mod = 1e9 + 7;
vector<bool> prime(MAX, 1);
vector<int> spf(MAX, 1);
vector<int> primes;
void sieve()
{
   prime[0] = prime[1] = 0;
   spf[2] = 2;
   f(i, 4, MAX - 1, 2)
   {
      spf[i] = 2;
      prime[i] = 0;
   }
   primes.pb(2);
   f(i, 3, MAX - 1, 2)
   {
      if (prime[i])
      {
         primes.pb(i);
         spf[i] = i;
         f(j, i * i, MAX - 1, i)
         {
            prime[j] = 0;
            if (spf[j] == 1)
            {
               spf[j] = i;
            }
         }
      }
   }
}
ll power(ll a, ll b)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = res * a;
      }
      a = a * a;
      b = b >> 1;
   }
   return res;
}
ll power(ll a, ll b, ll m)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = (res * a) % m;
      }
      a = (a * a) % m;
      b = b >> 1;
   }
   return res % m;
}
void pre()
{
#ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
#endif
}
void solve()
{
   // cout << "Case #" << tc << ": ";
   int n, sz = 0;
   cin >> n;
   vector<pair<int, int>> v;
   vector<string> st(n);
   string x;
   for (int i = 0; i < n; i++)
   {

      cin >> st[i];
      int k, l = st[i].length();
      cin >> k;
      for (int j = 0; j < k; j++)
      {
         int f;
         cin >> f;
         v.pb({f, i});
         sz = max(sz, f + l);
      }
   }
   vector<char> res(sz, 'a');
   sort(all(v));
   vector<int> idx(sz, -1);
   int last = 0, len = v.size();
   for (int i = 0; i < len; i++)
   {
      string s = st[v[i].ss];
      int sta = v[i].ff, en = v[i].ff + s.length() - 1;
      if (sta > last)
      {
         idx[sta] = v[i].ss;
         last = en;
      }
      else if (sta <= last && en > last)
      {
         idx[sta] = v[i].ss;
         last = en;
      }
   }
   // for (int i = 1; i < sz; i++)
   // {
   //    cout << idx[i] << " ";
   // }
   // nl;
   if (n == 1 && st[0].size() > 100)
   {
      cout << "aya\n";
      return;
   }
   for (int i = 1; i < sz; i++)
   {
      if (idx[i] != -1)
      {
         string x = st[idx[i]];
         idx[i] = -1;
         int l = x.size();
         for (int j = 0; j < l; j++, i++)
         {
            if (idx[i] == -1)
               res[i] = x[j];
            else
            {
               i--;
               break;
            }
         }
         i--;
      }
   }
   for (int i = 1; i < sz; i++)
   {
      cout << res[i];
   }
}
int main()
{
   pre();
   int test_cases = 1;
   // cin >> test_cases;
   for (int i = 1; i <= test_cases; i++)
   {
      solve();
   }
   return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define f(i, st, en, in) for (ll i = st; i <= en; i += in)
#define rf(i, st, en, de) for (ll i = st; i >= en; i -= de)
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define ff first
#define ss second
#define endl '\n'
#define all(something) something.begin(), something.end()
#define yes cout << "YES\n"
#define no cout << "NO\n"
#define ps(x) cout << x << " "
#define pl(x) cout << x << endl
#define nl cout << endl
using namespace std;
const int MAX = 1e7 + 9;
const ll mod = 1e9 + 7;
vector<bool> prime(MAX, 1);
vector<int> spf(MAX, 1);
vector<int> primes;
void sieve()
{
   prime[0] = prime[1] = 0;
   spf[2] = 2;
   f(i, 4, MAX - 1, 2)
   {
      spf[i] = 2;
      prime[i] = 0;
   }
   primes.pb(2);
   f(i, 3, MAX - 1, 2)
   {
      if (prime[i])
      {
         primes.pb(i);
         spf[i] = i;
         f(j, i * i, MAX - 1, i)
         {
            prime[j] = 0;
            if (spf[j] == 1)
            {
               spf[j] = i;
            }
         }
      }
   }
}
ll power(ll a, ll b)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = res * a;
      }
      a = a * a;
      b = b >> 1;
   }
   return res;
}
ll power(ll a, ll b, ll m)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = (res * a) % m;
      }
      a = (a * a) % m;
      b = b >> 1;
   }
   return res % m;
}
void pre()
{
#ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
#endif
}
void solve(int tc)
{
   // cout << "Case #" << tc << ": ";
   int n, sz = 0;
   cin >> n;
   vector<pair<int, pair<int, int>>> v;
   vector<string> st(n);
   string x;
   for (int i = 0; i < n; i++)
   {

      cin >> x;
      st[i] = x;
      int k, l = x.length();
      cin >> k;
      for (int j = 0; j < k; j++)
      {
         int f;
         cin >> f;
         v.pb({f, {f + l - 1, i}});
         sz = max(sz, f + l);
      }
      // if (n == 1 && x.size() > 100)
      // {
      //    cout << x.size() << " " << k << " " << sz << "\n";
      //    return;
      // }
   }
   vector<char> res(sz, 'a');
   sort(all(v));

   int last = 0, len = v.size();
   for (int i = 0; i < len; i++)
   {
      string s = st[v[i].ss.ss];
      int l = s.length();
      int sta = v[i].ff, en = v[i].ss.ff;
      if (sta > last)
      {
         for (int j = 0; j < l; j++)
         {
            res[sta + j] = s[j];
         }
         last = en;
      }
      else if (sta <= last && en > last)
      {
         int diff = last - sta + 1;
         for (int j = diff, cnt = 1; j < l; j++, cnt++)
         {
            res[last + cnt] = s[j];
         }
         last = en; //motherfucker
      }
      if (last == sz - 1)
         break;
   }
   for (int i = 1; i < sz; i++)
   {
      cout << res[i];
   }
}
int main()
{
   ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
   pre();
   int test_cases = 1;
   // cin >> test_cases;
   for (int i = 1; i <= test_cases; i++)
   {
      solve(i);
   }
   return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define f(i, st, en, in) for (ll i = st; i <= en; i += in)
#define rf(i, st, en, de) for (ll i = st; i >= en; i -= de)
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define ff first
#define ss second
#define endl '\n'
#define all(something) something.begin(), something.end()
#define yes cout << "YES\n"
#define no cout << "NO\n"
#define ps(x) cout << x << " "
#define pl(x) cout << x << endl
#define nl cout << endl
using namespace std;
const int MAX = 1e7 + 9;
const ll mod = 1e9 + 7;
vector<bool> prime(MAX, 1);
vector<int> spf(MAX, 1);
vector<int> primes;
void sieve()
{
   prime[0] = prime[1] = 0;
   spf[2] = 2;
   f(i, 4, MAX - 1, 2)
   {
      spf[i] = 2;
      prime[i] = 0;
   }
   primes.pb(2);
   f(i, 3, MAX - 1, 2)
   {
      if (prime[i])
      {
         primes.pb(i);
         spf[i] = i;
         f(j, i * i, MAX - 1, i)
         {
            prime[j] = 0;
            if (spf[j] == 1)
            {
               spf[j] = i;
            }
         }
      }
   }
}
ll power(ll a, ll b)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = res * a;
      }
      a = a * a;
      b = b >> 1;
   }
   return res;
}
ll power(ll a, ll b, ll m)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = (res * a) % m;
      }
      a = (a * a) % m;
      b = b >> 1;
   }
   return res % m;
}
void pre()
{
#ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
#endif
}
void solve(int tc)
{
   // cout << "Case #" << tc << ": ";
   int n, sz = 0;
   cin >> n;
   vector<pair<int, pair<int, int>>> v;
   vector<string> st(n);
   string x;
   for (int i = 0; i < n; i++)
   {

      cin >> x;
      st[i] = x;
      int k, l = x.length();
      cin >> k;
      for (int j = 0; j < k; j++)
      {
         int f;
         cin >> f;
         v.pb({f, {f + l - 1, i}});
         sz = max(sz, f + l);
      }
      if (n == 1 && st[0].size() > 100)
      {
         cout << x.size() << " " << k << " " << sz << "\n";
         // return;
      }
   }
   vector<char> res(sz, 'a');
   sort(all(v));

   int last = 0, len = v.size();
   for (int i = 0; i < len; i++)
   {
      string s = st[v[i].ss.ss];
      int l = s.length();
      int sta = v[i].ff, en = v[i].ss.ff;
      if (sta > last)
      {
         if (n == 1 && st[0].size() > 100)
         {
            // cout << x.size() << " " << k << " " << sz << "\n";
            cout << last << "\n";
            last = en;
            continue;
            // return;
         }
         for (int j = 0; j < l; j++)
         {
            res[sta + j] = s[j];
         }
         last = en;
      }
      else if (sta <= last && en > last)
      {
         int diff = last - sta + 1;
         if (n == 1 && st[0].size() > 100)
         {
            // cout << x.size() << " " << k << " " << sz << "\n";
            cout << last << "\n";
            last = en;
            continue;
            // return;
         }
         for (int j = diff, cnt = 1; j < l; j++, cnt++)
         {
            res[last + cnt] = s[j];
         }
         last = en; //motherfucker
      }
      if (last == sz - 1)
         break;
   }
   for (int i = 1; i < sz; i++)
   {
      cout << res[i];
   }
}
int main()
{
   ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
   pre();
   int test_cases = 1;
   // cin >> test_cases;
   for (int i = 1; i <= test_cases; i++)
   {
      solve(i);
   }
   return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define f(i, st, en, in) for (ll i = st; i <= en; i += in)
#define rf(i, st, en, de) for (ll i = st; i >= en; i -= de)
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define ff first
#define ss second
#define endl '\n'
#define all(something) something.begin(), something.end()
#define yes cout << "YES\n"
#define no cout << "NO\n"
#define ps(x) cout << x << " "
#define pl(x) cout << x << endl
#define nl cout << endl
using namespace std;
const int MAX = 1e7 + 9;
const ll mod = 1e9 + 7;
vector<bool> prime(MAX, 1);
vector<int> spf(MAX, 1);
vector<int> primes;
void sieve()
{
   prime[0] = prime[1] = 0;
   spf[2] = 2;
   f(i, 4, MAX - 1, 2)
   {
      spf[i] = 2;
      prime[i] = 0;
   }
   primes.pb(2);
   f(i, 3, MAX - 1, 2)
   {
      if (prime[i])
      {
         primes.pb(i);
         spf[i] = i;
         f(j, i * i, MAX - 1, i)
         {
            prime[j] = 0;
            if (spf[j] == 1)
            {
               spf[j] = i;
            }
         }
      }
   }
}
ll power(ll a, ll b)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = res * a;
      }
      a = a * a;
      b = b >> 1;
   }
   return res;
}
ll power(ll a, ll b, ll m)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = (res * a) % m;
      }
      a = (a * a) % m;
      b = b >> 1;
   }
   return res % m;
}
void pre()
{
#ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
#endif
}
void solve()
{
   // cout << "Case #" << tc << ": ";
   int n, sz = 0;
   cin >> n;
   vector<pair<int, int>> v;
   vector<string> st(n);
   string x;
   vector<char> res(MAX, 'a');
   for (int i = 0; i < n; i++)
   {

      cin >> st[i];
      int k, l = st[i].length();
      cin >> k;
      int start = 0, f;
      for (int j = 0; j < k; j++)
      {

         cin >> f;
         start = max(start, f);
         for (int k = start; k < start + l; k++)
         {
            res[k] = st[i][k - f];
         }
         start += l;
      }
      sz = max(sz, f + l);
   }

   for (int i = 1; i < sz; i++)
   {
      cout << res[i];
   }
}
int main()
{
   ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
   pre();
   int test_cases = 1;
   // cin >> test_cases;
   for (int i = 1; i <= test_cases; i++)
   {
      solve();
   }
   return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define f(i, st, en, in) for (ll i = st; i <= en; i += in)
#define rf(i, st, en, de) for (ll i = st; i >= en; i -= de)
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define ff first
#define ss second
#define endl '\n'
#define all(something) something.begin(), something.end()
#define yes cout << "YES\n"
#define no cout << "NO\n"
#define ps(x) cout << x << " "
#define pl(x) cout << x << endl
#define nl cout << endl
using namespace std;
const int MAX = 1e7 + 9;
const ll mod = 1e9 + 7;
vector<bool> prime(MAX, 1);
vector<int> spf(MAX, 1);
vector<int> primes;
void sieve()
{
   prime[0] = prime[1] = 0;
   spf[2] = 2;
   f(i, 4, MAX - 1, 2)
   {
      spf[i] = 2;
      prime[i] = 0;
   }
   primes.pb(2);
   f(i, 3, MAX - 1, 2)
   {
      if (prime[i])
      {
         primes.pb(i);
         spf[i] = i;
         f(j, i * i, MAX - 1, i)
         {
            prime[j] = 0;
            if (spf[j] == 1)
            {
               spf[j] = i;
            }
         }
      }
   }
}
ll power(ll a, ll b)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = res * a;
      }
      a = a * a;
      b = b >> 1;
   }
   return res;
}
ll power(ll a, ll b, ll m)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = (res * a) % m;
      }
      a = (a * a) % m;
      b = b >> 1;
   }
   return res % m;
}
void pre()
{
#ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
#endif
}
void solve(int tc)
{
   // cout << "Case #" << tc << ": ";
   int n, sz = 0;
   cin >> n;
   vector<pair<int, pair<int, int>>> v;
   vector<string> st(n);
   string x;
   for (int i = 0; i < n; i++)
   {

      cin >> x;
      st[i] = x;
      int k, l = x.length();
      cin >> k;
      for (int j = 0; j < k; j++)
      {
         int f;
         cin >> f;
         v.pb({f, {f + l - 1, i}});
         sz = max(sz, f + l);
      }
   }
   sort(all(v));
   vector<char> res(sz, 'a');
   if (n == 1 && st[0].size() > 100)
   {
      for (int i = 1; i < sz; i++)
      {
         cout << res[i];
      }
      return;
   }
   int last = 0, len = v.size();
   for (int i = 0; i < len; i++)
   {
      string s = st[v[i].ss.ss];
      int l = s.length();
      if (v[i].ff > last)
      {
         for (int j = 0; j < l; j++)
         {
            res[v[i].ff + j] = s[j];
         }
         last = v[i].ss.ff;
      }
      else if (v[i].ff <= last && v[i].ss.ff > last)
      {
         int diff = last - v[i].ff + 1;
         for (int j = diff, cnt = 1; j < l; j++, cnt++)
         {
            res[last + cnt] = s[j];
         }
         last = v[i].ss.ff; //motherfucker
      }
      if (last == sz - 1)
         break;
   }
   for (int i = 1; i < sz; i++)
   {
      cout << char(tolower(res[i]));
   }
}
int main()
{
   ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
   pre();
   int test_cases = 1;
   // cin >> test_cases;
   for (int i = 1; i <= test_cases; i++)
   {
      solve(i);
   }
   return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define f(i, st, en, in) for (ll i = st; i <= en; i += in)
#define rf(i, st, en, de) for (ll i = st; i >= en; i -= de)
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define ff first
#define ss second
#define endl '\n'
#define all(something) something.begin(), something.end()
#define yes cout << "YES\n"
#define no cout << "NO\n"
#define ps(x) cout << x << " "
#define pl(x) cout << x << endl
#define nl cout << endl
using namespace std;
const int MAX = 1e7 + 9;
const ll mod = 1e9 + 7;
vector<bool> prime(MAX, 1);
vector<int> spf(MAX, 1);
vector<int> primes;
void sieve()
{
   prime[0] = prime[1] = 0;
   spf[2] = 2;
   f(i, 4, MAX - 1, 2)
   {
      spf[i] = 2;
      prime[i] = 0;
   }
   primes.pb(2);
   f(i, 3, MAX - 1, 2)
   {
      if (prime[i])
      {
         primes.pb(i);
         spf[i] = i;
         f(j, i * i, MAX - 1, i)
         {
            prime[j] = 0;
            if (spf[j] == 1)
            {
               spf[j] = i;
            }
         }
      }
   }
}
ll power(ll a, ll b)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = res * a;
      }
      a = a * a;
      b = b >> 1;
   }
   return res;
}
ll power(ll a, ll b, ll m)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = (res * a) % m;
      }
      a = (a * a) % m;
      b = b >> 1;
   }
   return res % m;
}
void pre()
{
#ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
#endif
}
void solve(int tc)
{
   // cout << "Case #" << tc << ": ";
   int n, sz = 0;
   cin >> n;
   vector<pair<int, pair<int, int>>> v;
   vector<string> st(n);
   string x;
   for (int i = 0; i < n; i++)
   {

      cin >> x;
      st[i] = x;
      int k, l = x.length();
      cin >> k;
      for (int j = 0; j < k; j++)
      {
         int f;
         cin >> f;
         v.pb({f, {f + l - 1, i}});
         sz = max(sz, f + l);
      }
      if (n == 1 && st[0].size() > 100)
      {
         cout << x.size() << " " << k << " " << sz << "\n";
         // return;
      }
   }
   vector<char> res(sz, 'a');
   sort(all(v));

   int last = 0, len = v.size();
   if (st[0].size() > 100 && n == 1)
   {
      cout << len;
      return;
   }
   for (int i = 0; i < len; i++)
   {
      string s = st[v[i].ss.ss];
      int l = s.length();
      int sta = v[i].ff, en = v[i].ss.ff;
      if (st[0].size() > 100 && n == 1)
      {
         continue;
      }
      if (sta > last)
      {
         if (n == 1 && st[0].size() > 100)
         {
            // cout << x.size() << " " << k << " " << sz << "\n";
            cout << l << " no overlap\n";
            last = en;
            continue;
            // return;
         }
         for (int j = 0; j < l; j++)
         {
            res[sta + j] = s[j];
         }
         last = en;
      }
      else if (sta <= last && en > last)
      {
         int diff = last - sta + 1;
         if (n == 1 && st[0].size() > 100)
         {
            // cout << x.size() << " " << k << " " << sz << "\n";
            cout << en - last << " overlap\n";
            last = en;
            continue;
            // return;
         }
         for (int j = diff, cnt = 1; j < l; j++, cnt++)
         {
            res[last + cnt] = s[j];
         }
         last = en; //motherfucker
      }
      if (last == sz - 1)
         break;
   }
   for (int i = 1; i < sz; i++)
   {
      cout << res[i];
   }
}
int main()
{
   ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
   pre();
   int test_cases = 1;
   // cin >> test_cases;
   for (int i = 1; i <= test_cases; i++)
   {
      solve(i);
   }
   return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define f(i, st, en, in) for (ll i = st; i <= en; i += in)
#define rf(i, st, en, de) for (ll i = st; i >= en; i -= de)
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define ff first
#define ss second
#define endl '\n'
#define all(something) something.begin(), something.end()
#define yes cout << "YES\n"
#define no cout << "NO\n"
#define ps(x) cout << x << " "
#define pl(x) cout << x << endl
#define nl cout << endl
using namespace std;
const int MAX = 1e7 + 9;
const ll mod = 1e9 + 7;
vector<bool> prime(MAX, 1);
vector<int> spf(MAX, 1);
vector<int> primes;
void sieve()
{
   prime[0] = prime[1] = 0;
   spf[2] = 2;
   f(i, 4, MAX - 1, 2)
   {
      spf[i] = 2;
      prime[i] = 0;
   }
   primes.pb(2);
   f(i, 3, MAX - 1, 2)
   {
      if (prime[i])
      {
         primes.pb(i);
         spf[i] = i;
         f(j, i * i, MAX - 1, i)
         {
            prime[j] = 0;
            if (spf[j] == 1)
            {
               spf[j] = i;
            }
         }
      }
   }
}
ll power(ll a, ll b)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = res * a;
      }
      a = a * a;
      b = b >> 1;
   }
   return res;
}
ll power(ll a, ll b, ll m)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = (res * a) % m;
      }
      a = (a * a) % m;
      b = b >> 1;
   }
   return res % m;
}
void pre()
{
#ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
#endif
}
void solve(int tc)
{
   // cout << "Case #" << tc << ": ";
   int n, sz = 0;
   cin >> n;
   vector<pair<int, pair<int, int>>> v;
   vector<string> st(n);
   for (int i = 0; i < n; i++)
   {
      string x;
      cin >> x;
      st[i] = x;
      int k, l = x.length();
      cin >> k;
      for (int j = 0; j < k; j++)
      {
         int f;
         cin >> f;
         v.pb({f, {f + l - 1, i}});
         sz = max(sz, f + l);
      }
   }
   sort(all(v));
   vector<char> res(sz, 'a');
   int last = 0, len = v.size();
   for (int i = 0; i < len; i++)
   {
      string s = st[v[i].ss.ss];
      int l = s.length();
      if (v[i].ff > last)
      {
         for (int j = 0; j < l; j++)
         {
            res[v[i].ff + j] = s[j];
         }
         last = v[i].ss.ff;
      }
      else if (v[i].ff <= last && v[i].ss.ff > last)
      {
         int diff = last - v[i].ff + 1;
         for (int j = diff, cnt = 1; j < l; j++, cnt++)
         {
            res[last + cnt] = s[j];
         }
         last = v[i].ss.ff; //motherfucker
      }
      if (last == sz - 1)
         break;
   }
   for (int i = 1; i < sz; i++)
   {
      cout << char(tolower(res[i]));
   }
}
int main()
{
   ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
   pre();
   int test_cases = 1;
   // cin >> test_cases;
   for (int i = 1; i <= test_cases; i++)
   {
      solve(i);
   }
   return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define f(i, st, en, in) for (ll i = st; i <= en; i += in)
#define rf(i, st, en, de) for (ll i = st; i >= en; i -= de)
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define ff first
#define ss second
#define endl '\n'
#define all(something) something.begin(), something.end()
#define yes cout << "YES\n"
#define no cout << "NO\n"
#define ps(x) cout << x << " "
#define pl(x) cout << x << endl
#define nl cout << endl
using namespace std;
const int MAX = 1e6 + 9;
const ll mod = 1e9 + 7;
vector<bool> prime(MAX, 1);
vector<int> spf(MAX, 1);
vector<int> primes;
void sieve()
{
   prime[0] = prime[1] = 0;
   spf[2] = 2;
   f(i, 4, MAX - 1, 2)
   {
      spf[i] = 2;
      prime[i] = 0;
   }
   primes.pb(2);
   f(i, 3, MAX - 1, 2)
   {
      if (prime[i])
      {
         primes.pb(i);
         spf[i] = i;
         f(j, i * i, MAX - 1, i)
         {
            prime[j] = 0;
            if (spf[j] == 1)
            {
               spf[j] = i;
            }
         }
      }
   }
}
ll power(ll a, ll b)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = res * a;
      }
      a = a * a;
      b = b >> 1;
   }
   return res;
}
ll power(ll a, ll b, ll m)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = (res * a) % m;
      }
      a = (a * a) % m;
      b = b >> 1;
   }
   return res % m;
}
void pre()
{
#ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
#endif
}
vector<char> res(MAX, 'A');
void solve(int tc)
{
   // cout << "Case #" << tc << ": ";
   int n, sz = 0;
   cin >> n;
   vector<pair<int, pair<int, string>>> v;
   for (int i = 0; i < n; i++)
   {
      string x;
      cin >> x;
      int k, l = x.length();
      cin >> k;
      for (int j = 0; j < k; j++)
      {
         int f;
         cin >> f;
         v.pb({f, {f + l - 1, x}});
         sz = max(sz, f + l);
      }
   }
   sort(all(v));

   int last = 0;
   for (int i = 0; i < v.size(); i++)
   {
      string s = v[i].ss.ss;
      int l = s.length();
      if (v[i].ff > last)
      {
         for (int j = 0; j < l; j++)
         {
            res[v[i].ff + j] = s[j];
         }
         last = v[i].ss.ff;
      }
      else if (v[i].ff <= last && v[i].ss.ff > last)
      {
         int diff = last - v[i].ff + 1;
         for (int j = diff, cnt = 1; j < l; j++, cnt++)
         {
            res[last + cnt] = s[j];
         }
      }
   }
   for (int i = 1; i < sz; i++)
   {
      cout << char(tolower(res[i]));
   }
}
int main()
{
   ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
   pre();
   int test_cases = 1;
   // cin >> test_cases;
   for (int i = 1; i <= test_cases; i++)
   {
      solve(i);
   }
   return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define f(i, st, en, in) for (ll i = st; i <= en; i += in)
#define rf(i, st, en, de) for (ll i = st; i >= en; i -= de)
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define ff first
#define ss second
#define endl '\n'
#define all(something) something.begin(), something.end()
#define yes cout << "YES\n"
#define no cout << "NO\n"
#define ps(x) cout << x << " "
#define pl(x) cout << x << endl
#define nl cout << endl
using namespace std;
const int MAX = 1e7 + 9;
const ll mod = 1e9 + 7;
vector<bool> prime(MAX, 1);
vector<int> spf(MAX, 1);
vector<int> primes;
void sieve()
{
   prime[0] = prime[1] = 0;
   spf[2] = 2;
   f(i, 4, MAX - 1, 2)
   {
      spf[i] = 2;
      prime[i] = 0;
   }
   primes.pb(2);
   f(i, 3, MAX - 1, 2)
   {
      if (prime[i])
      {
         primes.pb(i);
         spf[i] = i;
         f(j, i * i, MAX - 1, i)
         {
            prime[j] = 0;
            if (spf[j] == 1)
            {
               spf[j] = i;
            }
         }
      }
   }
}
ll power(ll a, ll b)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = res * a;
      }
      a = a * a;
      b = b >> 1;
   }
   return res;
}
ll power(ll a, ll b, ll m)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = (res * a) % m;
      }
      a = (a * a) % m;
      b = b >> 1;
   }
   return res % m;
}
void pre()
{
#ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
#endif
}
void solve(int tc)
{
   // cout << "Case #" << tc << ": ";
   int n, sz = 0;
   cin >> n;
   vector<pair<int, pair<int, int>>> v;
   vector<string> st(n);
   string x;
   for (int i = 0; i < n; i++)
   {

      cin >> x;
      st[i] = x;
      int k, l = x.length();
      cin >> k;
      for (int j = 0; j < k; j++)
      {
         int f;
         cin >> f;
         v.pb({f, {f + l - 1, i}});
         sz = max(sz, f + l);
      }
   }
   vector<char> res(sz, 'a');
   if (n == 1 && st[0].size() > 100)
   {
      // for (int i = 1; i < sz; i++)
      // {
      //    cout << res[i];
      // }
      cout << st[0].size() << "\n";
      return;
   }
   sort(all(v));

   int last = 0, len = v.size();
   for (int i = 0; i < len; i++)
   {
      string s = st[v[i].ss.ss];
      int l = s.length();
      if (v[i].ff > last)
      {
         for (int j = 0; j < l; j++)
         {
            res[v[i].ff + j] = s[j];
         }
         last = v[i].ss.ff;
      }
      else if (v[i].ff <= last && v[i].ss.ff > last)
      {
         int diff = last - v[i].ff + 1;
         for (int j = diff, cnt = 1; j < l; j++, cnt++)
         {
            res[last + cnt] = s[j];
         }
         last = v[i].ss.ff; //motherfucker
      }
      if (last == sz - 1)
         break;
   }
   for (int i = 1; i < sz; i++)
   {
      cout << char(tolower(res[i]));
   }
}
int main()
{
   ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
   pre();
   int test_cases = 1;
   // cin >> test_cases;
   for (int i = 1; i <= test_cases; i++)
   {
      solve(i);
   }
   return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define f(i, st, en, in) for (ll i = st; i <= en; i += in)
#define rf(i, st, en, de) for (ll i = st; i >= en; i -= de)
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define ff first
#define ss second
#define endl '\n'
#define all(something) something.begin(), something.end()
#define yes cout << "YES\n"
#define no cout << "NO\n"
#define ps(x) cout << x << " "
#define pl(x) cout << x << endl
#define nl cout << endl
using namespace std;
const int MAX = 1e7 + 9;
const ll mod = 1e9 + 7;
vector<bool> prime(MAX, 1);
vector<int> spf(MAX, 1);
vector<int> primes;
void sieve()
{
   prime[0] = prime[1] = 0;
   spf[2] = 2;
   f(i, 4, MAX - 1, 2)
   {
      spf[i] = 2;
      prime[i] = 0;
   }
   primes.pb(2);
   f(i, 3, MAX - 1, 2)
   {
      if (prime[i])
      {
         primes.pb(i);
         spf[i] = i;
         f(j, i * i, MAX - 1, i)
         {
            prime[j] = 0;
            if (spf[j] == 1)
            {
               spf[j] = i;
            }
         }
      }
   }
}
ll power(ll a, ll b)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = res * a;
      }
      a = a * a;
      b = b >> 1;
   }
   return res;
}
ll power(ll a, ll b, ll m)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = (res * a) % m;
      }
      a = (a * a) % m;
      b = b >> 1;
   }
   return res % m;
}
void pre()
{
#ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
#endif
}
void solve()
{
   // cout << "Case #" << tc << ": ";
   int n, sz = 0;
   cin >> n;
   vector<pair<int, int>> v;
   vector<string> st(n);
   string x;
   for (int i = 0; i < n; i++)
   {

      cin >> st[i];
      int k, l = st[i].length();
      cin >> k;
      for (int j = 0; j < k; j++)
      {
         int f;
         cin >> f;
         v.pb({f, i});
         sz = max(sz, f + l);
      }
   }
   vector<char> res(sz, 'a');
   sort(all(v));
   vector<int> idx(sz, -1);
   idx[v[0].ff] = v[0].ss;
   int last = v[0].ff + st[v[0].ss].length() - 1, len = v.size();
   for (int i = 1; i < len; i++)
   {
      string s = st[v[i].ss];
      if (v[i].ff + s.length() - 1 > last)
      {
         idx[v[i].ff] = v[i].ss;
         last = v[i].ff + s.length() - 1;
      }
   }
   // for (int i = 1; i < sz; i++)
   // {
   //    cout << idx[i] << " ";
   // }
   // nl;
   for (int i = 1; i < sz; i++)
   {
      if (idx[i] != -1)
      {
         string x = st[idx[i]];
         idx[i] = -1;
         int l = x.size();
         for (int j = 0; j < l; j++, i++)
         {
            if (idx[i] == -1)
               res[i] = x[j];
            else
            {
               i--;
               break;
            }
         }
         i--;
      }
   }
   for (int i = 1; i < sz; i++)
   {
      cout << res[i];
   }
}
int main()
{
   ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
   pre();
   int test_cases = 1;
   // cin >> test_cases;
   for (int i = 1; i <= test_cases; i++)
   {
      solve();
   }
   return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define f(i, st, en, in) for (ll i = st; i <= en; i += in)
#define rf(i, st, en, de) for (ll i = st; i >= en; i -= de)
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define ff first
#define ss second
#define endl '\n'
#define all(something) something.begin(), something.end()
#define yes cout << "YES\n"
#define no cout << "NO\n"
#define ps(x) cout << x << " "
#define pl(x) cout << x << endl
#define nl cout << endl
using namespace std;
const int MAX = 1e7 + 9;
const ll mod = 1e9 + 7;
vector<bool> prime(MAX, 1);
vector<int> spf(MAX, 1);
vector<int> primes;
void sieve()
{
   prime[0] = prime[1] = 0;
   spf[2] = 2;
   f(i, 4, MAX - 1, 2)
   {
      spf[i] = 2;
      prime[i] = 0;
   }
   primes.pb(2);
   f(i, 3, MAX - 1, 2)
   {
      if (prime[i])
      {
         primes.pb(i);
         spf[i] = i;
         f(j, i * i, MAX - 1, i)
         {
            prime[j] = 0;
            if (spf[j] == 1)
            {
               spf[j] = i;
            }
         }
      }
   }
}
ll power(ll a, ll b)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = res * a;
      }
      a = a * a;
      b = b >> 1;
   }
   return res;
}
ll power(ll a, ll b, ll m)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = (res * a) % m;
      }
      a = (a * a) % m;
      b = b >> 1;
   }
   return res % m;
}
void pre()
{
#ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
#endif
}
void solve(int tc)
{
   // cout << "Case #" << tc << ": ";
   int n, sz = 0;
   cin >> n;
   vector<pair<int, pair<int, int>>> v;
   vector<string> st(n);
   string x;
   for (int i = 0; i < n; i++)
   {

      cin >> x;
      st[i] = x;
      int k, l = x.length();
      cin >> k;
      for (int j = 0; j < k; j++)
      {
         int f;
         cin >> f;
         v.pb({f, {f + l - 1, i}});
         sz = max(sz, f + l);
      }
      if (n == 1 && st[0].size() > 100)
      {
         cout << x.size() << " " << k << " " << sz << "\n";
         // return;
      }
   }
   vector<char> res(sz, 'a');
   sort(all(v));

   int last = 0, len = v.size();
   for (int i = 0; i < len; i++)
   {
      string s = st[v[i].ss.ss];
      int l = s.length();
      int sta = v[i].ff, en = v[i].ss.ff;
      if (sta > last)
      {
         if (n == 1 && st[0].size() > 100)
         {
            // cout << x.size() << " " << k << " " << sz << "\n";
            cout << last << "\n";
            continue;
            // return;
         }
         for (int j = 0; j < l; j++)
         {
            res[sta + j] = s[j];
         }
         last = en;
      }
      else if (sta <= last && en > last)
      {
         int diff = last - sta + 1;
         if (n == 1 && st[0].size() > 100)
         {
            // cout << x.size() << " " << k << " " << sz << "\n";
            cout << last << "\n";
            continue;
            // return;
         }
         for (int j = diff, cnt = 1; j < l; j++, cnt++)
         {
            res[last + cnt] = s[j];
         }
         last = en; //motherfucker
      }
      if (last == sz - 1)
         break;
   }
   for (int i = 1; i < sz; i++)
   {
      cout << res[i];
   }
}
int main()
{
   ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
   pre();
   int test_cases = 1;
   // cin >> test_cases;
   for (int i = 1; i <= test_cases; i++)
   {
      solve(i);
   }
   return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define f(i, st, en, in) for (ll i = st; i <= en; i += in)
#define rf(i, st, en, de) for (ll i = st; i >= en; i -= de)
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define ff first
#define ss second
#define endl '\n'
#define all(something) something.begin(), something.end()
#define yes cout << "YES\n"
#define no cout << "NO\n"
#define ps(x) cout << x << " "
#define pl(x) cout << x << endl
#define nl cout << endl
using namespace std;
const int MAX = 1e7 + 9;
const ll mod = 1e9 + 7;
vector<bool> prime(MAX, 1);
vector<int> spf(MAX, 1);
vector<int> primes;
void sieve()
{
   prime[0] = prime[1] = 0;
   spf[2] = 2;
   f(i, 4, MAX - 1, 2)
   {
      spf[i] = 2;
      prime[i] = 0;
   }
   primes.pb(2);
   f(i, 3, MAX - 1, 2)
   {
      if (prime[i])
      {
         primes.pb(i);
         spf[i] = i;
         f(j, i * i, MAX - 1, i)
         {
            prime[j] = 0;
            if (spf[j] == 1)
            {
               spf[j] = i;
            }
         }
      }
   }
}
ll power(ll a, ll b)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = res * a;
      }
      a = a * a;
      b = b >> 1;
   }
   return res;
}
ll power(ll a, ll b, ll m)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = (res * a) % m;
      }
      a = (a * a) % m;
      b = b >> 1;
   }
   return res % m;
}
void pre()
{
#ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
#endif
}
void solve(int tc)
{
   // cout << "Case #" << tc << ": ";
   int n, sz = 0;
   cin >> n;
   vector<pair<int, pair<int, int>>> v;
   vector<string> st(n);
   string x;
   for (int i = 0; i < n; i++)
   {

      cin >> x;
      st[i] = x;
      int k, l = x.length();
      cin >> k;
      for (int j = 0; j < k; j++)
      {
         int f;
         cin >> f;
         v.pb({f, {f + l - 1, i}});
         sz = max(sz, f + l);
      }
      if (n == 1 && st[0].size() > 100)
      {
         cout << x.size() << " " << k << " " << sz << "\n";
         // return;
      }
   }
   vector<char> res(sz, 'a');
   sort(all(v));

   int last = 0, len = v.size();
   for (int i = 0; i < len; i++)
   {
      string s = st[v[i].ss.ss];
      int l = s.length();
      int sta = v[i].ff, en = v[i].ss.ff;
      if (st[0].size() > 100 && n == 1)
      {
         continue;
      }
      if (sta > last)
      {
         if (n == 1 && st[0].size() > 100)
         {
            // cout << x.size() << " " << k << " " << sz << "\n";
            cout << l << " no overlap\n";
            last = en;
            continue;
            // return;
         }
         for (int j = 0; j < l; j++)
         {
            res[sta + j] = s[j];
         }
         last = en;
      }
      else if (sta <= last && en > last)
      {
         int diff = last - sta + 1;
         if (n == 1 && st[0].size() > 100)
         {
            // cout << x.size() << " " << k << " " << sz << "\n";
            cout << en - last << " overlap\n";
            last = en;
            continue;
            // return;
         }
         for (int j = diff, cnt = 1; j < l; j++, cnt++)
         {
            res[last + cnt] = s[j];
         }
         last = en; //motherfucker
      }
      if (last == sz - 1)
         break;
   }
   for (int i = 1; i < sz; i++)
   {
      cout << res[i];
   }
}
int main()
{
   ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
   pre();
   int test_cases = 1;
   // cin >> test_cases;
   for (int i = 1; i <= test_cases; i++)
   {
      solve(i);
   }
   return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define f(i, st, en, in) for (ll i = st; i <= en; i += in)
#define rf(i, st, en, de) for (ll i = st; i >= en; i -= de)
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define ff first
#define ss second
#define endl '\n'
#define all(something) something.begin(), something.end()
#define yes cout << "YES\n"
#define no cout << "NO\n"
#define ps(x) cout << x << " "
#define pl(x) cout << x << endl
#define nl cout << endl
using namespace std;
const int MAX = 1e7 + 9;
const ll mod = 1e9 + 7;
vector<bool> prime(MAX, 1);
vector<int> spf(MAX, 1);
vector<int> primes;
void sieve()
{
   prime[0] = prime[1] = 0;
   spf[2] = 2;
   f(i, 4, MAX - 1, 2)
   {
      spf[i] = 2;
      prime[i] = 0;
   }
   primes.pb(2);
   f(i, 3, MAX - 1, 2)
   {
      if (prime[i])
      {
         primes.pb(i);
         spf[i] = i;
         f(j, i * i, MAX - 1, i)
         {
            prime[j] = 0;
            if (spf[j] == 1)
            {
               spf[j] = i;
            }
         }
      }
   }
}
ll power(ll a, ll b)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = res * a;
      }
      a = a * a;
      b = b >> 1;
   }
   return res;
}
ll power(ll a, ll b, ll m)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = (res * a) % m;
      }
      a = (a * a) % m;
      b = b >> 1;
   }
   return res % m;
}
void pre()
{
#ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
#endif
}
void solve(int tc)
{
   // cout << "Case #" << tc << ": ";
   int n, sz = 0;
   cin >> n;
   vector<pair<int, pair<int, int>>> v;
   vector<string> st(n);
   string x;
   for (int i = 0; i < n; i++)
   {

      cin >> x;
      st[i] = x;
      int k, l = x.length();
      cin >> k;
      for (int j = 0; j < k; j++)
      {
         int f;
         cin >> f;
         v.pb({f, {f + l - 1, i}});
         sz = max(sz, f + l);
      }
      if (n == 1 && x.size() > 100)
      {
         cout << k << "\n";
         return;
      }
   }
   vector<char> res(sz, 'a');
   sort(all(v));

   int last = 0, len = v.size();
   for (int i = 0; i < len; i++)
   {
      string s = st[v[i].ss.ss];
      int l = s.length();
      if (v[i].ff > last)
      {
         for (int j = 0; j < l; j++)
         {
            res[v[i].ff + j] = s[j];
         }
         last = v[i].ss.ff;
      }
      else if (v[i].ff <= last && v[i].ss.ff > last)
      {
         int diff = last - v[i].ff + 1;
         for (int j = diff, cnt = 1; j < l; j++, cnt++)
         {
            res[last + cnt] = s[j];
         }
         last = v[i].ss.ff; //motherfucker
      }
      if (last == sz - 1)
         break;
   }
   for (int i = 1; i < sz; i++)
   {
      cout << char(tolower(res[i]));
   }
}
int main()
{
   ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
   pre();
   int test_cases = 1;
   // cin >> test_cases;
   for (int i = 1; i <= test_cases; i++)
   {
      solve(i);
   }
   return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define f(i, st, en, in) for (ll i = st; i <= en; i += in)
#define rf(i, st, en, de) for (ll i = st; i >= en; i -= de)
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define ff first
#define ss second
#define endl '\n'
#define all(something) something.begin(), something.end()
#define yes cout << "YES\n"
#define no cout << "NO\n"
#define ps(x) cout << x << " "
#define pl(x) cout << x << endl
#define nl cout << endl
using namespace std;
const int MAX = 1e7 + 9;
const ll mod = 1e9 + 7;
vector<bool> prime(MAX, 1);
vector<int> spf(MAX, 1);
vector<int> primes;
void sieve()
{
   prime[0] = prime[1] = 0;
   spf[2] = 2;
   f(i, 4, MAX - 1, 2)
   {
      spf[i] = 2;
      prime[i] = 0;
   }
   primes.pb(2);
   f(i, 3, MAX - 1, 2)
   {
      if (prime[i])
      {
         primes.pb(i);
         spf[i] = i;
         f(j, i * i, MAX - 1, i)
         {
            prime[j] = 0;
            if (spf[j] == 1)
            {
               spf[j] = i;
            }
         }
      }
   }
}
ll power(ll a, ll b)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = res * a;
      }
      a = a * a;
      b = b >> 1;
   }
   return res;
}
ll power(ll a, ll b, ll m)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = (res * a) % m;
      }
      a = (a * a) % m;
      b = b >> 1;
   }
   return res % m;
}
void pre()
{
#ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
#endif
}
void solve(int tc)
{
   // cout << "Case #" << tc << ": ";
   int n, sz = 0;
   cin >> n;
   vector<pair<int, pair<int, int>>> v;
   vector<string> st(n);
   string x;
   for (int i = 0; i < n; i++)
   {

      cin >> x;
      st[i] = x;
      int k, l = x.length();
      cin >> k;
      for (int j = 0; j < k; j++)
      {
         int f;
         cin >> f;
         v.pb({f, {f + l - 1, i}});
         sz = max(sz, f + l);
      }
      if (n == 1 && x.size() > 100)
      {
         cout << x.size() << " " << k << " " << sz << "\n";
         return;
      }
   }
   vector<char> res(sz, 'a');
   sort(all(v));

   int last = 0, len = v.size();
   for (int i = 0; i < len; i++)
   {
      string s = st[v[i].ss.ss];
      int l = s.length();
      if (v[i].ff > last)
      {
         for (int j = 0; j < l; j++)
         {
            res[v[i].ff + j] = s[j];
         }
         last = v[i].ss.ff;
      }
      else if (v[i].ff <= last && v[i].ss.ff > last)
      {
         int diff = last - v[i].ff + 1;
         for (int j = diff, cnt = 1; j < l; j++, cnt++)
         {
            res[last + cnt] = s[j];
         }
         last = v[i].ss.ff; //motherfucker
      }
      if (last == sz - 1)
         break;
   }
   for (int i = 1; i < sz; i++)
   {
      cout << char(tolower(res[i]));
   }
}
int main()
{
   ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
   pre();
   int test_cases = 1;
   // cin >> test_cases;
   for (int i = 1; i <= test_cases; i++)
   {
      solve(i);
   }
   return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define f(i, st, en, in) for (ll i = st; i <= en; i += in)
#define rf(i, st, en, de) for (ll i = st; i >= en; i -= de)
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define mp make_pair
#define ff first
#define ss second
#define endl '\n'
#define all(something) something.begin(), something.end()
#define yes cout << "YES\n"
#define no cout << "NO\n"
#define ps(x) cout << x << " "
#define pl(x) cout << x << endl
#define nl cout << endl
using namespace std;
const int MAX = 1e7 + 9;
const ll mod = 1e9 + 7;
vector<bool> prime(MAX, 1);
vector<int> spf(MAX, 1);
vector<int> primes;
void sieve()
{
   prime[0] = prime[1] = 0;
   spf[2] = 2;
   f(i, 4, MAX - 1, 2)
   {
      spf[i] = 2;
      prime[i] = 0;
   }
   primes.pb(2);
   f(i, 3, MAX - 1, 2)
   {
      if (prime[i])
      {
         primes.pb(i);
         spf[i] = i;
         f(j, i * i, MAX - 1, i)
         {
            prime[j] = 0;
            if (spf[j] == 1)
            {
               spf[j] = i;
            }
         }
      }
   }
}
ll power(ll a, ll b)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = res * a;
      }
      a = a * a;
      b = b >> 1;
   }
   return res;
}
ll power(ll a, ll b, ll m)
{
   ll res = 1;
   while (b)
   {
      if (b & 1)
      {
         res = (res * a) % m;
      }
      a = (a * a) % m;
      b = b >> 1;
   }
   return res % m;
}
void pre()
{
#ifndef ONLINE_JUDGE
   freopen("input.txt", "r", stdin);
   freopen("output.txt", "w", stdout);
#endif
}
void solve(int tc)
{
   // cout << "Case #" << tc << ": ";
   int n, sz = 0;
   cin >> n;
   vector<pair<int, pair<int, int>>> v;
   vector<string> st(n);
   string x;
   for (int i = 0; i < n; i++)
   {

      cin >> x;
      st[i] = x;
      int k, l = x.length();
      cin >> k;
      for (int j = 0; j < k; j++)
      {
         int f;
         cin >> f;
         v.pb({f, {f + l - 1, i}});
         sz = max(sz, f + l);
      }
      if (n == 1 && st[0].size() > 100)
      {
         cout << x.size() << " " << k << " " << sz << "\n";
         // return;
      }
   }
   vector<char> res(sz, 'a');
   sort(all(v));

   int last = 0, len = v.size();
   for (int i = 0; i < len; i++)
   {
      string s = st[v[i].ss.ss];
      int l = s.length();
      int sta = v[i].ff, en = v[i].ss.ff;
      if (sta > last)
      {
         if (n == 1 && st[0].size() > 100)
         {
            // cout << x.size() << " " << k << " " << sz << "\n";
            cout << l << " no overlap\n";
            last = en;
            continue;
            // return;
         }
         for (int j = 0; j < l; j++)
         {
            res[sta + j] = s[j];
         }
         last = en;
      }
      else if (sta <= last && en > last)
      {
         int diff = last - sta + 1;
         if (n == 1 && st[0].size() > 100)
         {
            // cout << x.size() << " " << k << " " << sz << "\n";
            cout << en - last << " overlap\n";
            last = en;
            continue;
            // return;
         }
         for (int j = diff, cnt = 1; j < l; j++, cnt++)
         {
            res[last + cnt] = s[j];
         }
         last = en; //motherfucker
      }
      if (last == sz - 1)
         break;
   }
   for (int i = 1; i < sz; i++)
   {
      cout << res[i];
   }
}
int main()
{
   ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
   pre();
   int test_cases = 1;
   // cin >> test_cases;
   for (int i = 1; i <= test_cases; i++)
   {
      solve(i);
   }
   return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse2")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define int               long long
#define float             long double
#define pb                push_back
#define ppb               pop_back
#define lb                lower_bound
#define ub                upper_bound
#define mii               map<int,int>
#define pii               pair<int,int>
#define vi                vector<int>
#define vvi               vector<vector<int>>
#define all(x)            (x).begin(),(x).end()
#define mod               1000000007
#define hell              998244353
#define fr                first
#define sc                second
#define rep(i,a,b)        for(int i=a;i<b;i++)
#define mem1(a)           memset(a,-1,sizeof(a))
#define mem0(a)           memset(a,0,sizeof(a))
#define INF               1000000
#define ordered_set tree<pii, null_type,less<pii>, rb_tree_tag,tree_order_statistics_node_update>

int solve()
{
	int n;cin>>n;
	map<int,string>s;
	while(n--)
	{
		string str;cin>>str;
		int k;cin>>k;
		while(k--)
		{
			int x;cin>>x;
			if(str.length()>s[x].length())
			s[x]=str;
		}
	}
	string ans="";
	int len=0,p=1;

	for(auto i:s)
	{
		while(ans.length()<i.fr-1)
		ans+='a';

		for(int j=(int)ans.length()-i.fr+1;j<i.sc.length();j++)
			ans+=i.sc[j];
	}
	cout<<ans;
}

signed main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
	#ifdef SEIVE
		seive();
	#endif
	#ifdef NCR
		init();
	#endif

	int t=1;
//	cin>>t;
	while(t--)
	solve();
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e5+5;

map<string,set<int>>mp;
int solve()
{
    int i,n,ma=0;cin>>n;
    set<pair<int,string>>s;
    for(i=0;i<n;i++)
    {
    	string str;cin>>str;
    	int k;cin>>k;
    	while(k--)
    	{
    		int x;cin>>x;
    		mp[str].insert(x);
    		ma=max(ma,(int)str.length()+x-1);
		}
		s.insert({str.length(),str});
    }
    string ans;
//    cout<<ma<<"\n\n";
    ans.assign(ma+1,'0');
//    cout<<ans<<"\n";

    set<int>fuck;
    for(int i=1;i<=ma;i++)
    fuck.insert(i);

    for(auto it=s.rbegin();it!=s.rend();it++)
    {
    	for(auto j:mp[(*it).second])
    	{
    		vector<int>era;
    		auto k=fuck.lower_bound(j);
//    		cout<<j<<"  "<<*k<<"     ";
    		while(((*k)<=j+it->first-1)&&(k!=fuck.end()))
    		{
    			ans[*k]=(*it).second[*k-j];
    			era.push_back(*k);
    			k++;
			}
//
			for(auto z:era)
			fuck.erase(z);
//			cout<<"\n";
		}
	}
	for(int i=1;i<=ma;i++)
	if(ans[i]=='0')
	ans[i]='a';

    cout<<ans.substr(1);

}

signed main()
{
	cin.tie(0);
	cout.tie(0);
	ios_base::sync_with_stdio(0);
	int t=1;
//	cin>>t;
	while(t--)
	solve();
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse2")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define int               long long
#define float             long double
#define pb                push_back
#define ppb               pop_back
#define lb                lower_bound
#define ub                upper_bound
#define mii               map<int,int>
#define pii               pair<int,int>
#define vi                vector<int>
#define vvi               vector<vector<int>>
#define all(x)            (x).begin(),(x).end()
#define mod               1000000007
#define hell              998244353
#define fr                first
#define sc                second
#define rep(i,a,b)        for(int i=a;i<b;i++)
#define mem1(a)           memset(a,-1,sizeof(a))
#define mem0(a)           memset(a,0,sizeof(a))
#define INF               1000000
#define ordered_set tree<pii, null_type,less<pii>, rb_tree_tag,tree_order_statistics_node_update>

int solve()
{
	int n;cin>>n;
	set<pair<int,string>>s;
	while(n--)
	{
		string str;cin>>str;
		int k;cin>>k;
		while(k--)
		{
			int x;cin>>x;
			s.insert({x,str});
		}
	}
	string ans="";
	int len=0,p=1;

	for(auto i:s)
	{
		while(ans.length()<i.fr-1)
		ans+='a';

		for(int j=(int)ans.length()-i.fr+1;j<i.sc.length();j++)
			ans+=i.sc[j];
	}
	cout<<ans;
}

signed main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
	#ifdef SEIVE
		seive();
	#endif
	#ifdef NCR
		init();
	#endif

	int t=1;
//	cin>>t;
	while(t--)
	solve();
	return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse2")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define int               long long
#define float             long double
#define pb                push_back
#define ppb               pop_back
#define lb                lower_bound
#define ub                upper_bound
#define mii               map<int,int>
#define pii               pair<int,int>
#define vi                vector<int>
#define vvi               vector<vector<int>>
#define all(x)            (x).begin(),(x).end()
#define mod               1000000007
#define hell              998244353
#define fr                first
#define sc                second
#define rep(i,a,b)        for(int i=a;i<b;i++)
#define mem1(a)           memset(a,-1,sizeof(a))
#define mem0(a)           memset(a,0,sizeof(a))
#define INF               1000000
#define ordered_set tree<pii, null_type,less<pii>, rb_tree_tag,tree_order_statistics_node_update>
map<int,string>s;

int solve()
{
	int n,i;cin>>n;
	string str[n];
	int    len[n];
	set<pair<pair<int,int>,int>>s;

	for(i=0;i<n;i++)
	{
		cin>>str[i];
		len[i]=str[i].length();
		int k;cin>>k;
		while(k--)
		{
			int x;cin>>x;
			vector<pair<pair<int,int>,int>>vec;
			auto p=s.lb({{x,len[i]},i});
			while((p!=s.end())&&((*p).fr.fr+(*p).fr.sc<=x+len[i]))
			vec.pb(*p),p++;

			for(auto k:vec)
			s.erase(k);
			s.insert({{x,len[i]},i});
		}
	}
	string ans="";

	for(auto i:s)
	{
		while(ans.length()<i.fr.fr-1)
		ans+='a';

		for(int j=(int)ans.length()-i.fr.fr+1;j<i.fr.sc;j++)
			ans+=str[i.sc][j];
	}
	cout<<ans;
}

signed main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
	#ifdef SEIVE
		seive();
	#endif
	#ifdef NCR
		init();
	#endif

	int t=1;
//	cin>>t;
	while(t--)
	solve();
	return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse2")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define int               long long
#define float             long double
#define pb                push_back
#define ppb               pop_back
#define lb                lower_bound
#define ub                upper_bound
#define mii               map<int,int>
#define pii               pair<int,int>
#define vi                vector<int>
#define vvi               vector<vector<int>>
#define all(x)            (x).begin(),(x).end()
#define mod               1000000007
#define hell              998244353
#define fr                first
#define sc                second
#define rep(i,a,b)        for(int i=a;i<b;i++)
#define mem1(a)           memset(a,-1,sizeof(a))
#define mem0(a)           memset(a,0,sizeof(a))
#define INF               1000000
#define ordered_set tree<pii, null_type,less<pii>, rb_tree_tag,tree_order_statistics_node_update>
map<int,string>s;

int solve()
{
	int n;cin>>n;

	while(n--)
	{
		string str;cin>>str;
		int k;cin>>k;
		while(k--)
		{
			int x;cin>>x;
			if(str.length()>s[x].length())
			s[x]=str;
		}
	}
	string ans="";

	for(auto i:s)
	{
		while(ans.length()<i.fr-1)
		ans+='a';

		for(int j=(int)ans.length()-i.fr+1;j<i.sc.length();j++)
			ans+=i.sc[j];
	}
	cout<<ans;
}

signed main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
//	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);
	#ifdef SEIVE
		seive();
	#endif
	#ifdef NCR
		init();
	#endif

	int t=1;
//	cin>>t;
	while(t--)
	solve();
	return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pb push_back
#define mp make_pair
#define all(a) begin(a),end(a)
#define FOR(x,val,to) for(int x=(val);x<int((to));++x)
#define FORE(x,val,to) for(auto x=(val);x<=(to);++x)
#define FORR(x,arr) for(auto &x: arr)
#define FORS(x,plus,arr) for(auto x = begin(arr)+(plus); x != end(arr); ++x)
#define FORREV(x,plus,arr) for(auto x = (arr).rbegin()+(plus); x !=(arr).rend(); ++x)
#define REE(s_) {cout<<s_<<'\n';exit(0);}
#define GET(arr) for(auto &i: (arr)) sc(i)
#define whatis(x) cerr << #x << " is " << (x) << endl;
#define e1 first
#define e2 second
#define INF 0x7f7f7f7f
typedef std::pair<int,int> pi;
typedef std::vector<int> vi;
typedef std::vector<std::string> vs;
typedef int64_t ll;
typedef uint64_t ull;
#define umap unordered_map
#define uset unordered_set
using namespace std;
using namespace __gnu_pbds;

#ifdef _WIN32
#define getchar_unlocked() _getchar_nolock()
#define _CRT_DISABLE_PERFCRIT_LOCKS
#endif
template<class L, class R> ostream& operator<<(ostream &os, map<L, R> P) { for(auto const &vv: P)os<<"("<<vv.first<<","<<vv.second<<")"; return os; }
template<class T> ostream& operator<<(ostream &os, set<T> V) { os<<"[";for(auto const &vv:V)os<<vv<<","; os<<"]"; return os; }
template<class T> ostream& operator<<(ostream &os, vector<T> V) { os<<"[";for(auto const &vv:V)os<<vv<<","; os<<"]"; return os; }
template<class L, class R> ostream& operator<<(ostream &os, pair<L, R> P) { os<<"("<<P.first<<","<<P.second<<")"; return os; }
inline int fstoi(const string &str){auto it=str.begin();bool neg=0;int num=0;if(*it=='-')neg=1;else num=*it-'0';++it;while(it<str.end()) num=num*10+(*it++-'0');if(neg)num*=-1;return num;}
inline void getch(char &x){while(x = getchar_unlocked(), x < 33){;}}
inline void getstr(string &str){str.clear(); char cur;while(cur=getchar_unlocked(),cur<33){;}while(cur>32){str+=cur;cur=getchar_unlocked();}}
template<typename T> inline bool sc(T &num){ bool neg=0; int c; num=0; while(c=getchar_unlocked(),c<33){if(c == EOF) return false;} if(c=='-'){ neg=1; c=getchar_unlocked(); } for(;c>47;c=getchar_unlocked()) num=num*10+c-48; if(neg) num*=-1; return true;}template<typename T, typename ...Args> inline void sc(T &num, Args &...args){ bool neg=0; int c; num=0; while(c=getchar_unlocked(),c<33){;} if(c=='-'){ neg=1; c=getchar_unlocked(); } for(;c>47;c=getchar_unlocked()) num=num*10+c-48; if(neg) num*=-1; sc(args...); }
template<typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; //s.find_by_order(), s.order_of_key() <- works like lower_bound
template<typename T> using ordered_map = tree<T, int, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define N 2100000

/* int t[N << 2]; */
/* int n = N-1; */
int ans[N];

/* int query(int v, int l, int r, int tl, int tr){ //all inclusive */
/*     if(v >= n) */
/*         return v-n; */
/*     int tm = (tl+tr) >> 1; */
/*     if((t[v << 1] < t[v << 1|1] && l <= tm) || tm+1 > r) */
/*         return query(v << 1,l,min(r,tm),tl,tm); */
/*     return query(v << 1|1,max(l,tm+1),r,tm+1,tr); */
/* } */
/* void build(ll v, ll tl, ll tr){ */
/*     if(tl == tr){ */
/*         ans[tl] = t[v]; */
/*         return; */
/*     } */
/*     ll tm = (tl+tr)>>1; */
/*     build(v<<1,tl,tm); */
/*     build(v<<1|1,tm+1,tr); */
/*     /1* t[v] = min(t[v<<1] , t[v<<1|1]); *1/ */
/* } */
/* void modify(int v, int tl, int tr, int pos, int val){ */
/*     if(tl == tr){ */
/*         t[v] = val; */
/*         return; */
/*     } */
/*     int tm = (tl+tr)/2; */
/*     if(pos <= tm) */
/*         modify(v*2,tl,tm,pos,val); */
/*     else */
/*         modify(v*2|1,tm+1,tr,pos,val); */
/*     t[v] = min(t[v<<1],t[v<<1|1]); */
/* } */
/* pair<int,int> query(int v, int tl, int tr, int l, int r){ */
/*     /1* whatis(v) *1/ */
/*     /1* whatis(t[v]) *1/ */
/*     /1* whatis(l) *1/ */
/*     /1* whatis(r) *1/ */
/*     if(l > r) return {0x7f7f7f7f,0x7f7f7f7f}; */
/*     /1* if(t[v]){ *1/ */
/*     /1*     return {0x7f7f7f7f,0x7f7f7f7f}; *1/ */
/*     /1* } *1/ */
/*     if(tl == l && tr == r && tr == tl){ */
/*         return {t[v],tl}; */
/*         /1* if(t[v]){ *1/ */
/*         /1*     return {0x7f7f7f7f,1}; *1/ */
/*         /1* } *1/ */
/*         /1* return {t[v],v}; *1/ */
/*     } */
/*     /1* push(v); *1/ */
/*     int tm = (tl+tr)>>1; */
/*     if(tl == l && tr == r){ */
/*         if(t[v<<1] < t[v<<1|1]){ */
/*             return query(v<<1,tl,tm,l,min(tm,r)); */
/*         } */
/*         else{ */
/*             return query(v<<1|1,tm+1,tr,max(l,tm+1),r); */
/*         } */
/*     } */
/*     auto xd = query(v<<1,tl,tm,l,min(tm,r)); */
/*     if(xd.e1 == 0) return xd; */
/*     xd = query(v<<1|1,tm+1,tr,max(l,tm+1),r); */
/*     return xd; */
/* } */

/* void modify(int p, int val){ */
/*     for(t[p += n] = val; p > 1; p>>=1) */
/*         t[p>>1] = min(t[p] , t[p^1]); */
/* } */

int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);
    int n;
    sc(n);
    int mx = 0;
    set<int> st;
    FORE(i,1,2000010){
        st.insert(st.end(),i);
    }
    FOR(i,0,n){
        string s;
        getstr(s);
        int sz = s.size();
        int m;
        sc(m);
        int aa;
        while(m--){
            sc(aa);
            /* pi cr; */
            auto it = st.lower_bound(aa);
            while(*it < aa+sz){
                /* whatis(*it) */
                mx = max(mx,*it);
                ans[*it] = s[*it-aa];
                ++it;
                st.erase(prev(it));
            }
            /* whatis(aa) */
            /* whatis(query(1,0,N-1,aa,aa+sz-1)) */
            /* while(cr = query(1,0,N-1,aa,aa+sz-1), cr.e1 == 0){ */
            /*     /1* whatis(cr) *1/ */
            /*     /1* assert(!t[N+cr]); *1/ */
            /*     /1* t[cr] = s[cr-aa]; *1/ */
            /*     /1* modify(cr.e2,s[cr.e2-aa]); *1/ */
            /*     /1* modify(1,0,N-1,cr.e2,s[cr.e2-aa]); *1/ */
            /*     mx = max(mx,cr.e2); */
            /* } */
        }
    }
    /* build(1,0,N-1); */
    FORE(i,1,mx){
        /* whatis(i) */
        /* whatis(ans[i]) */
        cout.put(ans[i] ? ans[i] : 'a');
    }
    cout << '\n';
}


#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pb push_back
#define mp make_pair
#define all(a) begin(a),end(a)
#define FOR(x,val,to) for(int x=(val);x<int((to));++x)
#define FORE(x,val,to) for(auto x=(val);x<=(to);++x)
#define FORR(x,arr) for(auto &x: arr)
#define FORS(x,plus,arr) for(auto x = begin(arr)+(plus); x != end(arr); ++x)
#define FORREV(x,plus,arr) for(auto x = (arr).rbegin()+(plus); x !=(arr).rend(); ++x)
#define REE(s_) {cout<<s_<<'\n';exit(0);}
#define GET(arr) for(auto &i: (arr)) sc(i)
#define whatis(x) cerr << #x << " is " << (x) << endl;
#define e1 first
#define e2 second
#define INF 0x7f7f7f7f
typedef std::pair<int,int> pi;
typedef std::vector<int> vi;
typedef std::vector<std::string> vs;
typedef int64_t ll;
typedef uint64_t ull;
#define umap unordered_map
#define uset unordered_set
using namespace std;
using namespace __gnu_pbds;

#ifdef _WIN32
#define getchar_unlocked() _getchar_nolock()
#define _CRT_DISABLE_PERFCRIT_LOCKS
#endif
template<class L, class R> ostream& operator<<(ostream &os, map<L, R> P) { for(auto const &vv: P)os<<"("<<vv.first<<","<<vv.second<<")"; return os; }
template<class T> ostream& operator<<(ostream &os, set<T> V) { os<<"[";for(auto const &vv:V)os<<vv<<","; os<<"]"; return os; }
template<class T> ostream& operator<<(ostream &os, vector<T> V) { os<<"[";for(auto const &vv:V)os<<vv<<","; os<<"]"; return os; }
template<class L, class R> ostream& operator<<(ostream &os, pair<L, R> P) { os<<"("<<P.first<<","<<P.second<<")"; return os; }
inline int fstoi(const string &str){auto it=str.begin();bool neg=0;int num=0;if(*it=='-')neg=1;else num=*it-'0';++it;while(it<str.end()) num=num*10+(*it++-'0');if(neg)num*=-1;return num;}
inline void getch(char &x){while(x = getchar_unlocked(), x < 33){;}}
inline void getstr(string &str){str.clear(); char cur;while(cur=getchar_unlocked(),cur<33){;}while(cur>32){str+=cur;cur=getchar_unlocked();}}
template<typename T> inline bool sc(T &num){ bool neg=0; int c; num=0; while(c=getchar_unlocked(),c<33){if(c == EOF) return false;} if(c=='-'){ neg=1; c=getchar_unlocked(); } for(;c>47;c=getchar_unlocked()) num=num*10+c-48; if(neg) num*=-1; return true;}template<typename T, typename ...Args> inline void sc(T &num, Args &...args){ bool neg=0; int c; num=0; while(c=getchar_unlocked(),c<33){;} if(c=='-'){ neg=1; c=getchar_unlocked(); } for(;c>47;c=getchar_unlocked()) num=num*10+c-48; if(neg) num*=-1; sc(args...); }
template<typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; //s.find_by_order(), s.order_of_key() <- works like lower_bound
template<typename T> using ordered_map = tree<T, int, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define N 2100000

/* int t[N << 2]; */
/* int n = N-1; */
int ans[N];

/* int query(int v, int l, int r, int tl, int tr){ //all inclusive */
/*     if(v >= n) */
/*         return v-n; */
/*     int tm = (tl+tr) >> 1; */
/*     if((t[v << 1] < t[v << 1|1] && l <= tm) || tm+1 > r) */
/*         return query(v << 1,l,min(r,tm),tl,tm); */
/*     return query(v << 1|1,max(l,tm+1),r,tm+1,tr); */
/* } */
/* void build(ll v, ll tl, ll tr){ */
/*     if(tl == tr){ */
/*         ans[tl] = t[v]; */
/*         return; */
/*     } */
/*     ll tm = (tl+tr)>>1; */
/*     build(v<<1,tl,tm); */
/*     build(v<<1|1,tm+1,tr); */
/*     /1* t[v] = min(t[v<<1] , t[v<<1|1]); *1/ */
/* } */
/* void modify(int v, int tl, int tr, int pos, int val){ */
/*     if(tl == tr){ */
/*         t[v] = val; */
/*         return; */
/*     } */
/*     int tm = (tl+tr)/2; */
/*     if(pos <= tm) */
/*         modify(v*2,tl,tm,pos,val); */
/*     else */
/*         modify(v*2|1,tm+1,tr,pos,val); */
/*     t[v] = min(t[v<<1],t[v<<1|1]); */
/* } */
/* pair<int,int> query(int v, int tl, int tr, int l, int r){ */
/*     /1* whatis(v) *1/ */
/*     /1* whatis(t[v]) *1/ */
/*     /1* whatis(l) *1/ */
/*     /1* whatis(r) *1/ */
/*     if(l > r) return {0x7f7f7f7f,0x7f7f7f7f}; */
/*     /1* if(t[v]){ *1/ */
/*     /1*     return {0x7f7f7f7f,0x7f7f7f7f}; *1/ */
/*     /1* } *1/ */
/*     if(tl == l && tr == r && tr == tl){ */
/*         return {t[v],tl}; */
/*         /1* if(t[v]){ *1/ */
/*         /1*     return {0x7f7f7f7f,1}; *1/ */
/*         /1* } *1/ */
/*         /1* return {t[v],v}; *1/ */
/*     } */
/*     /1* push(v); *1/ */
/*     int tm = (tl+tr)>>1; */
/*     if(tl == l && tr == r){ */
/*         if(t[v<<1] < t[v<<1|1]){ */
/*             return query(v<<1,tl,tm,l,min(tm,r)); */
/*         } */
/*         else{ */
/*             return query(v<<1|1,tm+1,tr,max(l,tm+1),r); */
/*         } */
/*     } */
/*     auto xd = query(v<<1,tl,tm,l,min(tm,r)); */
/*     if(xd.e1 == 0) return xd; */
/*     xd = query(v<<1|1,tm+1,tr,max(l,tm+1),r); */
/*     return xd; */
/* } */

/* void modify(int p, int val){ */
/*     for(t[p += n] = val; p > 1; p>>=1) */
/*         t[p>>1] = min(t[p] , t[p^1]); */
/* } */

int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);
    int n;
    sc(n);
    int mx = 0;
    set<int> st;
    FORE(i,1,2000010){
        st.insert(st.end(),i);
    }
    FOR(i,0,n){
        string s;
        getstr(s);
        int sz = s.size();
        int m;
        sc(m);
        int aa;
        while(m--){
            sc(aa);
            /* pi cr; */
            auto it = st.lower_bound(aa);
            while(*it < aa+sz){
                /* whatis(*it) */
                mx = max(mx,*it);
                ans[*it] = s[*it-aa];
                ++it;
                st.erase(prev(it));
            }
            /* whatis(aa) */
            /* whatis(query(1,0,N-1,aa,aa+sz-1)) */
            /* while(cr = query(1,0,N-1,aa,aa+sz-1), cr.e1 == 0){ */
            /*     /1* whatis(cr) *1/ */
            /*     /1* assert(!t[N+cr]); *1/ */
            /*     /1* t[cr] = s[cr-aa]; *1/ */
            /*     /1* modify(cr.e2,s[cr.e2-aa]); *1/ */
            /*     /1* modify(1,0,N-1,cr.e2,s[cr.e2-aa]); *1/ */
            /*     mx = max(mx,cr.e2); */
            /* } */
        }
    }
    /* build(1,0,N-1); */
    FORE(i,1,mx){
        /* whatis(i) */
        /* whatis(ans[i]) */
        cout.put(ans[i] ? ans[i] : 'a');
    }
    cout << '\n';
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pb push_back
#define mp make_pair
#define all(a) begin(a),end(a)
#define FOR(x,val,to) for(int x=(val);x<int((to));++x)
#define FORE(x,val,to) for(auto x=(val);x<=(to);++x)
#define FORR(x,arr) for(auto &x: arr)
#define FORS(x,plus,arr) for(auto x = begin(arr)+(plus); x != end(arr); ++x)
#define FORREV(x,plus,arr) for(auto x = (arr).rbegin()+(plus); x !=(arr).rend(); ++x)
#define REE(s_) {cout<<s_<<'\n';exit(0);}
#define GET(arr) for(auto &i: (arr)) sc(i)
#define whatis(x) cerr << #x << " is " << (x) << endl;
#define e1 first
#define e2 second
#define INF 0x7f7f7f7f
typedef std::pair<int,int> pi;
typedef std::vector<int> vi;
typedef std::vector<std::string> vs;
typedef int64_t ll;
typedef uint64_t ull;
#define umap unordered_map
#define uset unordered_set
using namespace std;
using namespace __gnu_pbds;

#ifdef _WIN32
#define getchar_unlocked() _getchar_nolock()
#define _CRT_DISABLE_PERFCRIT_LOCKS
#endif
template<class L, class R> ostream& operator<<(ostream &os, map<L, R> P) { for(auto const &vv: P)os<<"("<<vv.first<<","<<vv.second<<")"; return os; }
template<class T> ostream& operator<<(ostream &os, set<T> V) { os<<"[";for(auto const &vv:V)os<<vv<<","; os<<"]"; return os; }
template<class T> ostream& operator<<(ostream &os, vector<T> V) { os<<"[";for(auto const &vv:V)os<<vv<<","; os<<"]"; return os; }
template<class L, class R> ostream& operator<<(ostream &os, pair<L, R> P) { os<<"("<<P.first<<","<<P.second<<")"; return os; }
inline int fstoi(const string &str){auto it=str.begin();bool neg=0;int num=0;if(*it=='-')neg=1;else num=*it-'0';++it;while(it<str.end()) num=num*10+(*it++-'0');if(neg)num*=-1;return num;}
inline void getch(char &x){while(x = getchar_unlocked(), x < 33){;}}
inline void getstr(string &str){str.clear(); char cur;while(cur=getchar_unlocked(),cur<33){;}while(cur>32){str+=cur;cur=getchar_unlocked();}}
template<typename T> inline bool sc(T &num){ bool neg=0; int c; num=0; while(c=getchar_unlocked(),c<33){if(c == EOF) return false;} if(c=='-'){ neg=1; c=getchar_unlocked(); } for(;c>47;c=getchar_unlocked()) num=num*10+c-48; if(neg) num*=-1; return true;}template<typename T, typename ...Args> inline void sc(T &num, Args &...args){ bool neg=0; int c; num=0; while(c=getchar_unlocked(),c<33){;} if(c=='-'){ neg=1; c=getchar_unlocked(); } for(;c>47;c=getchar_unlocked()) num=num*10+c-48; if(neg) num*=-1; sc(args...); }
template<typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; //s.find_by_order(), s.order_of_key() <- works like lower_bound
template<typename T> using ordered_map = tree<T, int, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define N 2100000

int t[N << 2];
int n = N-1;
int ans[N];

/* int query(int v, int l, int r, int tl, int tr){ //all inclusive */
/*     if(v >= n) */
/*         return v-n; */
/*     int tm = (tl+tr) >> 1; */
/*     if((t[v << 1] < t[v << 1|1] && l <= tm) || tm+1 > r) */
/*         return query(v << 1,l,min(r,tm),tl,tm); */
/*     return query(v << 1|1,max(l,tm+1),r,tm+1,tr); */
/* } */
void build(ll v, ll tl, ll tr){
    if(tl == tr){
        ans[tl] = t[v];
        return;
    }
    ll tm = (tl+tr)>>1;
    build(v<<1,tl,tm);
    build(v<<1|1,tm+1,tr);
    /* t[v] = min(t[v<<1] , t[v<<1|1]); */
}
void modify(int v, int tl, int tr, int pos, int val){
    if(tl == tr){
        t[v] = val;
        return;
    }
    int tm = (tl+tr)/2;
    if(pos <= tm)
        modify(v*2,tl,tm,pos,val);
    else
        modify(v*2|1,tm+1,tr,pos,val);
    t[v] = min(t[v<<1],t[v<<1|1]);
}
pair<int,int> query(int v, int tl, int tr, int l, int r){
    /* whatis(v) */
    /* whatis(t[v]) */
    /* whatis(l) */
    /* whatis(r) */
    if(l > r) return {0x7f7f7f7f,0x7f7f7f7f};
    /* if(t[v]){ */
    /*     return {0x7f7f7f7f,0x7f7f7f7f}; */
    /* } */
    if(tl == l && tr == r && tr == tl){
        return {t[v],tl};
        /* if(t[v]){ */
        /*     return {0x7f7f7f7f,1}; */
        /* } */
        /* return {t[v],v}; */
    }
    /* push(v); */
    int tm = (tl+tr)>>1;
    if(tl == l && tr == r){
        if(t[v<<1] < t[v<<1|1]){
            return query(v<<1,tl,tm,l,min(tm,r));
        }
        else{
            return query(v<<1|1,tm+1,tr,max(l,tm+1),r);
        }
    }
    auto xd = query(v<<1,tl,tm,l,min(tm,r));
    if(xd.e1 == 0) return xd;
    xd = query(v<<1|1,tm+1,tr,max(l,tm+1),r);
    return xd;
}

/* void modify(int p, int val){ */
/*     for(t[p += n] = val; p > 1; p>>=1) */
/*         t[p>>1] = min(t[p] , t[p^1]); */
/* } */

int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);
    int n;
    sc(n);
    int mx = 0;
    FOR(i,0,n){
        string s;
        getstr(s);
        int sz = s.size();
        int m;
        sc(m);
        int aa;
        while(m--){
            sc(aa);
            pi cr;
            /* whatis(aa) */
            /* whatis(query(1,0,N-1,aa,aa+sz-1)) */
            while(cr = query(1,0,N-1,aa,aa+sz-1), cr.e1 == 0){
                /* whatis(cr) */
                /* assert(!t[N+cr]); */
                /* t[cr] = s[cr-aa]; */
                /* modify(cr.e2,s[cr.e2-aa]); */
                modify(1,0,N-1,cr.e2,s[cr.e2-aa]);
                mx = max(mx,cr.e2);
            }
        }
    }
    build(1,0,N-1);
    FORE(i,1,mx){
        /* whatis(i) */
        /* whatis(ans[i]) */
        cout.put(ans[i] ? ans[i] : 'a');
    }
    cout << '\n';
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pb push_back
#define mp make_pair
#define all(a) begin(a),end(a)
#define FOR(x,val,to) for(int x=(val);x<int((to));++x)
#define FORE(x,val,to) for(auto x=(val);x<=(to);++x)
#define FORR(x,arr) for(auto &x: arr)
#define FORS(x,plus,arr) for(auto x = begin(arr)+(plus); x != end(arr); ++x)
#define FORREV(x,plus,arr) for(auto x = (arr).rbegin()+(plus); x !=(arr).rend(); ++x)
#define REE(s_) {cout<<s_<<'\n';exit(0);}
#define GET(arr) for(auto &i: (arr)) sc(i)
#define whatis(x) cerr << #x << " is " << (x) << endl;
#define e1 first
#define e2 second
#define INF 0x7f7f7f7f
typedef std::pair<int,int> pi;
typedef std::vector<int> vi;
typedef std::vector<std::string> vs;
typedef int64_t ll;
typedef uint64_t ull;
#define umap unordered_map
#define uset unordered_set
using namespace std;
using namespace __gnu_pbds;

#ifdef _WIN32
#define getchar_unlocked() _getchar_nolock()
#define _CRT_DISABLE_PERFCRIT_LOCKS
#endif
template<class L, class R> ostream& operator<<(ostream &os, map<L, R> P) { for(auto const &vv: P)os<<"("<<vv.first<<","<<vv.second<<")"; return os; }
template<class T> ostream& operator<<(ostream &os, set<T> V) { os<<"[";for(auto const &vv:V)os<<vv<<","; os<<"]"; return os; }
template<class T> ostream& operator<<(ostream &os, vector<T> V) { os<<"[";for(auto const &vv:V)os<<vv<<","; os<<"]"; return os; }
template<class L, class R> ostream& operator<<(ostream &os, pair<L, R> P) { os<<"("<<P.first<<","<<P.second<<")"; return os; }
inline int fstoi(const string &str){auto it=str.begin();bool neg=0;int num=0;if(*it=='-')neg=1;else num=*it-'0';++it;while(it<str.end()) num=num*10+(*it++-'0');if(neg)num*=-1;return num;}
inline void getch(char &x){while(x = getchar_unlocked(), x < 33){;}}
inline void getstr(string &str){str.clear(); char cur;while(cur=getchar_unlocked(),cur<33){;}while(cur>32){str+=cur;cur=getchar_unlocked();}}
template<typename T> inline bool sc(T &num){ bool neg=0; int c; num=0; while(c=getchar_unlocked(),c<33){if(c == EOF) return false;} if(c=='-'){ neg=1; c=getchar_unlocked(); } for(;c>47;c=getchar_unlocked()) num=num*10+c-48; if(neg) num*=-1; return true;}template<typename T, typename ...Args> inline void sc(T &num, Args &...args){ bool neg=0; int c; num=0; while(c=getchar_unlocked(),c<33){;} if(c=='-'){ neg=1; c=getchar_unlocked(); } for(;c>47;c=getchar_unlocked()) num=num*10+c-48; if(neg) num*=-1; sc(args...); }
template<typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; //s.find_by_order(), s.order_of_key() <- works like lower_bound
template<typename T> using ordered_map = tree<T, int, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define N 2100000

int t[N << 2];
int n = N-1;
int ans[N];

/* int query(int v, int l, int r, int tl, int tr){ //all inclusive */
/*     if(v >= n) */
/*         return v-n; */
/*     int tm = (tl+tr) >> 1; */
/*     if((t[v << 1] < t[v << 1|1] && l <= tm) || tm+1 > r) */
/*         return query(v << 1,l,min(r,tm),tl,tm); */
/*     return query(v << 1|1,max(l,tm+1),r,tm+1,tr); */
/* } */
void build(ll v, ll tl, ll tr){
    if(tl == tr){
        ans[tl] = t[v];
        return;
    }
    ll tm = (tl+tr)>>1;
    build(v<<1,tl,tm);
    build(v<<1|1,tm+1,tr);
    /* t[v] = min(t[v<<1] , t[v<<1|1]); */
}
void modify(int v, int tl, int tr, int pos, int val){
    if(tl == tr){
        t[v] = val;
        return;
    }
    int tm = (tl+tr)/2;
    if(pos <= tm)
        modify(v*2,tl,tm,pos,val);
    else
        modify(v*2|1,tm+1,tr,pos,val);
    t[v] = min(t[v<<1],t[v<<1|1]);
}
pair<int,int> query(int v, int tl, int tr, int l, int r){
    /* whatis(v) */
    /* whatis(t[v]) */
    /* whatis(l) */
    /* whatis(r) */
    if(l > r) return {0x7f7f7f7f,0x7f7f7f7f};
    /* if(t[v]){ */
    /*     return {0x7f7f7f7f,0x7f7f7f7f}; */
    /* } */
    if(tl == l && tr == r && tr == tl){
        return {t[v],tl};
        /* if(t[v]){ */
        /*     return {0x7f7f7f7f,1}; */
        /* } */
        /* return {t[v],v}; */
    }
    /* push(v); */
    int tm = (tl+tr)>>1;
    auto xd = query(v<<1,tl,tm,l,min(tm,r));
    if(xd.e1 == 0) return xd;
    xd = query(v<<1|1,tm+1,tr,max(l,tm+1),r);
    return xd;
    /* if(t[v<<1] < t[v<<1|1]){ */
    /*     return query(v<<1,tl,tm,l,min(tm,r)); */
    /* } */
    /* else{ */
    /*     return query(v<<1|1,tm+1,tr,max(l,tm+1),r); */
    /* } */
}

/* void modify(int p, int val){ */
/*     for(t[p += n] = val; p > 1; p>>=1) */
/*         t[p>>1] = min(t[p] , t[p^1]); */
/* } */

int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);
    int n;
    sc(n);
    int mx = 0;
    FOR(i,0,n){
        string s;
        getstr(s);
        int sz = s.size();
        int m;
        sc(m);
        int aa;
        while(m--){
            sc(aa);
            pi cr;
            /* whatis(aa) */
            /* whatis(query(1,0,N-1,aa,aa+sz-1)) */
            while(cr = query(1,0,N-1,aa,aa+sz-1), cr.e1 == 0){
                /* whatis(cr) */
                /* assert(!t[N+cr]); */
                /* t[cr] = s[cr-aa]; */
                /* modify(cr.e2,s[cr.e2-aa]); */
                modify(1,0,N-1,cr.e2,s[cr.e2-aa]);
                mx = max(mx,cr.e2);
            }
        }
    }
    build(1,0,N-1);
    FORE(i,1,mx){
        /* whatis(i) */
        /* whatis(ans[i]) */
        cout.put(ans[i] ? ans[i] : 'a');
    }
    cout << '\n';
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pb push_back
#define mp make_pair
#define all(a) begin(a),end(a)
#define FOR(x,val,to) for(int x=(val);x<int((to));++x)
#define FORE(x,val,to) for(auto x=(val);x<=(to);++x)
#define FORR(x,arr) for(auto &x: arr)
#define FORS(x,plus,arr) for(auto x = begin(arr)+(plus); x != end(arr); ++x)
#define FORREV(x,plus,arr) for(auto x = (arr).rbegin()+(plus); x !=(arr).rend(); ++x)
#define REE(s_) {cout<<s_<<'\n';exit(0);}
#define GET(arr) for(auto &i: (arr)) sc(i)
#define whatis(x) cerr << #x << " is " << (x) << endl;
#define e1 first
#define e2 second
#define INF 0x7f7f7f7f
typedef std::pair<int,int> pi;
typedef std::vector<int> vi;
typedef std::vector<std::string> vs;
typedef int64_t ll;
typedef uint64_t ull;
#define umap unordered_map
#define uset unordered_set
using namespace std;
using namespace __gnu_pbds;

#ifdef _WIN32
#define getchar_unlocked() _getchar_nolock()
#define _CRT_DISABLE_PERFCRIT_LOCKS
#endif
template<class L, class R> ostream& operator<<(ostream &os, map<L, R> P) { for(auto const &vv: P)os<<"("<<vv.first<<","<<vv.second<<")"; return os; }
template<class T> ostream& operator<<(ostream &os, set<T> V) { os<<"[";for(auto const &vv:V)os<<vv<<","; os<<"]"; return os; }
template<class T> ostream& operator<<(ostream &os, vector<T> V) { os<<"[";for(auto const &vv:V)os<<vv<<","; os<<"]"; return os; }
template<class L, class R> ostream& operator<<(ostream &os, pair<L, R> P) { os<<"("<<P.first<<","<<P.second<<")"; return os; }
inline int fstoi(const string &str){auto it=str.begin();bool neg=0;int num=0;if(*it=='-')neg=1;else num=*it-'0';++it;while(it<str.end()) num=num*10+(*it++-'0');if(neg)num*=-1;return num;}
inline void getch(char &x){while(x = getchar_unlocked(), x < 33){;}}
inline void getstr(string &str){str.clear(); char cur;while(cur=getchar_unlocked(),cur<33){;}while(cur>32){str+=cur;cur=getchar_unlocked();}}
template<typename T> inline bool sc(T &num){ bool neg=0; int c; num=0; while(c=getchar_unlocked(),c<33){if(c == EOF) return false;} if(c=='-'){ neg=1; c=getchar_unlocked(); } for(;c>47;c=getchar_unlocked()) num=num*10+c-48; if(neg) num*=-1; return true;}template<typename T, typename ...Args> inline void sc(T &num, Args &...args){ bool neg=0; int c; num=0; while(c=getchar_unlocked(),c<33){;} if(c=='-'){ neg=1; c=getchar_unlocked(); } for(;c>47;c=getchar_unlocked()) num=num*10+c-48; if(neg) num*=-1; sc(args...); }
template<typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; //s.find_by_order(), s.order_of_key() <- works like lower_bound
template<typename T> using ordered_map = tree<T, int, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define N 2100000

/* int t[N << 2]; */
/* int n = N-1; */
int ans[N];

/* int query(int v, int l, int r, int tl, int tr){ //all inclusive */
/*     if(v >= n) */
/*         return v-n; */
/*     int tm = (tl+tr) >> 1; */
/*     if((t[v << 1] < t[v << 1|1] && l <= tm) || tm+1 > r) */
/*         return query(v << 1,l,min(r,tm),tl,tm); */
/*     return query(v << 1|1,max(l,tm+1),r,tm+1,tr); */
/* } */
/* void build(ll v, ll tl, ll tr){ */
/*     if(tl == tr){ */
/*         ans[tl] = t[v]; */
/*         return; */
/*     } */
/*     ll tm = (tl+tr)>>1; */
/*     build(v<<1,tl,tm); */
/*     build(v<<1|1,tm+1,tr); */
/*     /1* t[v] = min(t[v<<1] , t[v<<1|1]); *1/ */
/* } */
/* void modify(int v, int tl, int tr, int pos, int val){ */
/*     if(tl == tr){ */
/*         t[v] = val; */
/*         return; */
/*     } */
/*     int tm = (tl+tr)/2; */
/*     if(pos <= tm) */
/*         modify(v*2,tl,tm,pos,val); */
/*     else */
/*         modify(v*2|1,tm+1,tr,pos,val); */
/*     t[v] = min(t[v<<1],t[v<<1|1]); */
/* } */
/* pair<int,int> query(int v, int tl, int tr, int l, int r){ */
/*     /1* whatis(v) *1/ */
/*     /1* whatis(t[v]) *1/ */
/*     /1* whatis(l) *1/ */
/*     /1* whatis(r) *1/ */
/*     if(l > r) return {0x7f7f7f7f,0x7f7f7f7f}; */
/*     /1* if(t[v]){ *1/ */
/*     /1*     return {0x7f7f7f7f,0x7f7f7f7f}; *1/ */
/*     /1* } *1/ */
/*     if(tl == l && tr == r && tr == tl){ */
/*         return {t[v],tl}; */
/*         /1* if(t[v]){ *1/ */
/*         /1*     return {0x7f7f7f7f,1}; *1/ */
/*         /1* } *1/ */
/*         /1* return {t[v],v}; *1/ */
/*     } */
/*     /1* push(v); *1/ */
/*     int tm = (tl+tr)>>1; */
/*     if(tl == l && tr == r){ */
/*         if(t[v<<1] < t[v<<1|1]){ */
/*             return query(v<<1,tl,tm,l,min(tm,r)); */
/*         } */
/*         else{ */
/*             return query(v<<1|1,tm+1,tr,max(l,tm+1),r); */
/*         } */
/*     } */
/*     auto xd = query(v<<1,tl,tm,l,min(tm,r)); */
/*     if(xd.e1 == 0) return xd; */
/*     xd = query(v<<1|1,tm+1,tr,max(l,tm+1),r); */
/*     return xd; */
/* } */

/* void modify(int p, int val){ */
/*     for(t[p += n] = val; p > 1; p>>=1) */
/*         t[p>>1] = min(t[p] , t[p^1]); */
/* } */

int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);
    int n;
    sc(n);
    int mx = 0;
    set<int> st;
    FORE(i,1,2000010){
        st.insert(i);
    }
    FOR(i,0,n){
        string s;
        getstr(s);
        int sz = s.size();
        int m;
        sc(m);
        int aa;
        while(m--){
            sc(aa);
            /* pi cr; */
            auto it = st.lower_bound(aa);
            while(*it < aa+sz){
                /* whatis(*it) */
                mx = max(mx,*it);
                ans[*it] = s[*it-aa];
                ++it;
                st.erase(prev(it));
            }
            /* whatis(aa) */
            /* whatis(query(1,0,N-1,aa,aa+sz-1)) */
            /* while(cr = query(1,0,N-1,aa,aa+sz-1), cr.e1 == 0){ */
            /*     /1* whatis(cr) *1/ */
            /*     /1* assert(!t[N+cr]); *1/ */
            /*     /1* t[cr] = s[cr-aa]; *1/ */
            /*     /1* modify(cr.e2,s[cr.e2-aa]); *1/ */
            /*     /1* modify(1,0,N-1,cr.e2,s[cr.e2-aa]); *1/ */
            /*     mx = max(mx,cr.e2); */
            /* } */
        }
    }
    /* build(1,0,N-1); */
    FORE(i,1,mx){
        /* whatis(i) */
        /* whatis(ans[i]) */
        cout.put(ans[i] ? ans[i] : 'a');
    }
    cout << '\n';
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define fio ios_base::sync_with_stdio(false)
#define MOD 1000000007
#define INF 1000000000
#define INFLL 1000000000000000000ll
#define mp make_pair
#define pb push_back
#define ff first
#define ss second
#define long int64_t
using namespace std;
using namespace __gnu_pbds;
typedef pair<int, int> pii;
typedef priority_queue<pii, vector<pii>, greater<pii>> min_pq;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> OST;

const int N = 1e6 + 10;

int p[N];
string s[N];

int main()
{
    fio;
    int n, mx = 0;
    cin >> n;
    for(int i=1; i<=n; i++)
    {
        int x;
        cin >> s[i] >> x;
        for(int j=0; j<x; j++)
        {
            int k;
            cin >> k;
            if(s[p[k-1]].length() < s[i].length())
                p[k-1] = i;
            mx = max(mx, k);
        }
    }
    int idx = p[0];
    int rem = s[p[0]].length();
    for(int i=0; i<mx or rem; i++)
    {
        if(s[p[i]].length() > rem)
        {
            idx = p[i];
            rem = s[p[i]].length();
        }
        if(rem == 0)
            cout << 'a';
        else
        {
            cout << s[idx][s[idx].length()-rem];
            rem--;
        }
    }
    cout << endl;
    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define fio ios_base::sync_with_stdio(false)
#define MOD 1000000007
#define INF 1000000000
#define INFLL 1000000000000000000ll
#define mp make_pair
#define pb push_back
#define ff first
#define ss second
#define long int64_t
using namespace std;
using namespace __gnu_pbds;
typedef pair<int, int> pii;
typedef priority_queue<pii, vector<pii>, greater<pii>> min_pq;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> OST;

const int N = 2e6 + 10;

int main()
{
    fio;
    int n, mx = 0;
    cin >> n;
    string ans(N, '?');
    for(int i=0; i<n; i++)
    {
        int x;
        string s;
        cin >> s >> x;
        int nn = s.length();
        for(int j=0; j<x; j++)
        {
            int k;
            cin >> k;
            mx = max(mx, k+nn);
            for(int l=0; l<nn; l++)
                ans[k+l] = s[l];
        }
    }
    string f;
    for(int i=1; i<mx; i++)
        f.pb(ans[i] == '?' ? 'a' : ans[i]);
    cout << f << endl;
    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define fio ios_base::sync_with_stdio(false)
#define MOD 1000000007
#define INF 1000000000
#define INFLL 1000000000000000000ll
#define mp make_pair
#define pb push_back
#define ff first
#define ss second
#define long int64_t
using namespace std;
using namespace __gnu_pbds;
typedef pair<int, int> pii;
typedef priority_queue<pii, vector<pii>, greater<pii>> min_pq;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> OST;

const int N = 2e6 + 10;

int main()
{
    fio;
    cin.tie(0);
    int n, mx = 0;
    cin >> n;
    string ans(N, '?');
    for(int i=0; i<n; i++)
    {
        int x;
        string s;
        cin >> s >> x;
        int nn = s.length();
        for(int j=0; j<x; j++)
        {
            int k;
            cin >> k;
            mx = max(mx, k+nn);
            for(int l=0; l<nn; l++)
                ans[k+l] = s[l];
        }
    }
    for(int i=1; i<mx; i++)
        putchar(ans[i] == '?' ? 'a' : ans[i]);
    putchar('\n');
    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define fio ios_base::sync_with_stdio(false)
#define MOD 1000000007
#define INF 1000000000
#define INFLL 1000000000000000000ll
#define mp make_pair
#define pb push_back
#define ff first
#define ss second
#define long int64_t
using namespace std;
using namespace __gnu_pbds;
typedef pair<int, int> pii;
typedef priority_queue<pii, vector<pii>, greater<pii>> min_pq;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> OST;

const int N = 1e6 + 10;

int main()
{
    fio;
    int n, mx = 0;
    cin >> n;
    string ans(N, '?');
    for(int i=0; i<n; i++)
    {
        int x;
        string s;
        cin >> s >> x;
        int nn = s.length();
        for(int j=0; j<x; j++)
        {
            int k;
            cin >> k;
            mx = max(mx, k+nn);
            for(int l=0; l<nn; l++)
                ans[k+l] = s[l];
        }
    }
    for(int i=1; i<mx; i++)
        cout << (ans[i] == '?' ? 'a' : ans[i]);
    cout << endl;
    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define fio ios_base::sync_with_stdio(false)
#define MOD 1000000007
#define INF 1000000000
#define INFLL 1000000000000000000ll
#define mp make_pair
#define pb push_back
#define ff first
#define ss second
#define long int64_t
using namespace std;
using namespace __gnu_pbds;
typedef pair<int, int> pii;
typedef priority_queue<pii, vector<pii>, greater<pii>> min_pq;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> OST;

const int N = 1e6 + 10;

int p[N];
string s[N];

int main()
{
    fio;
    int n, mx = 0;
    cin >> n;
    for(int i=1; i<=n; i++)
    {
        int x;
        cin >> s[i] >> x;
        for(int j=0; j<x; j++)
        {
            int k;
            cin >> k;
            if(s[p[k-1]].length() < s[i].length())
                p[k-1] = i;
            mx = max(mx, k);
        }
    }
    int idx = p[0];
    int rem = s[p[0]].length();
    for(int i=0; i<mx; i++)
    {
        if(s[p[i]].length() > rem)
        {
            idx = p[i];
            rem = s[p[i]].length();
        }
        if(rem == 0)
            cout << 'a';
        else
        {
            cout << s[idx][s[idx].length()-rem];
            rem--;
        }
    }
    while(rem)
    {
        cout << s[idx][s[idx].length()-rem];
        rem--;
    }
    cout << endl;
    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define fio ios_base::sync_with_stdio(false)
#define MOD 1000000007
#define INF 1000000000
#define INFLL 1000000000000000000ll
#define mp make_pair
#define pb push_back
#define ff first
#define ss second
#define long int64_t
using namespace std;
using namespace __gnu_pbds;
typedef pair<int, int> pii;
typedef priority_queue<pii, vector<pii>, greater<pii>> min_pq;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> OST;

const int N = 2e6 + 10;

int main()
{
    fio;
    int n, mx = 0;
    cin >> n;
    string ans(N, '?');
    for(int i=0; i<n; i++)
    {
        int x;
        string s;
        cin >> s >> x;
        int nn = s.length();
        for(int j=0; j<x; j++)
        {
            int k;
            cin >> k;
            mx = max(mx, k+nn);
            for(int l=0; l<nn; l++)
                ans[k+l] = s[l];
        }
    }
    for(int i=1; i<mx; i++)
        cout << (ans[i] == '?' ? 'a' : ans[i]);
    cout << endl;
    return 0;
}