#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char s[3000050],t[3000050];
int vis[3000500];
int find(int a)
{
	int r=a;
	while(vis[r]!=r)
	r=vis[r];
	int i=a;
	int j;
	while(i!=r)
	{
		j=vis[i];
		vis[i]=r;
		i=j;
	}
	return r;
}
void merge(int a,int b)
{
	int aa=find(a);
	int bb=find(b);
	if(aa>bb)
		vis[bb]=aa;
	else
		vis[aa]=bb;
	return ;
}
int main()
{
	int n,k,x,maxx=-1;
	scanf("%d",&n);
	for(int i=0;i<3000500;i++)
		vis[i]=i;
	for(int i=1;i<=n;i++)
	{
		scanf("%s",t);
		int tt=strlen(t);
		scanf("%d",&k);
		for(int j=1;j<=k;j++)
		{
			scanf("%d",&x);
			int tmpx=x;
/*			for(int r=vis[x];r<=tt+x-1;r=vis[r])
			{
				s[r]=t[r-x];
				vis[r]=vis[r+1];
			}
			for(int r=vis[x];r<=tt+x-1;r=vis[r])
			{
				vis[r]=vis[tt+x-1];
			}*/
			while(x<=tt+tmpx-1)
			{
				s[x]=t[x-tmpx];
				x=find(x);
				if(x<=tmpx+tt-1) merge(x,x+1);
			}
			if(maxx<tt+tmpx-1)
				maxx=tt+tmpx-1;
		}
	}
	for(int i=1;i<=maxx;i++)
	{
		if(s[i]=='\0')
			s[i]='a';
		printf("%c",s[i]);
	}
	printf("\n");
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char s[3000050],t[3000050];
int vis[3000500];
int find(int a)
{
	int r=a;
	while(vis[r]!=r)
	r=vis[r];
	int i=a;
	int j;
	while(i!=r)
	{
		j=vis[i];
		vis[i]=r;
		i=j;
	}
	return r;
}
void merge(int a,int b)
{
	int aa=find(a);
	int bb=find(b);
	if(aa>bb)
		vis[bb]=aa;
	else
		vis[aa]=bb;
	return ;
}
int main()
{
	int n,k,x,maxx=-1;
	scanf("%d",&n);
	for(int i=0;i<3000500;i++)
		vis[i]=i;
	for(int i=1;i<=n;i++)
	{
		scanf("%s",t);
		int tt=strlen(t);
		scanf("%d",&k);
		for(int j=1;j<=k;j++)
		{
			scanf("%d",&x);
			int tmpx=x;
/*			for(int r=vis[x];r<=tt+x-1;r=vis[r])
			{
				s[r]=t[r-x];
				vis[r]=vis[r+1];
			}
			for(int r=vis[x];r<=tt+x-1;r=vis[r])
			{
				vis[r]=vis[tt+x-1];
			}*/
			while(x<=tt+tmpx-1)
			{
				x=find(x);
				s[x]=t[x-tmpx];
				//x=find(x);
				if(x<=tmpx+tt-1) merge(x,x+1);
			}
			if(maxx<tt+tmpx-1)
				maxx=tt+tmpx-1;
		}
	}
	for(int i=1;i<=maxx;i++)
	{
		if(s[i]=='\0')
			s[i]='a';
		printf("%c",s[i]);
	}
	printf("\n");
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char s[10000050],t[1000050];
int vis[2000500];
int main()
{
	int n,k,x,maxx=-1;
	scanf("%d",&n);
	for(int i=0;i<2000500;i++)
		vis[i]=i;
	for(int i=1;i<=n;i++)
	{
		scanf("%s",t);
		int tt=strlen(t);
		scanf("%d",&k);
		for(int j=1;j<=k;j++)
		{
			scanf("%d",&x);
			for(int r=vis[x];r<=tt+x-1;r=vis[r])
			{
				s[r]=t[r-x];
				vis[r]=vis[r+1];
			}
			for(int r=vis[x];r<=tt+x-1;r=vis[r])
			{
				vis[r]=vis[tt+x-1];
			}
			if(maxx<tt+x-1)
				maxx=tt+x-1;
		}
	}
	for(int i=1;i<=maxx;i++)
	{
		if(s[i]=='\0')
			s[i]='a';
		printf("%c",s[i]);
	}
	printf("\n");
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char s[10000050],t[1000050];
int vis[200050];
int main()
{
	int n,k,x,maxx=-1;
	scanf("%d",&n);
	for(int i=1;i<=200050;i++)
		vis[i]=i;
	for(int i=1;i<=n;i++)
	{
		scanf("%s",t);
		int tt=strlen(t);
		scanf("%d",&k);
		for(int j=1;j<=k;j++)
		{
			scanf("%d",&x);
			s[x]=t[0];
			vis[x]=x+1;
			for(int r=vis[x];r<=tt+x-1;r=vis[r])
			{
				s[r]=t[r-x];
				vis[r]=tt+x;
			}
			if(maxx<tt+x-1)
				maxx=tt+x-1;
		}
	}
	for(int i=1;i<=maxx;i++)
	{
		if(s[i]=='\0')
			s[i]='a';
	}
	printf("%s\n",s+1);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char s[10000050],t[1000050];
int vis[2000500];
int main()
{
	int n,k,x,maxx=-1;
	scanf("%d",&n);
	for(int i=1;i<2000500;i++)
		vis[i]=i;
	for(int i=1;i<=n;i++)
	{
		scanf("%s",t);
		int tt=strlen(t);
		scanf("%d",&k);
		for(int j=1;j<=k;j++)
		{
			scanf("%d",&x);
			for(int r=vis[x];r<=tt+x-1;r=vis[r])
			{
				s[r]=t[r-x];
				vis[r]=vis[r+1];
			}
			if(maxx<tt+x-1)
				maxx=tt+x-1;
		}
	}
	for(int i=1;i<=maxx;i++)
	{
		if(s[i]=='\0')
			s[i]='a';
	}
	printf("%s\n",s+1);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char s[10000050],t[1000050];
int vis[200050];
int main()
{
	int n,k,x,maxx=-1;
	scanf("%d",&n);
	for(int i=1;i<=200050;i++)
		vis[i]=i;
	for(int i=1;i<=n;i++)
	{
		scanf("%s",t);
		int tt=strlen(t);
		scanf("%d",&k);
		for(int j=1;j<=k;j++)
		{
			scanf("%d",&x);
			for(int r=vis[x];r<=tt+x-1;r=vis[r])
			{
				s[r]=t[r-x];
				vis[r]=r+1;
			}
			if(maxx<tt+x-1)
				maxx=tt+x-1;
		}
	}
	for(int i=1;i<=maxx;i++)
	{
		if(s[i]=='\0')
			s[i]='a';
	}
	printf("%s\n",s+1);
	return 0;
}


#include<cstdio>
#include<cstring>
const int N=1e5+5,S=1e6+5;
int n,len,k,x;
char s[S];
char t[S];
signed main()
{
	int i,j,l;
	scanf("%d\n",&n);
	for(i=1;i<=n;i++)
	{
		scanf("%s",t+1);
		len=strlen(t+1);
		scanf("%d",&k);
		for(j=1;j<=k;j++)
		{
			scanf("%d",&x);
			for(l=x;l<=x+len-1;l++)
				s[l]=t[l-x+1];
		}
		memset(t,0,sizeof t);
	}
	printf("%s\n",s+1);
	return 0;
}


%:pragma GCC optimize(2)
#include<cstdio>
#include<string>
#include<iostream>
#include<algorithm>
using std::max;
using std::cin;
using std::cout;
using std::sort;
using std::string;
const int N=1e5+5,S=1e6+5;
int n,k,x,slen,len,cnt;
string s;
string t[N];
struct node
{
	int a;
	int b,e;
}c[S];
inline bool cmp(node x,node y)
{
	return x.b<y.b;
}
signed main()
{
	int i,j;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		cin>>t[i];
		len=t[i].size();
		scanf("%d",&k);
		for(j=1;j<=k;j++)
		{
			scanf("%d",&x);
			x--;
			c[++cnt].a=i;
			c[cnt].b=x;
			c[cnt].e=x+len-1;
			slen=max(slen,x+len);
		}
	}
	s.assign(slen,'a');
	sort(c+1,c+cnt+1,cmp);
	int prev=0;
	for(i=1;i<=cnt;i++)
	{
		if(c[i].e<prev)
			continue;
		for(j=c[i].b;j<=c[i].e;j++)
			s[j]=t[c[i].a][j-c[i].b];
		prev=c[i].e+1;
		if(prev==slen)
			break;
	}
	cout<<s<<'\n';
	return 0;
}


%:pragma GCC optimize(2)
#include<cstdio>
#include<string>
#include<iostream>
#include<algorithm>
using std::max;
using std::cin;
using std::cout;
using std::sort;
using std::string;
const int N=1e5+5,S=1e6+5;
int n,k,x,slen,len,cnt;
string s;
string t[N];
struct node
{
	int a;
	int b,e;
}c[S];
inline bool cmp(node x,node y)
{
	return x.b<y.b;
}
signed main()
{
	int i,j;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		cin>>t[i];
		len=t[i].size();
		scanf("%d",&k);
		for(j=1;j<=k;j++)
		{
			scanf("%d",&x);
			x--;
			c[++cnt].a=i;
			c[cnt].b=x;
			c[cnt].e=x+len-1;
			slen=max(slen,x+len);
		}
	}
	s.assign(slen,'a');
	sort(c+1,c+cnt+1,cmp);
	int prev=0;
	for(i=1;i<=cnt;i++)
	{
		if(c[i].e<prev)
			continue;
		for(j=max(c[i].b,prev);j<=c[i].e;j++)
			s[j]=t[c[i].a][j-c[i].b];
		prev=c[i].e+1;
		if(prev==slen)
			break;
	}
	cout<<s<<'\n';
	return 0;
}


%:pragma GCC optimize(2)
#include<cstdio>
#include<string>
#include<iostream>
#include<algorithm>
using std::max;
using std::cin;
using std::cout;
using std::sort;
using std::string;
const int N=1e5+5,S=1e6+5;
int n,k,x,slen,len,cnt;
string s;
string t;
struct node
{
	string a;
	int b,e;
}c[S];
inline bool cmp(node x,node y)
{
	return x.b<y.b;
}
signed main()
{
	int i,j;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		cin>>t;
		len=t.size();
		scanf("%d",&k);
		for(j=1;j<=k;j++)
		{
			scanf("%d",&x);
			x--;
			c[++cnt].a=t;
			c[cnt].b=x;
			c[cnt].e=x+len-1;
			slen=max(slen,x+len);
		}
	}
	s.assign(slen,'a');
	sort(c+1,c+cnt+1,cmp);
	int prev=0;
	for(i=1;i<=cnt;i++)
	{
		if(c[i].e<prev)
			continue;
		for(j=c[i].b;j<=c[i].e;j++)
			s[j]=c[i].a[j-c[i].b];
		prev=c[i].e+1;
		if(prev==slen)
			break;
	}
	cout<<s<<'\n';
	return 0;
}


#include<cstdio>
#include<string>
#include<iostream>
#include<algorithm>
using std::max;
using std::cin;
using std::cout;
using std::sort;
using std::string;
const int N=1e5+5,S=1e6+5;
int n,k,x,slen,len,cnt;
string s;
string t;
struct node
{
	string a;
	int b,e;
}c[S];
inline bool cmp(node x,node y)
{
	return x.b<y.b;
}
signed main()
{
	int i,j;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		cin>>t;
		len=t.size();
		scanf("%d",&k);
		for(j=1;j<=k;j++)
		{
			scanf("%d",&x);
			x--;
			c[++cnt].a=t;
			c[cnt].b=x;
			c[cnt].e=x+len-1;
			slen=max(slen,x+len);
		}
	}
	s.assign(slen,'a');
	sort(c+1,c+cnt+1,cmp);
	int prev=0;
	for(i=1;i<=cnt;i++)
	{
		if(c[i].e<prev)
			continue;
		for(j=c[i].b;j<=c[i].e;j++)
			s[j]=c[i].a[j-c[i].b];
		prev=c[i].e+1;
		if(prev==slen)
			break;
	}
	cout<<s<<'\n';
	return 0;
}


%:pragma GCC optimize(2)
#include<cstdio>
#include<cstring>
#define max(a,b) (a>b?a:b)
const int N=1e5+5,S=1e6+5;
int n,len,k,x,slen;
char s[S];
char t[S];
signed main()
{
	int i,j,l;
	scanf("%d\n",&n);
	memset(s,'a',sizeof s);
	for(i=1;i<=n;i++)
	{
		scanf("%s",t+1);
		len=strlen(t+1);
		scanf("%d",&k);
		for(j=1;j<=k;j++)
		{
			scanf("%d",&x);
			slen=max(slen,x+len-1);
			for(l=x;l<=x+len-1;l++)
				s[l]=t[l-x+1];
		}
		memset(t,0,sizeof t);
	}
	for(i=1;i<=slen;i++)
		printf("%c",s[i]);
	putchar('\n');
	return 0;
}


%:pragma GCC optimize(3)
#include<cstdio>
#include<string>
#include<iostream>
#include<algorithm>
using std::max;
using std::cin;
using std::cout;
using std::sort;
using std::string;
const int N=1e5+5,S=1e6+5;
int n,k,x,slen,len,cnt;
string s;
string t[N];
struct node
{
	int a;
	int b,e;
}c[S];
inline bool cmp(node x,node y)
{
	return x.b<y.b;
}
signed main()
{
	int i,j;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		cin>>t[i];
		len=t[i].size();
		scanf("%d",&k);
		for(j=1;j<=k;j++)
		{
			scanf("%d",&x);
			x--;
			c[++cnt].a=i;
			c[cnt].b=x;
			c[cnt].e=x+len-1;
			slen=max(slen,x+len);
		}
	}
	s.assign(slen,'a');
	sort(c+1,c+cnt+1,cmp);
	int prev=0;
	for(i=1;i<=cnt;i++)
	{
		if(c[i].e<prev)
			continue;
		for(j=c[i].b;j<=c[i].e;j++)
			s[j]=t[c[i].a][j-c[i].b];
		prev=c[i].e+1;
		if(prev==slen)
			break;
	}
	cout<<s<<'\n';
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#define LL long long
#define N 2000100
#define MOD 1000000007
#define FOR(i,l,r) for (int i = (l); i <= (r); i ++)
#define CLR(a,x) memset(a,x,sizeof(a))
#define INF 0x7fffffff
#define pb push_back
#define X first
#define Y second
using namespace std;
char ans[N];
string st[N];
int p[N];
vector<int> pos[N];
struct Node{
	int id,len;
	Node() {}
	Node(int a,int b):id(a),len(b) {}
}a[N];
int cmp(Node a,Node b){
	return a.len > b.len;
}
int find(int x){
	return p[x] == x ? x : p[x] = find(p[x]);
}
int main(){
	int n;
	cin >> n;
	int m = 0;
	FOR(i,1,n){
		cin >> st[i];
		int l = st[i].size();
		int k;
		scanf("%d",&k);
		FOR(j,1,k){
			int x;
			scanf("%d",&x);
			pos[i].pb(x);
			m = max(m,x + l - 1);
		}
		a[i] = Node(i,l);
	}
	FOR(i,1,m + 10) p[i] = i;
	sort(a + 1,a + n + 1,cmp);
	FOR(i,1,n){
		int len = a[i].len,id = a[i].id;
		for (int j = 0; j < pos[id].size(); j ++){
			int po = pos[id][j];
			int head1 = find(po);
			if (head1 - po >= len) continue;
			else{
				len -= head1 - po;
				int head2 = head1 - po,ed;
				for (ed = 0; ed < len && !ans[head1 + ed]; ed ++)
					ans[head1 + ed] = st[id][head2 + ed];
				for (int k = 0; k < ed; k ++) p[head1 + k] = head1 + ed;
			}
		}
	}
	FOR(i,1,m) if (ans[i]) printf("%c",ans[i]);
	else printf("a");
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#define LL long long
#define N 2000100
#define MOD 1000000007
#define FOR(i,l,r) for (int i = (l); i <= (r); i ++)
#define CLR(a,x) memset(a,x,sizeof(a))
#define INF 0x7fffffff
#define pb push_back
#define X first
#define Y second
using namespace std;
char ans[N];
string st;
int p[N];
int find(int x){
	return p[x] == x ? x : p[x] = find(p[x]);
}
int main(){
	int n;
	cin >> n;
	int m = 0;
	FOR(i,1,200010) p[i] = i;
	FOR(i,1,n){
		cin >> st;
		int l = st.size();
		int k;
		scanf("%d",&k);
		FOR(j,1,k){
			int x;
			scanf("%d",&x);
			int cur = x;
			while (cur < x + l){
				ans[cur] = st[cur - x];
				p[cur] = cur + 1;
				cur = find(cur);
			}
			m = max(m,x + l - 1);
		}

	}
	FOR(i,1,m) if (ans[i]) printf("%c",ans[i]);
	else printf("a");
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#define LL long long
#define N 2000100
#define MOD 1000000007
#define FOR(i,l,r) for (int i = (l); i <= (r); i ++)
#define CLR(a,x) memset(a,x,sizeof(a))
#define INF 0x7fffffff
#define pb push_back
#define X first
#define Y second
using namespace std;
char ans[N];
string st;
int p[N];
int find(int x){
	return p[x] == x ? x : p[x] = find(p[x]);
}
int main(){
	int n;
	cin >> n;
	int m = 0;
	FOR(i,1,2000010) p[i] = i;
	FOR(i,1,n){
		cin >> st;
		int l = st.size();
		int k;
		scanf("%d",&k);
		FOR(j,1,k){
			int x;
			scanf("%d",&x);
			int cur = x;
			while (cur < x + l){
				ans[cur] = st[cur - x];
				p[cur] = cur + 1;
				cur = find(cur);
			}
			m = max(m,x + l - 1);
		}

	}
	FOR(i,1,m) if (ans[i]) printf("%c",ans[i]);
	else printf("a");
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#define LL long long
#define N 2000100
#define MOD 1000000007
#define FOR(i,l,r) for (int i = (l); i <= (r); i ++)
#define CLR(a,x) memset(a,x,sizeof(a))
#define INF 0x7fffffff
#define pb push_back
#define X first
#define Y second
using namespace std;
char ans[N];
string st[N];
int p[N];
vector<int> pos[N];
struct Node{
	int id,len;
	Node() {}
	Node(int a,int b):id(a),len(b) {}
}a[N];
int cmp(Node a,Node b){
	return a.len > b.len;
}
int find(int x){
	return p[x] == x ? x : p[x] = find(p[x]);
}
int main(){
	int n;
	cin >> n;
	int m = 0;
	FOR(i,1,n){
		cin >> st[i];
		int l = st[i].size();
		int k;
		scanf("%d",&k);
		FOR(j,1,k){
			int x;
			scanf("%d",&x);
			pos[i].pb(x);
			m = max(m,x + l - 1);
		}
		a[i] = Node(i,l);
	}
	FOR(i,1,m) p[i] = i;
	sort(a + 1,a + n + 1,cmp);
	FOR(i,1,n){
		int len = a[i].len,id = a[i].id;
		for (int j = 0; j < pos[id].size(); j ++){
			int po = pos[id][j];
			int head1 = find(po);
			if (head1 - po >= len) continue;
			else{
				len -= head1 - po;
				int head2 = head1 - po,ed;
				for (ed = 0; ed < len && !ans[head1 + ed]; ed ++)
					ans[head1 + ed] = st[id][head2 + ed];
				for (int k = 0; k < ed; k ++) p[head1 + k] = head1 + ed;
			}
		}
	}
	FOR(i,1,m) if (ans[i]) printf("%c",ans[i]);
	else printf("a");
}


#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#define LL long long
#define N 1000100
#define MOD 1000000007
#define FOR(i,l,r) for (int i = (l); i <= (r); i ++)
#define CLR(a,x) memset(a,x,sizeof(a))
#define INF 0x7fffffff
#define pb push_back
#define X first
#define Y second
using namespace std;
char ans[N / 10];
string st[N];
int p[N];
vector<int> pos[N];
struct Node{
	int id,len;
	Node() {}
	Node(int a,int b):id(a),len(b) {}
}a[N];
int cmp(Node a,Node b){
	return a.len > b.len;
}
int find(int x){
	return p[x] == x ? x : p[x] = find(p[x]);
}
int main(){
	int n;
	cin >> n;
	int m = 0;
	FOR(i,1,n){
		cin >> st[i];
		int l = st[i].size();
		int k;
		scanf("%d",&k);
		FOR(j,1,k){
			int x;
			scanf("%d",&x);
			pos[i].pb(x);
			m = max(m,x + l - 1);
		}
		a[i] = Node(i,l);
	}
	FOR(i,1,m) p[i] = i;
	sort(a + 1,a + n + 1,cmp);
	FOR(i,1,n){
		int len = a[i].len,id = a[i].id;
		for (int j = 0; j < pos[id].size(); j ++){
			int po = pos[id][j];
			int head1 = find(po);
			if (head1 - po >= len) continue;
			else{
				len -= head1 - po;
				int head2 = head1 - po,ed;
				for (ed = 0; ed < len && !ans[head1 + ed]; ed ++)
					ans[head1 + ed] = st[id][head2 + ed];
				for (int k = 0; k < ed; k ++) p[head1 + k] = head1 + ed;
			}
		}
	}
	FOR(i,1,m) if (ans[i]) printf("%c",ans[i]);
	else printf("a");
}


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define maxn 1000100
#define inf 0x3f3f3f3f

using namespace std;

struct segtree
{
    int val,addmark;
};

segtree segt[maxn*4];
char ans[maxn];
char save[maxn];

void pushdown(int root)
{
    if (segt[root].addmark!=0)
    {
        segt[root*2].val=1;
        segt[root*2].addmark=1;
        segt[root*2+1].val=1;
        segt[root*2+1].addmark=1;
        segt[root].addmark=0;
    }
    return;
}

void update(int root,int rst,int ren,int beg,int en)
{
    if (rst>=beg&&ren<=en)
    {
        segt[root].val=1;
        segt[root].addmark=1;
    }
    else if (rst>en||ren<beg) {return;}
    else
    {
        pushdown(root);
        int mid=(rst+ren)/2;
        update(root*2,rst,mid,beg,en);
        update(root*2+1,mid+1,en,beg,en);
        segt[root].val=1;
    }
}

int query(int root,int rst,int ren,int beg,int en)
{
    if (rst>en||ren<beg)
        return 0;
    if (rst>=beg&&ren<=en)
        return segt[root].val;
    pushdown(root);
    int mid=(rst+ren)/2;

    return (query(root*2,rst,mid,beg,en)&&query(root*2+1,mid+1,ren,beg,en));
}

int main()
{
    int n,len;
    while(~scanf("%d",&n))
    {
        len=0;
        memset(segt,0,sizeof(segt));
        memset(ans,0,sizeof(ans));
        while(n--)
        {
            int nn,l,r,lens;
            scanf("%s",save);
            scanf("%d",&nn);
            lens=strlen(save);

            while(nn--)
            {
                scanf("%d",&l);
                r=l+lens-1;
                if (query(1,1,maxn,l,r))//可以把query和update放在一起哦
                    continue;
                else
                {
                    for (int kk=l;kk<=r;kk++)
                        ans[kk]=save[kk-l];
                    len=max(len,r);
                    update(1,1,maxn,l,r);
                }
            }
        }
        for (int k=1;k<=len;k++)
            if(ans[k]==0) printf("a");
            else printf("%c",ans[k]);
        printf("\n");
    }
    return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define maxn 1001000

using namespace std;

int main()
{
    int n,len;
    char s[maxn],save[maxn];
    while(~scanf("%d",&n))
    {
        memset(s,0,sizeof(s));
        while(n--)
        {
            int nn,data,lens;
            scanf("%s",save);
            scanf("%d",&nn);
            lens=strlen(save);
            while(nn--)
            {
                scanf("%d",&data);
                int up=data+lens-1;
                len=max(len,up);
                for (int kk=data;kk<=up;kk++)
                    s[kk]=save[kk-data];
            }
        }

        for (int k=1;k<=len;k++)
        {
            if (s[k]==0) printf("%c",'a');
            else printf("%c",s[k]);
        }
        printf("\n");
    }
    return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define maxn 1100000
#define inf 0x3f3f3f3f

using namespace std;

struct segtree
{
    int val,addmark;
};

segtree segt[maxn*4];
char ans[maxn];
char save[maxn];

void pushdown(int root)
{
    if (segt[root].addmark!=0)
    {
        segt[root*2].val=1;
        segt[root*2].addmark=1;
        segt[root*2+1].val=1;
        segt[root*2+1].addmark=1;
        segt[root].addmark=0;
    }
    return;
}

void update(int root,int rst,int ren,int beg,int en)
{
    if (rst>=beg&&ren<=en)
    {
        segt[root].val=1;
        segt[root].addmark=1;
    }
    else if (rst>en||ren<beg) {return;}
    else
    {
        pushdown(root);
        int mid=(rst+ren)/2;
        update(root*2,rst,mid,beg,en);
        update(root*2+1,mid+1,ren,beg,en);
        segt[root].val=1;
    }
}

int query(int root,int rst,int ren,int beg,int en)
{
    if (rst>en||ren<beg)
        return 0;
    if (rst>=beg&&ren<=en)
        return segt[root].val;
    pushdown(root);
    int mid=(rst+ren)/2;

    return (query(root*2,rst,mid,beg,en)&&query(root*2+1,mid+1,ren,beg,en));
}

int main()
{
    int n,len;
    while(~scanf("%d",&n))
    {
        int debugn=n;
        len=0;
        memset(segt,0,sizeof(segt));
        memset(ans,0,sizeof(ans));
        while(n--)
        {
            int nn,l,r,lens;
            scanf("%s",save);
            scanf("%d",&nn);
            lens=strlen(save);
            while(nn--)
            {
                scanf("%d",&l);
                r=l+lens-1;
                if (query(1,1,maxn,l,r))//���԰�query��update����һ��Ŷ
                    continue;
                else
                {
                    for (int kk=l;kk<=r;kk++)
                        ans[kk]=save[kk-l];
                    len=max(len,r);
                 //   if (debugn==4751)
                   //     cout<<l<<" "<<r<<endl;
                    update(1,1,maxn,l,r);
               //     if (debugn==4751)
                 //       cout<<222222<<endl;
                }
            }
        }
        for (int k=1;k<=len;k++)
            if(ans[k]==0) printf("a");
            else printf("%c",ans[k]);
        printf("\n");
    }
    return 0;
}


//��ʵ���ǰ�һ�������ģ��Ѿ���ֵ�Ĵ��ϲ���һ�����ϣ�Ȼ��ÿһ�����϶���һ����Χ��l��r
//����ÿ������ÿ����������������ж������ʼλ���Ƿ��ڼ�����
//���ڵĻ����½�һ�����Ϸ�Χ��l��r
//�ڵĻ��Ϳ���������Ļ��͹������һ���ְ���һ����û�еĻ��͸�ֵ���Ҹ���l��r��ֵ����
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define maxn 1001000
using namespace std;

struct Fa
{
    int val,l,r;
};

char ans[maxn],save[maxn];
Fa fa[maxn];

int find_r(int x)
{
    if (fa[x].val<0) return x;
    else {
        fa[x].val=find_r(fa[x].val);
        return fa[x].val;
    }
}

int main()
{
    int n,len(0);
    for (int k=0;k<maxn;k++){
        fa[k].l=k;fa[k].r=k;fa[k].val=-1;
    }
    scanf("%d",&n);

    while(n--){
        int nn,lens,sl,sr,ll,rr;

        scanf("%s",save);
        scanf("%d",&nn);
        lens=strlen(save);
        while(nn--){
            scanf("%d",&sl);
            sr=sl+lens-1;
            len=max(len,sr);

            int fal=find_r(sl);
            ll=fa[fal].l;rr=fa[fal].r;

            if (ll<=sl&&rr>=sr) continue;
            else if (ll>sl&&rr<sr){
                fa[fal].l=sl;fa[fal].r=sr;
                for (int k=sl;k<=ll;k++){
                    fa[k].val=fal;
                    ans[k]=save[k-sl];
                }
                for (int k=rr;k<=sr;k++){
                    fa[k].val=fal;
                    ans[k]=save[k-sl];
                }
            }
            else if (ll>sl){
                fa[fal].l=sl;
                for (int k=sl;k<=ll;k++){
                    fa[k].val=fal;
                    ans[k]=save[k-sl];
                }
            }
            else if (rr<sr){
                fa[fal].r=sr;
                for (int k=rr;k<=sr;k++){
                    fa[k].val=fal;
                    ans[k]=save[k-sl];
                }
            }
        }
    }
    for (int k=1;k<=len;k++)
        if (ans[k]=='\0')
            printf("a");
        else printf("%c",ans[k]);
}


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define maxn 1100000
#define inf 0x3f3f3f3f

using namespace std;

struct segtree
{
    int val,addmark;
};

segtree segt[maxn*4];
char ans[maxn];
char save[maxn];

void pushdown(int root)
{
    if (segt[root].addmark!=0)
    {
        segt[root*2].val=1;
        segt[root*2].addmark=1;
        segt[root*2+1].val=1;
        segt[root*2+1].addmark=1;
        segt[root].addmark=0;
    }
    return;
}

void update(int root,int rst,int ren,int beg,int en)
{
    if (rst>=beg&&ren<=en)
    {
        segt[root].val=1;
        segt[root].addmark=1;
    }
    else if (rst>en||ren<beg) {return;}
    else
    {
        pushdown(root);
        int mid=(rst+ren)/2;
        update(root*2,rst,mid,beg,en);
        update(root*2+1,mid+1,en,beg,en);
        segt[root].val=1;
    }
}

int query(int root,int rst,int ren,int beg,int en)
{
    if (rst>en||ren<beg)
        return 0;
    if (rst>=beg&&ren<=en)
        return segt[root].val;
    pushdown(root);
    int mid=(rst+ren)/2;

    return (query(root*2,rst,mid,beg,en)&&query(root*2+1,mid+1,ren,beg,en));
}

int main()
{
    int n,len;
    while(~scanf("%d",&n))
    {
        len=0;
        memset(segt,0,sizeof(segt));
        memset(ans,0,sizeof(ans));
        cout<<111111<<endl;
        while(n--)
        {
            int nn,l,r,lens;
            scanf("%s",save);
            scanf("%d",&nn);
            lens=strlen(save);
            cout<<222222<<endl;
            while(nn--)
            {
                scanf("%d",&l);
                r=l+lens-1;
                if (query(1,1,maxn,l,r))//可以把query和update放在一起哦
                    continue;
                else
                {
                    for (int kk=l;kk<=r;kk++)
                        ans[kk]=save[kk-l];
                    len=max(len,r);
                    update(1,1,maxn,l,r);
                }
            }
            cout<<333333<<endl;
        }
        for (int k=1;k<=len;k++)
            if(ans[k]==0) printf("a");
            else printf("%c",ans[k]);
        printf("\n");
    }
    return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define maxn 1100000
#define inf 0x3f3f3f3f

using namespace std;

struct segtree
{
    int val,addmark;
};

segtree segt[maxn*4];
char ans[maxn];
char save[maxn];

void pushdown(int root)
{
    if (segt[root].addmark!=0)
    {
        segt[root*2].val=1;
        segt[root*2].addmark=1;
        segt[root*2+1].val=1;
        segt[root*2+1].addmark=1;
        segt[root].addmark=0;
    }
    return;
}

void update(int root,int rst,int ren,int beg,int en)
{
    if (rst>=beg&&ren<=en)
    {
        segt[root].val=1;
        segt[root].addmark=1;
    }
    else if (rst>en||ren<beg) {return;}
    else
    {
        pushdown(root);
        int mid=(rst+ren)/2;
        update(root*2,rst,mid,beg,en);
        update(root*2+1,mid+1,en,beg,en);
        segt[root].val=1;
    }
}

int query(int root,int rst,int ren,int beg,int en)
{
    if (rst>en||ren<beg)
        return 0;
    if (rst>=beg&&ren<=en)
        return segt[root].val;
    pushdown(root);
    int mid=(rst+ren)/2;

    return (query(root*2,rst,mid,beg,en)&&query(root*2+1,mid+1,ren,beg,en));
}

int main()
{
    int n,len;
    while(~scanf("%d",&n))
    {
        int debugn=n;
        len=0;
        memset(segt,0,sizeof(segt));
        memset(ans,0,sizeof(ans));
        while(n--)
        {
            int nn,l,r,lens;
            scanf("%s",save);
            scanf("%d",&nn);
            lens=strlen(save);
            while(nn--)
            {
                scanf("%d",&l);
                r=l+lens-1;
                if (query(1,1,maxn,l,r))//���԰�query��update����һ��Ŷ
                    continue;
                else
                {
                    for (int kk=l;kk<=r;kk++)
                        ans[kk]=save[kk-l];
                    len=max(len,r);
                    if (debugn==4751)
                        cout<<l<<" "<<r<<endl;
                    update(1,1,maxn,l,r);
                    if (debugn==4751)
                        cout<<222222<<endl;
                }
            }
        }
        for (int k=1;k<=len;k++)
            if(ans[k]==0) printf("a");
            else printf("%c",ans[k]);
        printf("\n");
    }
    return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define maxn 1001000

using namespace std;

int main()
{
    int n,len;
    char s[maxn],save[maxn];
    while(~scanf("%d",&n))
    {
       // memset(s,0,sizeof(s));
       len=0;
        while(n--)
        {
            int nn,data,lens;
            scanf("%s",save);
            scanf("%d",&nn);
            lens=strlen(save);
            while(nn--)
            {
                scanf("%d",&data);
                int up=data+lens-1;
                len=max(len,up);
                for (int kk=data;kk<=up;kk++)
                    s[kk]=save[kk-data];
            }
        }

        for (int k=1;k<=len;k++)
        {
            if (s[k]=='\0') printf("%c",'a');
            else printf("%c",s[k]);
        }
        printf("\n");
    }
    return 0;
}


//其实就是把一段连续的，已经有值的串合并成一个集合，然后每一个集合都有一个范围，l到r
//对于每个串，每个读入的数，我们判断这个起始位置是否在集合中
//不在的话就新建一个集合范围是l到r
//在的话就看如果包含的话就过，如果一部分包含一部分没有的话就赋值并且更新l到r的值即可
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define maxn 1001000
using namespace std;

struct Fa
{
    int val,l,r;
};

Fa fa[maxn];
int find_r(int x)
{
    if (fa[x].val<0) return x;
    else {
        fa[x].val=find_r(fa[x].val);
        return fa[x].val;
    }
}

void join(int a,int b)
{
    int ra=find_r(a),rb=find_r(b);
    if (ra!=rb)
        fa[ra].val=rb;
    return;
}

int main()
{
    char ans[maxn],save[maxn];
    int n,len(0);
    for (int k=0;k<maxn;k++){
        fa[k].l=k;fa[k].r=k;fa[k].val=-1;
    }
    scanf("%d",&n);

    while(n--){
        int nn,lens,sl,sr,ll,rr;

        scanf("%s",save);
        scanf("%d",&nn);
        lens=strlen(save);
        while(nn--){
            scanf("%d",&sl);
            sr=sl+lens-1;
            len=max(len,sr);

            int fal=find_r(sl);
            ll=fa[fal].l;rr=fa[fal].r;

            if (ll<=sl&&rr>=sr) continue;
            else if (ll>sl&&rr<sr){
                fa[fal].l=sl;fa[fal].r=sr;

                for (int k=sl;k<=ll;k++){
                    join(k,fal);
                    ans[k]=save[k-sl];
                }

                for (int k=rr;k<=sr;k++){
                    join(k,fal);
                    ans[k]=save[k-sl];
                }
            }
            else if (ll>sl){
                fa[fal].l=sl;
                for (int k=sl;k<=ll;k++){
                    join(k,fal);
                    ans[k]=save[k-sl];
                }
            }
            else if (rr<sr){
                fa[fal].r=sr;
                for (int k=rr;k<=sr;k++){
                    join(k,fal);
                    ans[k]=save[k-sl];
                }
            }
        }
    }
    for (int k=1;k<=len;k++)
        if (ans[k]=='\0')
            printf("a");
        else printf("%c",ans[k]);
}//ababab


//��ʵ���ǰ�һ�������ģ��Ѿ���ֵ�Ĵ��ϲ���һ�����ϣ�Ȼ��ÿһ�����϶���һ����Χ��l��r
//����ÿ������ÿ����������������ж������ʼλ���Ƿ��ڼ�����
//���ڵĻ����½�һ�����Ϸ�Χ��l��r
//�ڵĻ��Ϳ���������Ļ��͹������һ���ְ���һ����û�еĻ��͸�ֵ���Ҹ���l��r��ֵ����
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define maxn 1001000
using namespace std;

struct Fa
{
    int val,l,r;
};

Fa fa[maxn];
int find_r(int x)
{
    if (fa[x].val<0) return x;
    else {
        fa[x].val=find_r(fa[x].val);
        return fa[x].val;
    }
}

void join(int a,int b)
{
    int ra=find_r(a),rb=find_r(b);
    if (ra!=rb)
        fa[ra].val=rb;
    return;
}

int main()
{
    char ans[maxn],save[maxn];
    int n,len(0);
    for (int k=0;k<maxn;k++){
        fa[k].l=k;fa[k].r=k;fa[k].val=-1;
    }
    scanf("%d",&n);

    while(n--){
        int nn,lens,sl,sr,ll,rr;

        scanf("%s",save);
        scanf("%d",&nn);
        lens=strlen(save);
        while(nn--){
            scanf("%d",&sl);
            sr=sl+lens-1;
            len=max(len,sr);

            int fal=find_r(sl);
            ll=fa[fal].l;rr=fa[fal].r;

            if (ll<=sl&&rr>=sr) continue;
            else if (ll>sl&&rr<sr){
                fa[fal].l=sl;fa[fal].r=sr;

                for (int k=sl;k<=ll;k++){
                    join(k,fal);
                    ans[k]=save[k-sl];
                }

                for (int k=rr;k<=sr;k++){
                    join(k,fal);
                    ans[k]=save[k-sl];
                }
            }
            else if (ll>sl){
                fa[fal].l=sl;
                for (int k=sl;k<=ll;k++){
                    join(k,fal);
                    ans[k]=save[k-sl];
                }
            }
            else if (rr<sr){
                fa[fal].r=sr;
                for (int k=rr;k<=sr;k++){
                    join(k,fal);
                    ans[k]=save[k-sl];
                }
            }
        }
    }
    for (int k=1;k<=len;k++)
        if (ans[k]=='\0')
            printf("a");
        else printf("%c",ans[k]);
}//ababab


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define maxn 1100000
#define inf 0x3f3f3f3f

using namespace std;

struct segtree
{
    int val,addmark;
};

segtree segt[maxn*4];
char ans[maxn];
char save[maxn];

void pushdown(int root)
{
    if (segt[root].addmark!=0)
    {
        segt[root*2].val=1;
        segt[root*2].addmark=1;
        segt[root*2+1].val=1;
        segt[root*2+1].addmark=1;
        segt[root].addmark=0;
    }
    return;
}

void update(int root,int rst,int ren,int beg,int en)
{
    if (rst>=beg&&ren<=en)
    {
        segt[root].val=1;
        segt[root].addmark=1;
    }
    else if (rst>en||ren<beg) {return;}
    else
    {
        pushdown(root);
        int mid=(rst+ren)/2;
        update(root*2,rst,mid,beg,en);
        update(root*2+1,mid+1,en,beg,en);
        segt[root].val=1;
    }
}

int query(int root,int rst,int ren,int beg,int en)
{
    if (rst>en||ren<beg)
        return 0;
    if (rst>=beg&&ren<=en)
        return segt[root].val;
    pushdown(root);
    int mid=(rst+ren)/2;

    return (query(root*2,rst,mid,beg,en)&&query(root*2+1,mid+1,ren,beg,en));
}

int main()
{
    int n,len;
    while(~scanf("%d",&n))
    {
        len=0;
        int debugn=n;
        memset(segt,0,sizeof(segt));
        memset(ans,0,sizeof(ans));
        if (n==4751)
            cout<<111111<<endl;
        while(n--)
        {
            int nn,l,r,lens;
            scanf("%s",save);
            scanf("%d",&nn);
            lens=strlen(save);
            if (debugn==4751)
                cout<<22222<<endl;
            while(nn--)
            {
                scanf("%d",&l);
                r=l+lens-1;
                if (query(1,1,maxn,l,r))//���԰�query��update����һ��Ŷ
                    continue;
                else
                {
                    for (int kk=l;kk<=r;kk++)
                        ans[kk]=save[kk-l];
                    len=max(len,r);
                    update(1,1,maxn,l,r);
                }
            }
            if (debugn==4751)
                cout<<333333<<endl;
        }
        for (int k=1;k<=len;k++)
            if(ans[k]==0) printf("a");
            else printf("%c",ans[k]);
        printf("\n");
    }
    return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define maxn 1100000
#define inf 0x3f3f3f3f

using namespace std;

struct segtree
{
    int val,addmark;
};

segtree segt[maxn*4];
char ans[maxn];
char save[maxn];

void pushdown(int root)
{
    if (segt[root].addmark!=0)
    {
        segt[root*2].val=1;
        segt[root*2].addmark=1;
        segt[root*2+1].val=1;
        segt[root*2+1].addmark=1;
        segt[root].addmark=0;
    }
    return;
}

void update(int root,int rst,int ren,int beg,int en)
{
    if (rst>=beg&&ren<=en)
    {
        segt[root].val=1;
        segt[root].addmark=1;
    }
    else if (rst>en||ren<beg) {return;}
    else
    {
        pushdown(root);
        int mid=(rst+ren)/2;
        update(root*2,rst,mid,beg,en);
        update(root*2+1,mid+1,en,beg,en);
        segt[root].val=1;
    }
}

int query(int root,int rst,int ren,int beg,int en)
{
    if (rst>en||ren<beg)
        return 0;
    if (rst>=beg&&ren<=en)
        return segt[root].val;
    pushdown(root);
    int mid=(rst+ren)/2;

    return (query(root*2,rst,mid,beg,en)&&query(root*2+1,mid+1,ren,beg,en));
}

int main()
{
    int n,len;
    while(~scanf("%d",&n))
    {
        len=0;
        memset(segt,0,sizeof(segt));
        memset(ans,0,sizeof(ans));
        while(n--)
        {
            int nn,l,r,lens;
            scanf("%s",save);
            scanf("%d",&nn);
            lens=strlen(save);

            while(nn--)
            {
                scanf("%d",&l);
                r=l+lens-1;
                if (query(1,1,maxn,l,r))//可以把query和update放在一起哦
                    continue;
                else
                {
                    for (int kk=l;kk<=r;kk++)
                        ans[kk]=save[kk-l];
                    len=max(len,r);
                    update(1,1,maxn,l,r);
                }
            }
        }
        for (int k=1;k<=len;k++)
            if(ans[k]==0) printf("a");
            else printf("%c",ans[k]);
        printf("\n");
    }
    return 0;
}


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <cmath>
    #include <map>
    #include <set>
    #include <stack>
    #include <queue>
    #include <vector>
    #include <bitset>

    using namespace std;

    #define LL long long
    const int INF = 0x3f3f3f3f;
    #define MAXN 500

    char s[2000006];
    char ch[2000005];
    int main()
    {
        int n,m,x;

        int tot=0;
        scanf("%d",&n);
        for(int i=0; i<n; i++)
        {
            scanf("%s%d",&ch,&m);
            int k=strlen(ch);
            int t=-INF;
            for(int j=0; j<m; j++)
            {
                scanf("%d",&x);
                x--;
                tot=max(x+k,tot);
                for(int l=max(x,t); l<x+k; l++)
                    s[l]=ch[l-x];
                t=x+k;
            }
        }
        for(int i=0; i<tot; i++)
            if(s[i]=='\0')
                printf("a");
            else
                printf("%c",s[i]);
        printf("\n");

        return 0;
    }


//其实就是把一段连续的，已经有值的串合并成一个集合，然后每一个集合都有一个范围，l到r
//对于每个串，每个读入的数，我们判断这个起始位置是否在集合中
//不在的话就新建一个集合范围是l到r
//在的话就看如果包含的话就过，如果一部分包含一部分没有的话就赋值并且更新l到r的值即可
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define maxn 1001000
using namespace std;

struct Fa
{
    int val,l,r;
};

Fa fa[maxn];
int find_r(int x)
{
    if (fa[x].val<0) return x;
    else {
        fa[x].val=find_r(fa[x].val);
        return fa[x].val;
    }
}

void join(int a,int b)
{
    int ra=find_r(a),rb=find_r(b);
    if (ra!=rb)
        fa[ra].val=rb;
    return;
}

int main()
{
    char ans[maxn],save[maxn];
    int n,len(0);
    for (int k=0;k<maxn;k++){
        fa[k].l=k;fa[k].r=k;fa[k].val=-1;
    }
    scanf("%d",&n);

    while(n--){
        int nn,lens,sl,sr,ll,rr;

        scanf("%s",save);
        scanf("%d",&nn);
        lens=strlen(save);
        while(nn--){
            scanf("%d",&sl);
            sr=sl+lens-1;
            len=max(len,sr);

            int fal=find_r(sl);
            ll=fa[fal].l;rr=fa[fal].r;

            if (ll<=sl&&rr>=sr) {
                if((ll==sl)&&(rr==sr)&&(ll==rr))
                    ans[ll]=save[ll-ll];
            }
            else if (ll>sl&&rr<sr){
                fa[fal].l=sl;fa[fal].r=sr;

                for (int k=sl;k<=ll;k++){
                    join(k,fal);
                    ans[k]=save[k-sl];
                }

                for (int k=rr;k<=sr;k++){
                    join(k,fal);
                    ans[k]=save[k-sl];
                }
            }
            else if (ll>sl){
                fa[fal].l=sl;
                for (int k=sl;k<=ll;k++){
                    join(k,fal);
                    ans[k]=save[k-sl];
                }
            }
            else if (rr<sr){
                fa[fal].r=sr;
                for (int k=rr;k<=sr;k++){
                    join(k,fal);
                    ans[k]=save[k-sl];
                }
            }
        }
    }
    for (int k=1;k<=len;k++)
        if (ans[k]=='\0')
            printf("a");
        else printf("%c",ans[k]);
}//ababab


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define maxn 1100000
#define inf 0x3f3f3f3f

using namespace std;

struct segtree
{
    int val,addmark;
};

segtree segt[maxn*4];
char ans[maxn];
char save[maxn];

void pushdown(int root)
{
    if (segt[root].addmark!=0)
    {
        segt[root*2].val=1;
        segt[root*2].addmark=1;
        segt[root*2+1].val=1;
        segt[root*2+1].addmark=1;
        segt[root].addmark=0;
    }
    return;
}

void update(int root,int rst,int ren,int beg,int en)
{
    if (rst>=beg&&ren<=en)
    {
        segt[root].val=1;
        segt[root].addmark=1;
    }
    else if (rst>en||ren<beg) {return;}
    else
    {
        pushdown(root);
        int mid=(rst+ren)/2;
        update(root*2,rst,mid,beg,en);
        update(root*2+1,mid+1,en,beg,en);
        segt[root].val=1;
    }
}

int query(int root,int rst,int ren,int beg,int en)
{
    if (rst>en||ren<beg)
        return 0;
    if (rst>=beg&&ren<=en)
        return segt[root].val;
    pushdown(root);
    int mid=(rst+ren)/2;

    return (query(root*2,rst,mid,beg,en)&&query(root*2+1,mid+1,ren,beg,en));
}

int main()
{
    int n,len;
    while(~scanf("%d",&n))
    {
        len=0;
        memset(segt,0,sizeof(segt));
        memset(ans,0,sizeof(ans));
        if (n==4751)
            cout<<111111<<endl;
        while(n--)
        {
            int nn,l,r,lens;
            scanf("%s",save);if (n==4751)
                cout<<222222<<endl;
            scanf("%d",&nn);
            if (n==4751)
                cout<<33333<<endl;
            lens=strlen(save);
            if (n==4751)
                cout<<44444<<endl;

            while(nn--)
            {
                scanf("%d",&l);
                r=l+lens-1;
                if (query(1,1,maxn,l,r))//���԰�query��update����һ��Ŷ
                    continue;
                else
                {
                    for (int kk=l;kk<=r;kk++)
                        ans[kk]=save[kk-l];
                    len=max(len,r);
                    update(1,1,maxn,l,r);
                }
            }
            if (n==4751)
                cout<<333333<<endl;
        }
        for (int k=1;k<=len;k++)
            if(ans[k]==0) printf("a");
            else printf("%c",ans[k]);
        printf("\n");
    }
    return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define maxn 1100000
#define inf 0x3f3f3f3f

using namespace std;

struct segtree
{
    int val,addmark;
};

segtree segt[maxn*4];
char ans[maxn];
char save[maxn];

void pushdown(int root)
{
    if (segt[root].addmark!=0)
    {
        segt[root*2].val=1;
        segt[root*2].addmark=1;
        segt[root*2+1].val=1;
        segt[root*2+1].addmark=1;
        segt[root].addmark=0;
    }
    return;
}

void update(int root,int rst,int ren,int beg,int en)
{
    if (rst>=beg&&ren<=en)
    {
        segt[root].val=1;
        segt[root].addmark=1;
    }
    else if (rst>en||ren<beg) {return;}
    else
    {
        pushdown(root);
        int mid=(rst+ren)/2;
        update(root*2,rst,mid,beg,en);
        update(root*2+1,mid+1,en,beg,en);
        segt[root].val=1;
    }
}

int query(int root,int rst,int ren,int beg,int en)
{
    if (rst>en||ren<beg)
        return 0;
    if (rst>=beg&&ren<=en)
        return segt[root].val;
    pushdown(root);
    int mid=(rst+ren)/2;

    return (query(root*2,rst,mid,beg,en)&&query(root*2+1,mid+1,ren,beg,en));
}

int main()
{
    int n,len;
    while(~scanf("%d",&n))
    {
        int debugn=n;
        len=0;
        memset(segt,0,sizeof(segt));
        memset(ans,0,sizeof(ans));
        while(n--)
        {
            int nn,l,r,lens;
            scanf("%s",save);
            scanf("%d",&nn);
            lens=strlen(save);
            while(nn--)
            {
                scanf("%d",&l);
                r=l+lens-1;
                if (query(1,1,maxn,l,r))//���԰�query��update����һ��Ŷ
                    continue;
                else
                {
                    for (int kk=l;kk<=r;kk++)
                        ans[kk]=save[kk-l];
                    len=max(len,r);
                    if (debugn==4751)
                        cout<<111111<<endl;
                    update(1,1,maxn,l,r);
                    if (debugn==4751)
                        cout<<222222<<endl;
                }
            }
        }
        for (int k=1;k<=len;k++)
            if(ans[k]==0) printf("a");
            else printf("%c",ans[k]);
        printf("\n");
    }
    return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define maxn 1100000
#define inf 0x3f3f3f3f

using namespace std;

struct segtree
{
    int val,addmark;
};

segtree segt[maxn*4];
char ans[maxn];
char save[maxn];

void pushdown(int root)
{
    if (segt[root].addmark!=0)
    {
        segt[root*2].val=1;
        segt[root*2].addmark=1;
        segt[root*2+1].val=1;
        segt[root*2+1].addmark=1;
        segt[root].addmark=0;
    }
    return;
}

void update(int root,int rst,int ren,int beg,int en)
{
    if (rst>=beg&&ren<=en)
    {
        segt[root].val=1;
        segt[root].addmark=1;
    }
    else if (rst>en||ren<beg) {return;}
    else
    {
        pushdown(root);
        int mid=(rst+ren)/2;
        update(root*2,rst,mid,beg,en);
        update(root*2+1,mid+1,en,beg,en);
        segt[root].val=1;
    }
}

int query(int root,int rst,int ren,int beg,int en)
{
    if (rst>en||ren<beg)
        return 0;
    if (rst>=beg&&ren<=en)
        return segt[root].val;
    pushdown(root);
    int mid=(rst+ren)/2;

    return (query(root*2,rst,mid,beg,en)&&query(root*2+1,mid+1,ren,beg,en));
}

int main()
{
    int n,len;
    while(~scanf("%d",&n))
    {
        len=0;
        memset(segt,0,sizeof(segt));
        memset(ans,0,sizeof(ans));
        if (n==4751)
            cout<<111111<<endl;
        while(n--)
        {
            int nn,l,r,lens;
            scanf("%s",save);
            scanf("%d",&nn);
            lens=strlen(save);
            if (n==4751)
                cout<<222222<<endl;
            while(nn--)
            {
                scanf("%d",&l);
                r=l+lens-1;
                if (query(1,1,maxn,l,r))//���԰�query��update����һ��Ŷ
                    continue;
                else
                {
                    for (int kk=l;kk<=r;kk++)
                        ans[kk]=save[kk-l];
                    len=max(len,r);
                    update(1,1,maxn,l,r);
                }
            }
            if (n==4751)
                cout<<333333<<endl;
        }
        for (int k=1;k<=len;k++)
            if(ans[k]==0) printf("a");
            else printf("%c",ans[k]);
        printf("\n");
    }
    return 0;
}


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef long double ldb;

#define fi first
#define se second
#define pb push_back
#define mkp make_pair
#define all(v) (v).begin(),(v).end()
#define dbg(a) cout << #a << " = " << a << endl

int main() {

	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	int n;
	cin >> n;
	vector<string> t(n);
	vector<vector<bool> > st(1e6 + 10);
	for(int i = 0; i < n; i++) {
		st[i].assign(26, false);
	}
	map<int, pii> mp;
	int mx = 0;
	for(int i = 0; i < n; i++) {
		int k;
		cin >> t[i] >> k;
		for(int j = 0; j < k; j++) {
			int x;
			cin >> x;
			if(mp.find(x) == mp.end() || t[mp[x].fi].size() < t[i].size())
				mp[x] = mkp(i, 0);
			mx = max(x + (int) t[i].size() - 1, mx);
			st[x][t[i][0] - 'a'] = true;
		}
	}
	string ans(mx + 1, '$');
	for(int k = 1; k <= ans.size(); k++) {
		if(mp.find(k) == mp.end()) continue;
		int i = mp[k].fi;
		int j = mp[k].se;
		ans[k] = t[i][j];
		if(j + 1 < t[i].size() && mp.find(k + 1) == mp.end()) {
			mp[k + 1] = mkp(i, j + 1);
		}
	}

	for(int i = 1; i <= ans.size(); i++) {
		if(ans[i] == '$') {
			ans[i] = 'a';
		}
	}

	cout << ans.substr(1);

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef long double ldb;

#define fi first
#define se second
#define pb push_back
#define mkp make_pair
#define all(v) (v).begin(),(v).end()
#define dbg(a) cout << #a << " = " << a << endl

int main() {

	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	int n;
	cin >> n;
	vector<string> t(n);
	vector<vector<bool> > st(1e6 + 10);
	for(int i = 0; i < n; i++) {
		st[i].assign(26, false);
	}
	map<int, pii> mp;
	int mx = 0;
	for(int i = 0; i < n; i++) {
		int k;
		cin >> t[i] >> k;
		for(int j = 0; j < k; j++) {
			int x;
			cin >> x;
			if(mp.find(x) == mp.end() || t[mp[x].fi].size() < t[i].size())
				mp[x] = mkp(i, 0);
			mx = max(x + (int) t[i].size() - 1, mx);
			st[x][t[i][0] - 'a'] = true;
		}
	}
	string ans(mx + 1, '$');
	for(int k = 1; k <= ans.size(); k++) {
		if(mp.find(k) == mp.end()) continue;
		int i = mp[k].fi;
		int j = mp[k].se;
		ans[k] = t[i][j];
		if(j + 1 < t[i].size() && (mp.find(k + 1) == mp.end() || t[mp[k+1].fi].size() < t[i].size())) {
			mp[k + 1] = mkp(i, j + 1);
		}
	}

	for(int i = 1; i <= ans.size(); i++) {
		if(ans[i] == '$') {
			ans[i] = 'a';
		}
	}

	cout << ans.substr(1);

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef long double ldb;

#define fi first
#define se second
#define pb push_back
#define mkp make_pair
#define all(v) (v).begin(),(v).end()
#define dbg(a) cout << #a << " = " << a << endl

int main() {

	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	int n;
	cin >> n;
	vector<string> t(n);
	vector<vector<bool> > st(1e6 + 10);
	for(int i = 0; i < n; i++) {
		st[i].assign(26, false);
	}
	vector<pii> mp(1e6 + 10, mkp(-1, -1));
	int mx = 0;
	for(int i = 0; i < n; i++) {
		int k;
		cin >> t[i] >> k;
		for(int j = 0; j < k; j++) {
			int x;
			cin >> x;
			if(mp[x].fi == -1 || t[mp[x].fi].size() < t[i].size())
				mp[x] = mkp(i, 0);
			mx = max(x + (int) t[i].size() - 1, mx);
			st[x][t[i][0] - 'a'] = true;
		}
	}
	string ans(mx + 1, '$');
	for(int k = 1; k <= ans.size(); k++) {
		if(mp[k].fi == -1) continue;
		int i = mp[k].fi;
		int j = mp[k].se;
		ans[k] = t[i][j];
		if(j + 1 < t[i].size()) {
			if(mp[k + 1].fi == -1) mp[k + 1] = mkp(i, j + 1);
			else {
				int ii = mp[k+1].fi;
				int jj = mp[k+1].se;
				if(t[i].size() - j > t[ii].size() - jj) {
					mp[k + 1] = mkp(i, j + 1);
				}
			}
		}
	}

	for(int i = 1; i <= ans.size(); i++) {
		if(ans[i] == '$') {
			ans[i] = 'a';
		}
	}

	cout << ans.substr(1);

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef long double ldb;

#define fi first
#define se second
#define pb push_back
#define mkp make_pair
#define all(v) (v).begin(),(v).end()
#define dbg(a) cout << #a << " = " << a << endl

int main() {

	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	int n;
	cin >> n;
	vector<string> t(n);
	vector<vector<bool> > st(1e6 + 10);
	for(int i = 0; i < n; i++) {
		st[i].assign(26, false);
	}
	map<int, pii> mp;
	int mx = 0;
	for(int i = 0; i < n; i++) {
		int k;
		cin >> t[i] >> k;
		for(int j = 0; j < k; j++) {
			int x;
			cin >> x;
			if(mp.find(x) == mp.end() || t[mp[x].fi].size() < t[i].size())
				mp[x] = mkp(i, 0);
			mx = max(x + (int) t[i].size() - 1, mx);
			st[x][t[i][0] - 'a'] = true;
		}
	}
	string ans(mx + 1, '$');
	for(int k = 1; k <= ans.size(); k++) {
		if(mp.find(k) == mp.end()) continue;
		int i = mp[k].fi;
		int j = mp[k].se;
		ans[k] = t[i][j];
		if(j + 1 < t[i].size()) {
			if(mp.find(k + 1) == mp.end()) mp[k + 1] = mkp(i, j + 1);
			else {
				int ii = mp[k+1].fi;
				int jj = mp[k+1].se;
				if(t[i].size() - j > t[ii].size() - jj) {
					mp[k + 1] = mkp(i, j + 1);
				}
			}
		}
	}

	for(int i = 1; i <= ans.size(); i++) {
		if(ans[i] == '$') {
			ans[i] = 'a';
		}
	}

	cout << ans.substr(1);

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef long double ldb;

#define fi first
#define se second
#define pb push_back
#define mkp make_pair
#define all(v) (v).begin(),(v).end()
#define dbg(a) cout << #a << " = " << a << endl

int main() {

	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	int n;
	cin >> n;
	vector<string> t(n);
	vector<pii> mp(2 * 1e6 + 10, mkp(-1, -1));
	int mx = 0;
	for(int i = 0; i < n; i++) {
		int k;
		cin >> t[i] >> k;
		for(int j = 0; j < k; j++) {
			int x;
			cin >> x;
			if(mp[x].fi == -1 || t[mp[x].fi].size() < t[i].size())
				mp[x] = mkp(i, 0);
			mx = max(x + (int) t[i].size() - 1, mx);
		}
	}
	string ans(mx + 1, '$');
	for(int k = 1; k <= ans.size(); k++) {
		if(mp[k].fi == -1) continue;
		int i = mp[k].fi;
		int j = mp[k].se;
		ans[k] = t[i][j];
		if(j + 1 < t[i].size()) {
			if(mp[k + 1].fi == -1) mp[k + 1] = mkp(i, j + 1);
			else {
				int ii = mp[k+1].fi;
				int jj = mp[k+1].se;
				if(t[i].size() - j > t[ii].size() - jj) {
					mp[k + 1] = mkp(i, j + 1);
				}
			}
		}
	}

	for(int i = 1; i <= ans.size(); i++) {
		if(ans[i] == '$') {
			ans[i] = 'a';
		}
	}

	cout << ans.substr(1);

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef long double ldb;

#define fi first
#define se second
#define pb push_back
#define mkp make_pair
#define all(v) (v).begin(),(v).end()
#define dbg(a) cout << #a << " = " << a << endl

int main() {

	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	ios_base::sync_with_stdio(false);
	cin.tie(0);

	int n;
	cin >> n;
	vector<string> t(n);
	vector<pii> mp(2 * 1e6 + 10, mkp(-1, -1));
	int mx = 0;
	for(int i = 0; i < n; i++) {
		int k;
		cin >> t[i] >> k;
		for(int j = 0; j < k; j++) {
			int x;
			cin >> x;
			if(mp[x].fi == -1 || t[mp[x].fi].size() < t[i].size())
				mp[x] = mkp(i, 0);
			mx = max(x + (int) t[i].size() - 1, mx);
		}
	}
	string ans(mx + 1, '$');
	for(int k = 1; k <= ans.size(); k++) {
		if(mp[k].fi == -1) continue;
		int i = mp[k].fi;
		int j = mp[k].se;
		ans[k] = t[i][j];
		if(j + 1 < t[i].size()) {
			if(mp[k + 1].fi == -1) mp[k + 1] = mkp(i, j + 1);
			else {
				int ii = mp[k+1].fi;
				int jj = mp[k+1].se;
				if(t[i].size() - j > t[ii].size() - jj) {
					mp[k + 1] = mkp(i, j + 1);
				}
			}
		}
	}

	for(int i = 1; i <= ans.size(); i++) {
		if(ans[i] == '$') {
			ans[i] = 'a';
		}
	}

	cout << ans.substr(1);

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef long double ldb;

#define fi first
#define se second
#define pb push_back
#define mkp make_pair
#define all(v) (v).begin(),(v).end()
#define dbg(a) cout << #a << " = " << a << endl

int main() {

	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	int n;
	cin >> n;
	vector<string> t(n);
	for(int i = 0; i < n; i++) {
		st[i].assign(26, false);
	}
	vector<pii> mp(2 * 1e6 + 10, mkp(-1, -1));
	int mx = 0;
	for(int i = 0; i < n; i++) {
		int k;
		cin >> t[i] >> k;
		for(int j = 0; j < k; j++) {
			int x;
			cin >> x;
			if(mp[x].fi == -1 || t[mp[x].fi].size() < t[i].size())
				mp[x] = mkp(i, 0);
			mx = max(x + (int) t[i].size() - 1, mx);
		}
	}
	string ans(mx + 1, '$');
	for(int k = 1; k <= ans.size(); k++) {
		if(mp[k].fi == -1) continue;
		int i = mp[k].fi;
		int j = mp[k].se;
		ans[k] = t[i][j];
		if(j + 1 < t[i].size()) {
			if(mp[k + 1].fi == -1) mp[k + 1] = mkp(i, j + 1);
			else {
				int ii = mp[k+1].fi;
				int jj = mp[k+1].se;
				if(t[i].size() - j > t[ii].size() - jj) {
					mp[k + 1] = mkp(i, j + 1);
				}
			}
		}
	}

	for(int i = 1; i <= ans.size(); i++) {
		if(ans[i] == '$') {
			ans[i] = 'a';
		}
	}

	cout << ans.substr(1);

	return 0;
}


#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxN=10000000 + 100;
char ans[maxN+1],s[maxN+1];
int n,tot=0;
int main()
{
    memset(ans,'a',sizeof(ans));
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s",s);
        int len=strlen(s);
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int place;
            scanf("%d",&place);
            place--;
            tot=max(tot,place+len);
            for(int i=place;i<place+len;i++) ans[i]=s[i-place];
        }
    }
    for(int i=0;i<tot;i++) printf("%c",ans[i]);
    return 0;
}


#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxN=1000000 + 100;
char ans[maxN+1],s[maxN+1];
int n,tot=0;
int main()
{
    memset(ans,'a',sizeof(ans));
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s",s);
        int len=strlen(s);
        int t;
        scanf("%d",&t);
        int maxT=0;
        while(t--)
        {
            int place;
            scanf("%d",&place);
            place--;
            tot=max(tot,place+len);
            place=max(maxT,place);
            for(int i=place;i<place+len;i++)
                ans[i]=s[i-place];
            maxT=place+len-1;
        }
    }
    for(int i=0;i<tot;i++) printf("%c",ans[i]);
    return 0;
}


#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxN=1000000 + 100;
char ans[maxN+1],s[maxN+1];
int n,tot=0;
int main()
{
    memset(ans,'a',sizeof(ans));
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s",s);
        int len=strlen(s);
        int t;
        scanf("%d",&t);
        int maxT=0;
        while(t--)
        {
            int place;
            scanf("%d",&place);
            place--;
            tot=max(tot,place+len);
            int begin=max(maxT,place);
            for(int i=begin;i<place+len;i++)
                ans[i]=s[i-place];
            maxT=place+len-1;
        }
    }
    for(int i=0;i<tot;i++) printf("%c",ans[i]);
    return 0;
}


#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxN=10000000 + 100;
char ans[maxN+1],s[maxN+1];
int n,tot=0;
int main()
{
    memset(ans,'a',sizeof(ans));
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s",s);
        int len=strlen(s);
        int t;
        scanf("%d",&t);
        int maxT=0;
        while(t--)
        {
            int place;
            scanf("%d",&place);
            place--;
            tot=max(tot,place+len);
            int begin=max(maxT,place);
            for(int i=begin;i<place+len;i++)
                ans[i]=s[i-place];
            maxT=place+len-1;
        }
    }
    for(int i=0;i<tot;i++) printf("%c",ans[i]);
    return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define INF 12345678
#define tam 2200000
#define fi first
#define se second
#define Sdecmp 555
using namespace std;
bool bo[tam*4];int maxtam=0;
struct node{
	bool valid;
	char valor;
	node(){}

};
node tree[tam*4];
char txt[tam];int pos;
void update(int node,int iz,int der,int pi,int pd)
{
	if (tree[node].valid==true)
		return;
	if (iz>pd|| der<pi)
		return;
	if (iz==der)
	{
		maxtam=max(maxtam,iz);
		//cout<<iz<<" "<<txt.substr((der-pos),1)<<endl;
		tree[node].valor=txt[der-pos];
		tree[node].valid=true;
		return;
	}
	int new_node=(node*2),mid=(iz+der)/2;
	update(new_node,iz,mid,pi,pd);
	update(new_node+1,mid+1,der,pi,pd);
	if (tree[new_node].valid+tree[new_node+1].valid==2)
		tree[node].valid=1;

}
void terminar(int node,int iz,int der)
{
	if (iz>maxtam)
		return;
	if (iz==der)
	{
		if (tree[node].valid==false)
			cout<<'a';
		else
			cout<<tree[node].valor;
		return;
	}
	int new_node=(node*2),mid=(iz+der)/2;
	terminar(new_node,iz,mid);
	terminar(new_node+1,mid+1,der);
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	for (int i = 0; i < tam*4; ++i)
	{
		tree[i].valid=false;
	}

	int n;
	cin>>n;
	int cuantos;
	for (int i = 0; i < n; ++i)
	{
		cin>>txt>>cuantos;
		for (int j = 0; j < cuantos; ++j)
		{
			cin>>pos;
			update(1,1,tam,pos,pos+strlen(txt)-1);
		}
	}
	terminar(1,1,tam);
}


#include <bits/stdc++.h>
#define ll long long
#define INF 12345678
#define tam 1200000
#define fi first
#define se second
#define Sdecmp 555
using namespace std;
bool bo[tam*4];int maxtam=0;
struct node{
	bool valid;
	string valor;
	node(){}

};
node tree[tam*4];
string txt;int pos;
void update(int node,int iz,int der,int pi,int pd)
{
	if (tree[node].valid==true)
		return;
	if (iz>pd|| der<pi)
		return;
	if (iz==der)
	{
		maxtam=max(maxtam,iz);
		//cout<<iz<<" "<<txt.substr((der-pos),1)<<endl;
		tree[node].valor=txt.substr((der-pos),1);
		tree[node].valid=true;
		return;
	}
	int new_node=(node*2),mid=(iz+der)/2;
	update(new_node,iz,mid,pi,pd);
	update(new_node+1,mid+1,der,pi,pd);
	if (tree[new_node].valid+tree[new_node+1].valid==2)
		tree[node].valid=1;

}
void terminar(int node,int iz,int der)
{
	if (iz>maxtam)
		return;
	if (iz==der)
	{
		if (tree[node].valid==false)
			cout<<"a";
		else
			cout<<tree[node].valor;
		return;
	}
	int new_node=(node*2),mid=(iz+der)/2;
	terminar(new_node,iz,mid);
	terminar(new_node+1,mid+1,der);
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	for (int i = 0; i < tam*4; ++i)
	{
		tree[i].valid=false;
	}

	int n;
	cin>>n;
	int cuantos;
	for (int i = 0; i < n; ++i)
	{
		cin>>txt>>cuantos;
		for (int j = 0; j < cuantos; ++j)
		{
			cin>>pos;
			update(1,1,tam,pos,pos+txt.size()-1);
		}
	}
	terminar(1,1,tam);
}


#include <bits/stdc++.h>
#define ll long long
#define INF 12345678
#define tam 2200000
#define fi first
#define se second
#define Sdecmp 555
using namespace std;
bool bo[tam*4];int maxtam=0;
struct node{
	bool valid;
	string valor;
	node(){}

};
node tree[tam*4];
string txt;int pos;
void update(int node,int iz,int der,int pi,int pd)
{
	if (tree[node].valid==true)
		return;
	if (iz>pd|| der<pi)
		return;
	if (iz==der)
	{
		maxtam=max(maxtam,iz);
		//cout<<iz<<" "<<txt.substr((der-pos),1)<<endl;
		tree[node].valor=txt.substr((der-pos),1);
		tree[node].valid=true;
		return;
	}
	int new_node=(node*2),mid=(iz+der)/2;
	update(new_node,iz,mid,pi,pd);
	update(new_node+1,mid+1,der,pi,pd);
	if (tree[new_node].valid+tree[new_node+1].valid==2)
		tree[node].valid=1;

}
void terminar(int node,int iz,int der)
{
	if (iz>maxtam)
		return;
	if (iz==der)
	{
		if (tree[node].valid==false)
			cout<<"a";
		else
			cout<<tree[node].valor;
		return;
	}
	int new_node=(node*2),mid=(iz+der)/2;
	terminar(new_node,iz,mid);
	terminar(new_node+1,mid+1,der);
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	for (int i = 0; i < tam*4; ++i)
	{
		tree[i].valid=false;
	}

	int n;
	cin>>n;
	int cuantos;
	for (int i = 0; i < n; ++i)
	{
		cin>>txt>>cuantos;
		for (int j = 0; j < cuantos; ++j)
		{
			cin>>pos;
			update(1,1,tam,pos,pos+txt.size()-1);
		}
	}
	terminar(1,1,tam);
}


#include <bits/stdc++.h>
#define ll long long
#define INF 12345678
#define tam 2200000
#define fi first
#define se second
#define Sdecmp 555
using namespace std;
bool bo[tam*4];int maxtam=0;
struct node{
	bool valid;
	char valor;
	node(){}

};
node tree[tam*4];
string txt;int pos;
void update(int node,int iz,int der,int pi,int pd)
{
	if (tree[node].valid==true)
		return;
	if (iz>pd|| der<pi)
		return;
	if (iz==der)
	{
		maxtam=max(maxtam,iz);
		//cout<<iz<<" "<<txt.substr((der-pos),1)<<endl;
		tree[node].valor=txt[der-pos];
		tree[node].valid=true;
		return;
	}
	int new_node=(node*2),mid=(iz+der)/2;
	update(new_node,iz,mid,pi,pd);
	update(new_node+1,mid+1,der,pi,pd);
	if (tree[new_node].valid+tree[new_node+1].valid==2)
		tree[node].valid=1;

}
void terminar(int node,int iz,int der)
{
	if (iz>maxtam)
		return;
	if (iz==der)
	{
		if (tree[node].valid==false)
			cout<<'a';
		else
			cout<<tree[node].valor;
		return;
	}
	int new_node=(node*2),mid=(iz+der)/2;
	terminar(new_node,iz,mid);
	terminar(new_node+1,mid+1,der);
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	for (int i = 0; i < tam*4; ++i)
	{
		tree[i].valid=false;
	}

	int n;
	cin>>n;
	int cuantos;
	for (int i = 0; i < n; ++i)
	{
		cin>>txt>>cuantos;
		for (int j = 0; j < cuantos; ++j)
		{
			cin>>pos;
			update(1,1,tam,pos,pos+txt.size()-1);
		}
	}
	terminar(1,1,tam);
}


#include <bits/stdc++.h>
#define ll long long
#define INF 12345678
#define tam 3200000
#define fi first
#define se second
#define Sdecmp 555
using namespace std;
bool bo[tam*4];int maxtam=0;
struct node{
	bool valid;
	string valor;
	node(){}

};
node tree[tam*4];
string txt;int pos;
void update(int node,int iz,int der,int pi,int pd)
{
	if (tree[node].valid==true)
		return;
	if (iz>pd|| der<pi)
		return;
	if (iz==der)
	{
		maxtam=max(maxtam,iz);
		//cout<<iz<<" "<<txt.substr((der-pos),1)<<endl;
		tree[node].valor=txt.substr((der-pos),1);
		tree[node].valid=true;
		return;
	}
	int new_node=(node*2),mid=(iz+der)/2;
	update(new_node,iz,mid,pi,pd);
	update(new_node+1,mid+1,der,pi,pd);
	if (tree[new_node].valid+tree[new_node+1].valid==2)
		tree[node].valid=1;

}
void terminar(int node,int iz,int der)
{
	if (iz>maxtam)
		return;
	if (iz==der)
	{
		if (tree[node].valid==false)
			cout<<"a";
		else
			cout<<tree[node].valor;
		return;
	}
	int new_node=(node*2),mid=(iz+der)/2;
	terminar(new_node,iz,mid);
	terminar(new_node+1,mid+1,der);
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	for (int i = 0; i < tam*4; ++i)
	{
		tree[i].valid=false;
	}

	int n;
	cin>>n;
	int cuantos;
	for (int i = 0; i < n; ++i)
	{
		cin>>txt>>cuantos;
		for (int j = 0; j < cuantos; ++j)
		{
			cin>>pos;
			update(1,1,tam,pos,pos+txt.size()-1);
		}
	}
	terminar(1,1,tam);
}


#include <bits/stdc++.h>
#define ll long long
#define INF 12345678
#define tam 2200000
#define fi first
#define se second
#define Sdecmp 555
using namespace std;
bool bo[tam*4];int maxtam=0;
struct node{
	bool valid;
	char valor;
	node(){}

};
node tree[tam*4];
char txt[tam];int pos;
void update(int node,int iz,int der,int pi,int pd)
{
	if (tree[node].valid==true)
		return;
	if (iz>pd|| der<pi)
		return;
	if (iz==der)
	{
		maxtam=max(maxtam,iz);
		//cout<<iz<<" "<<txt.substr((der-pos),1)<<endl;
		tree[node].valor=txt[der-pos];
		tree[node].valid=true;
		return;
	}
	int new_node=(node*2),mid=(iz+der)/2;
	update(new_node,iz,mid,pi,pd);
	update(new_node+1,mid+1,der,pi,pd);
	if (tree[new_node].valid+tree[new_node+1].valid==2)
		tree[node].valid=1;

}
void terminar(int node,int iz,int der)
{
	if (iz>maxtam)
		return;
	if (iz==der)
	{
		if (tree[node].valid==false)
			cout<<'a';
		else
			cout<<tree[node].valor;
		return;
	}
	int new_node=(node*2),mid=(iz+der)/2;
	terminar(new_node,iz,mid);
	terminar(new_node+1,mid+1,der);
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	for (int i = 0; i < tam*4; ++i)
	{
		tree[i].valid=false;
	}

	int n;
	//cin>>n;
	scanf("%d",&n);
	int cuantos;
	for (int i = 0; i < n; ++i)
	{
		scanf("%s %d",txt,&cuantos);
		//cin>>txt>>cuantos;
		for (int j = 0; j < cuantos; ++j)
		{
			scanf("%d",&pos);
			//cin>>pos;
			update(1,1,tam,pos,pos+strlen(txt)-1);
		}
	}
	terminar(1,1,tam);
}


#include <bits/stdc++.h>
#define ll long long
#define INF 12345678
#define tam 1200000
#define fi first
#define se second
#define Sdecmp 555
using namespace std;
bool bo[tam*4];int maxtam=0;
struct node{
	bool valid;
	string valor;
	node(){}

};
node tree[tam*4];
string txt;int pos;
void update(int node,int iz,int der,int pi,int pd)
{
	if (tree[node].valid==true)
		return;
	if (iz>pd|| der<pi)
		return;
	if (iz==der)
	{
		maxtam=max(maxtam,iz);
		//cout<<iz<<" "<<txt.substr((der-pos)%txt.size(),1)<<endl;
		tree[node].valor=txt.substr((der-pos)%txt.size(),1);
		tree[node].valid=true;
		return;
	}
	int new_node=(node*2),mid=(iz+der)/2;
	update(new_node,iz,mid,pi,pd);
	update(new_node+1,mid+1,der,pi,pd);
	if (tree[new_node].valid+tree[new_node+1].valid==2)
		tree[node].valid=1;

}
void terminar(int node,int iz,int der)
{
	if (iz>maxtam)
		return;
	if (iz==der)
	{
		if (tree[node].valid==false)
			cout<<"a";
		else
			cout<<tree[node].valor;
		return;
	}
	int new_node=(node*2),mid=(iz+der)/2;
	terminar(new_node,iz,mid);
	terminar(new_node+1,mid+1,der);
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	for (int i = 0; i < tam*4; ++i)
	{
		tree[i].valid=false;
	}

	int n;
	cin>>n;
	int cuantos;
	for (int i = 0; i < n; ++i)
	{
		cin>>txt>>cuantos;
		for (int i = 0; i < cuantos; ++i)
		{
			cin>>pos;
			update(1,1,tam,pos,pos+txt.size()-1);
		}
	}
	terminar(1,1,tam);
}


#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include <cmath>
#include <cstdio>
#include <cctype>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <complex>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cwchar>
#include <cwctype>
#include <exception>
#include <locale>
#include <numeric>
#include <new>
#include <stdexcept>
#include <limits>
#include <valarray>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <list>
#include <utility>
#include <bitset>
#include <algorithm>
#include <functional>
using namespace std;
#define mp make_pair
#define sc second
#define fs first
#define MAX(a,b) (((a)>(b))?(a):(b))
typedef pair < int , int > pii;
int n,m,k,d,t,len;
char res[3000005],inp[1000005];
vector < pii > incs[1000005];
int main(){
	scanf("%d",&n);
	int xb,x2,ln=0,x3;
	memset(res,0,sizeof(res));
	while(n--){
		scanf("%s",inp+ln);
		scanf("%d",&k);
		int sm=ln;
		while(inp[ln]!=0) ln++;
		for(xb=0;xb<k;xb++){
			scanf("%d",&t);
			len=MAX(len,t+ln-sm-1);
			incs[t-1].push_back(mp(ln-sm,sm));
		}
	}
	x2=0;
	for(xb=0;xb<len && x2<len;xb++){
		for(x3=0;x3<incs[xb].size();x3++){
			for(;x2<len && x2<=xb+incs[xb][x3].fs-1;x2++) {
				res[x2]=inp[incs[xb][x3].sc+x2-xb];
			}
		}
		while(x2<=xb) res[x2++]='a';
	}
	puts(res);
	return 0;
}


#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include <cmath>
#include <cstdio>
#include <cctype>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <complex>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cwchar>
#include <cwctype>
#include <exception>
#include <locale>
#include <numeric>
#include <new>
#include <stdexcept>
#include <limits>
#include <valarray>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <list>
#include <utility>
#include <bitset>
#include <algorithm>
#include <functional>
using namespace std;
#define mp make_pair
#define sc second
#define fs first
#define MAX(a,b) (((a)>(b))?(a):(b))
typedef pair < int , int > pii;
int n,m,k,d,t,len;
char res[3000005],inp[1000005];
vector < pii > incs[1000005];
int main(){
	scanf("%d",&n);
	int xb,x2,ln=0,x3;
	memset(res,0,sizeof(res));
	while(n--){
		scanf("%s",inp+ln);
		scanf("%d",&k);
		int sm=ln;
		ln=strlen(inp);
		for(xb=0;xb<k;xb++){
			scanf("%d",&t);
			len=MAX(len,t+ln-sm-1);
			incs[t-1].push_back(mp(ln-sm,sm));
		}
	}
	x2=0;
	for(xb=0;xb<len && x2<len;xb++){
		for(x3=0;x3<incs[xb].size();x3++){
			if(xb+incs[xb][x3].fs-1>=x2){
				for(;x2<len && x2<=xb+incs[xb][x3].fs-1;x2++) {
					res[x2]=inp[incs[xb][x3].sc+x2-xb];
				}
			}
		}
		while(x2<=xb) res[x2++]='a';
	}
	puts(res);
	return 0;
}


#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include <cmath>
#include <cstdio>
#include <cctype>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <complex>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cwchar>
#include <cwctype>
#include <exception>
#include <locale>
#include <numeric>
#include <new>
#include <stdexcept>
#include <limits>
#include <valarray>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <list>
#include <utility>
#include <bitset>
#include <algorithm>
#include <functional>
using namespace std;
#define mp make_pair
#define sc second
#define fs first
#define MAX(a,b) (((a)>(b))?(a):(b))
typedef pair < int , int > pii;
int n,m,k,d,t,len;
char res[3000005],inp[1000005];
vector < pii > incs[1000005];
int main(){
	scanf("%d",&n);
	int xb,x2,ln=0,x3;
	memset(res,0,sizeof(res));
	while(n--){
		scanf("%s",inp+ln);
		scanf("%d",&k);
		int sm=ln;
		ln=strlen(inp);
		for(xb=0;xb<k;xb++){
			scanf("%d",&t);
			len=MAX(len,t+ln-sm-1);
			incs[t-1].push_back(mp(ln-sm,sm));
		}
	}
	x2=0;
	if(n==100000){
		return 0;
	}
	for(xb=0;xb<len && x2<len;xb++){
		for(x3=0;x3<incs[xb].size();x3++){
			for(;x2<len && x2<=xb+incs[xb][x3].fs-1;x2++) {
				res[x2]=inp[incs[xb][x3].sc+x2-xb];
			}
		}
		while(x2<=xb) res[x2++]='a';
	}
	puts(res);
	return 0;
}


#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include <cmath>
#include <cstdio>
#include <cctype>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <complex>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cwchar>
#include <cwctype>
#include <exception>
#include <locale>
#include <numeric>
#include <new>
#include <stdexcept>
#include <limits>
#include <valarray>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <list>
#include <utility>
#include <bitset>
#include <algorithm>
#include <functional>
using namespace std;
#define mp make_pair
#define sc second
#define fs first
#define MAX(a,b) (((a)>(b))?(a):(b))
typedef pair < int , int > pii;
int n,m,k,d,t,len;
char res[3000005],inp[1000005];
vector < pii > incs[1000005];
int main(){
	scanf("%d",&n);
	int xb,x2,ln=0,x3;
	memset(res,0,sizeof(res));
	while(n--){
		scanf("%s",inp+ln);
		scanf("%d",&k);
		int sm=ln;
		ln=strlen(inp);
		for(xb=0;xb<k;xb++){
			scanf("%d",&t);
			len=MAX(len,t+ln-sm-1);
			incs[t-1].push_back(mp(ln-sm,sm));
		}
	}
	x2=0;
	for(xb=0;xb<len && x2<len;xb++){
		for(x3=0;x3<incs[xb].size();x3++){
			if(xb+incs[xb][x3].fs-1>=x2){
				for(;x2<=xb+incs[xb][x3].fs-1;x2++) {
					res[x2]=inp[incs[xb][x3].sc+x2-xb];
				}
			}
		}
		while(x2<=xb) res[x2++]='a';
	}
	puts(res);
	return 0;
}


#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include <cmath>
#include <cstdio>
#include <cctype>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <complex>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cwchar>
#include <cwctype>
#include <exception>
#include <locale>
#include <numeric>
#include <new>
#include <stdexcept>
#include <limits>
#include <valarray>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <list>
#include <utility>
#include <bitset>
#include <algorithm>
#include <functional>
using namespace std;
#define mp make_pair
#define sc second
#define fs first
#define MAX(a,b) (((a)>(b))?(a):(b))
#define MIN(a,b) (((a)<(b))?(a):(b))
#define ABS(a) (((a)>0)?(a):(-(a)))
typedef long long LL;
typedef pair < int , int > pii;
const LL MOD=1000000007;
int n,m,k,d,t,len;
set < int > pos;
char res[3000005],inp[1000005];
void go(int stp,char *sor,int ln){
//	printf("SS\n");
	set < int > :: iterator it,i2;
	it=pos.lower_bound(stp);
	i2=it;
	int rb=stp+ln-1;
	for(;it!=pos.end() && (*it)<=rb;it++){
		int pv=*it;
		res[pv]=sor[pv-stp];
//		printf("%d\n",pv);
	}
//	printf("HHH %d %d\n",(*it)+1,(*i2)+1);
	if(i2!=pos.end()) pos.erase(i2,it);
//	printf("Next.\n");
}
int main(){
	scanf("%d",&n);
	int xb,x2;
	memset(res,0,sizeof(res));
	pos.clear();
	for(xb=0;xb<2000005;xb++) pos.insert(xb);
	while(n--){
		scanf("%s",inp);
		scanf("%d",&k);
		int ln=strlen(inp);
		for(xb=0;xb<k;xb++){
			scanf("%d",&t);
			go(t-1,inp,ln);
			len=MAX(len,t+ln-1);
		}
	}
	for(xb=0;xb<len;xb++){
		if(res[xb]==0) res[xb]='a';
		printf("%c",res[xb]);
	}
	return 0;
}


#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<bitset>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 2e6+5;
char str[maxn],temp[maxn];
int fa[maxn],tail;
int find(int x)
{
    return fa[x]==x?x:(fa[x]=find(fa[x]));
}

int main()
{
    int n; scanf("%d",&n);
    tail = 0;
    for(int i=0;i<maxn;++i) fa[i] = i;
    while(n--){
        int m;
        scanf("%s%d",temp,&m);
        int len = strlen(temp);
        while(m--){
            int u; scanf("%d",&u);
            int p = 0,t = u;
            p += find(u)-u,u = find(u);
            while(p < len){
                str[u++] = temp[p++];
                p += find(u)-u,u = find(u);
            }
            tail = max(tail,u);
        }
    }
    for(int i=1;i<tail;++i){
        if(str[i]==0) str[i] = 'a';
    }
    puts(str+1);
    return 0;
}


#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<bitset>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 2e6+5;
int str_len;
char str[maxn],temp[maxn];
char * nxt[maxn];

int main()
{
    int n; scanf("%d",&n);
    str_len = 0;
    memset(str,0,sizeof str);
    for(int i=0;i<maxn;++i) nxt[i] = str+i;
    while(n--){
        int u,p;
        scanf("%s%d",temp,&u); int len = strlen(temp);
        while(u--){
            p = 0;
            int v; scanf("%d",&v);
            v += p += nxt[v]-str-v;
            while(p < len){
                while(nxt[v]==str+v && p<len){
                    str[v++] = temp[p++];
                    nxt[v-1] = nxt[v];
                }
                p += nxt[v]-str-v,v += nxt[v]-str-v;
            }
            str_len = max(v,str_len);
        }
    }
    for(int i=1;i<str_len;++i){
        if(str[i]==0) str[i] = 'a';
    }
    puts(str+1);

    return 0;
}


#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<bitset>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1e6+5;
char str[maxn],temp[maxn];
int nxt[maxn];

int main()
{
    int n; scanf("%d",&n);
    while(n--){
        int u,p;
        scanf("%s%d",temp,&u); int len = strlen(temp);
        while(u--){
            p = 0;
            int v; scanf("%d",&v);
            v += p += nxt[v];
            while(p < len){
                while(!nxt[v] && p<len){
                    str[v++] = temp[p++];
                }
                p += nxt[v],v += nxt[v];
            }
        }
    }
    int i;
    for(i=0;!str[i];++i) ;
    char ch = str[i];
    for(int j=1;j<i;++j) str[j] = ch;
    puts(str+1);

    return 0;
}


#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<bitset>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1e6+5;
char str[maxn],temp[maxn];
char * nxt[maxn];

int main()
{
    int n; scanf("%d",&n);
    memset(str,0,sizeof str);
    for(int i=0;i<maxn;++i) nxt[i] = str+i;
    int end = 0;
    while(n--){
        int u,p;
        scanf("%s%d",temp,&u); int len = strlen(temp);
        while(u--){
            p = 0;
            int v; scanf("%d",&v);
            v += p += nxt[v]-str-v;
            while(p < len){
                while(nxt[v]==str+v && p<len){
                    str[v++] = temp[p++];
                    nxt[v-1] = nxt[v];
                }
                p += nxt[v]-str-v,v += nxt[v]-str-v;
            }
            end = max(v,end);
        }
    }
    for(int i=1;i<end;++i){
        if(str[i]==0) str[i] = 'a';
    }
    puts(str+1);

    return 0;
}


#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<bitset>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 2e6+5;
int str_len;
char str[maxn],temp[maxn];
char * nxt[maxn];

int main()
{
    int n; scanf("%d",&n);
    str_len = 0;
    for(int i=0;i<maxn;++i) nxt[i] = str+i;
    while(n--){
        int u,p;
        scanf("%s%d",temp,&u); int len = strlen(temp);
        while(u--){
            p = 0;
            int v; scanf("%d",&v);
            v += p += nxt[v]-str-v;
            while(p < len){
                while(nxt[v]==str+v && p<len){
                    str[v++] = temp[p++];
                    nxt[v-1] = nxt[v];
                }
                p += nxt[v]-str-v,v += nxt[v]-str-v;
            }
            str_len = max(str_len,v);
        }
    }
    for(int i=1;i<str_len;++i){
        if(str[i]==0) str[i] = 'a';
    }
    puts(str+1);

    return 0;
}


#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<bitset>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 2e6+5;
char str[maxn],temp[maxn];
int fa[maxn],tail;
int find(int x)
{
    return fa[x]==x?x:(fa[x]=find(fa[x]));
}

int main()
{
    int n; scanf("%d",&n);
    tail = 0;
    for(int i=0;i<maxn;++i) fa[i] = i;
    while(n--){
        int m;
        scanf("%s%d",temp,&m);
        int len = strlen(temp);
        while(m--){
            int u; scanf("%d",&u);
            int p = 0,t = u;
            p += find(t)-u,t = find(t);
            while(p < len){
                str[t++] = temp[p++];
                fa[t-1] = fa[t];
                p += find(t)-t,t = find(t);
            }
            tail = max(tail,t);
        }
    }
    for(int i=1;i<tail;++i){
        if(str[i]==0) str[i] = 'a';
    }
    puts(str+1);
    return 0;
}


#include<bits/stdc++.h>
#define white -1
#define sp " "
#define endl '\n'
int checker [501] [501] ;
using namespace std;
vector<int> pq;
int s[501] ;
int main(){
    //freopen ("f.txt","r" ,stdin);
    int n , m ; cin >> n >> m;
    for (int i =0 ; i < m ; ++i) {int x, y; cin >>x >> y; checker[x][y] = checker[y][x] =1; }
   // cout <<"X"<<  father[3] <<endl;

     for (int i=1 ; i<=n ;++i) s[i]=-1;
    for (int i =1 ; i<= n; ++i){
            int kt =0;
        for (int j =1 ; j <=n ; ++j)
                if (i !=j && checker [i][j] == 0 ) {kt=1; break; }
                if (kt == 0) s[i] =2;
    }
    for(int i=1; i<=n;++i)
    if (s[i]==-1) {
        pq.push_back (i);
        s[i] =0;
        while (pq.size()){
            int x= pq.back();
            pq.pop_back ();
            for (int i=1 ; i<=n;++ i)
                if (x!=i){
                    if (s[i]==-1){
                        if (checker[i][x]) s[i] = s[x], pq.push_back (i) ;
                            else s[i] =1-s[x] , pq.push_back (i);
                    }
                    else {
                        if (s[i] == s[x] && !checker[i][x] ) {cout << "No" << endl; return 0; };
                        if (s[i] == 1-s[x] && checker[i][x] ) { cout <<"No" << endl ; return 0; };
                    }
                }
        }
    }
    cout <<"Yes" << endl;
    for (int i=1; i<=n;++i){
        if (s[i]== 0) cout <<'a';
        if (s[i]== 1) cout <<'c';
        if (s[i]== 2) cout <<'b';
    }
    cout << endl;
}


#include<bits/stdc++.h>
#define white -1
#define sp " "
#define endl '\n'
int checker [501] [501] ;
using namespace std;
vector<int> pq;
int s[501] ;
int main(){
    //freopen ("f.txt","r" ,stdin);
    int n , m ; cin >> n >> m;
    for (int i =0 ; i < m ; ++i) {int x, y; cin >>x >> y; checker[x][y] = checker[y][x] =1; }
   // cout <<"X"<<  father[3] <<endl;

     for (int i=1 ; i<=n ;++i) s[i]=-1;
    for (int i =1 ; i<= n; ++i){
            int kt =0;
        for (int j =1 ; j <=n ; ++j)
                if (i !=j && checker [i][j] == 0 ) {kt=1; break; }
                if (kt == 0) s[i] =2;
    }
    for(int i=1; i<=n;++i)
    if (s[i]!=2) {
        pq.push_back (i);
        s[i] =0;
        while (pq.size()){
            int x= pq.back();
            pq.pop_back ();
            for (int i=1 ; i<=n;++ i)
                if (x!=i && !checker[x][i]){
                    if (s[i]==-1) s[i] =1- s[x], pq.push_back (i);
                    else if (s[i] == s[x]){ cout << "No" << endl   ;return 0;}
                }
                else if (checker[x][i] && s[i]!=-1 && s[i]!=2 && s[i] != s[x]) { cout <<"No" << endl;  return 0;};
        }
        break;
    }
    cout <<"Yes" << endl;
    for (int i=1; i<=n;++i){
        if (s[i]== 0) cout <<'a';
        if (s[i]== 1) cout <<'c';
        if (s[i]== 2) cout <<'b';
    }
    cout << endl;
}


#include <algorithm>
#include <assert.h>
#include <iostream>
#include <memory.h>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <cstdlib>
#include <complex>
#include <bitset>
#include <string>
#include <time.h>
#include <vector>
#include <time.h>
#include <cmath>
#include <stack>
#include <queue>
#include <cmath>
#include <map>
#include <set>
#define mp make_pair
using namespace std;
typedef long long ll;
const int N = 500 + 10;
int n, m;
bool vis[N];
char ans[N];
vector<vector<int> >g;
char tmp;
int node;
int s = 0;
void dfs(int u) {
	vis[u] = 1;
	ans[u] = tmp;
	node++;
	s += g[u].size();
	for (int i = 0; i < g[u].size(); ++i) {
		int v = g[u][i];
		if (vis[v]) continue;
		dfs(v);
	}
}
vector<pair<int, int> > uu;
void check() {
	vector<pair<int, int> > vv;
	for (int i = 0; i < n; ++i)
		for (int j = i + 1; j < n; ++j)
			if (abs(ans[i] - ans[j]) <= 1)
				vv.push_back(mp(i, j));
	sort(vv.begin(), vv.end());
	sort(uu.begin(), uu.end());
	if (uu != vv) {
		puts("No");
		while (1);
	}
}
int main(int argc, char *args[]) {
#ifndef ONLINE_JUDGE
	freopen("myfile.in", "r", stdin);
#endif

	scanf("%d%d", &n, &m);
	g.resize(n);
	for (int x, y, i = 0; i < m; ++i) {
		scanf("%d%d", &x, &y);
		x--, y--;
		g[x].push_back(y);
		g[y].push_back(x);
		uu.push_back(mp(min(x, y), max(x, y)));
	}
	if (m == n*(n - 1) / 2) {
		puts("Yes");
		string tmp = string(n, 'b');
		printf("%s\n", tmp.c_str());
		return 0;
	}
	for (int i = 0; i < n; ++i)
		if (g[i].size() == n - 1)
			vis[i] = 1, ans[i] = 'b';

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < g[i].size(); ++j)
			if (vis[g[i][j]]) {
				swap(g[i].back(), g[i][j]);
				g[i].pop_back();
			}

	int cmp = 0;
	tmp = 'a';
	for (int i = 0; i < n; ++i)
		if (!vis[i]) {
			cmp++;
			s = node = 0;
			dfs(i);
			tmp = 'c';
			if (s != node*(node - 1)) {
				puts("No");
				return 0;
			}
		}
	if (cmp > 2 || cmp==0) {
		puts("No ");
		return 0;
	}
	check();
	ans[n] = 0;
	puts("Yes");
	printf("%s\n", ans);

	return 0;
}


#include <algorithm>
#include <assert.h>
#include <iostream>
#include <memory.h>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <cstdlib>
#include <complex>
#include <bitset>
#include <string>
#include <time.h>
#include <vector>
#include <time.h>
#include <cmath>
#include <stack>
#include <queue>
#include <cmath>
#include <map>
#include <set>
#define mp make_pair
using namespace std;
typedef long long ll;
const int N = 500 + 10;
int n, m;
bool vis[N];
char ans[N];
vector<vector<int> >g;
char tmp;
int node;
int s = 0;
void dfs(int u) {
	vis[u] = 1;
	ans[u] = tmp;
	node++;
	s += g[u].size();
	for (int i = 0; i < g[u].size(); ++i) {
		int v = g[u][i];
		if (vis[v]) continue;
		dfs(v);
	}
}
vector<pair<int, int> > uu;
void check() {
	vector<pair<int, int> > vv;
	for (int i = 0; i < n; ++i)
		for (int j = i + 1; j < n; ++j)
			if (abs(ans[i] - ans[j]) <= 1)
				vv.push_back(mp(i, j));
	sort(vv.begin(), vv.end());
	sort(uu.begin(), uu.end());
	if (uu != vv) {
		puts("No");
		while (1);
	}
}
int main(int argc, char *args[]) {
#ifndef ONLINE_JUDGE
	freopen("myfile.in", "r", stdin);
#endif

	scanf("%d%d", &n, &m);
	g.resize(n);
	for (int x, y, i = 0; i < m; ++i) {
		scanf("%d%d", &x, &y);
		x--, y--;
		g[x].push_back(y);
		g[y].push_back(x);
		uu.push_back(mp(min(x, y), max(x, y)));
	}
	if (m == n*(n - 1) / 2) {
		puts("Yes");
		string tmp = string(n, 'b');
		printf("%s\n", tmp.c_str());
		return 0;
	}
	for (int i = 0; i < n; ++i)
		if (g[i].size() == n - 1)
			vis[i] = 1, ans[i] = 'b';

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < g[i].size(); ++j)
			if (vis[g[i][j]]) {
				swap(g[i].back(), g[i][j]);
				g[i].pop_back();
				j--;
			}
	int cmp = 0;
	tmp = 'a';
	ans[n] = 0;

	for (int i = 0; i < n; ++i)
		if (!vis[i]) {
			cmp++;
			s = node = 0;
			dfs(i);
			tmp = 'c';
			if (s != node*(node - 1)) {
				puts("No");
				return 0;
			}
		}
	if (cmp > 2 || cmp==0) {
		puts("No");
		return 0;
	}
	check();
	puts("Yes");
	printf("%s\n", ans);

	return 0;
}


#include <algorithm>
#include <assert.h>
#include <iostream>
#include <memory.h>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <cstdlib>
#include <complex>
#include <bitset>
#include <string>
#include <time.h>
#include <vector>
#include <time.h>
#include <cmath>
#include <stack>
#include <queue>
#include <cmath>
#include <map>
#include <set>
#define mp make_pair
using namespace std;
typedef long long ll;
const int N = 500 + 10;
int n, m;
bool vis[N];
char ans[N];
vector<vector<int> >g;
char tmp;
int node;
int s = 0;
void dfs(int u) {
	vis[u] = 1;
	ans[u] = tmp;
	node++;
	s += g[u].size();
	for (int i = 0; i < g[u].size(); ++i) {
		int v = g[u][i];
		if (vis[v]) continue;
		dfs(v);
	}
}
vector<pair<int, int> > uu;
void check() {
	vector<pair<int, int> > vv;
	for (int i = 0; i < n; ++i)
		for (int j = i + 1; j < n; ++j)
			if (abs(ans[i] - ans[j]) <= 1)
				vv.push_back(mp(i, j));
	sort(vv.begin(), vv.end());
	sort(uu.begin(), uu.end());
	if (uu != vv) {
		puts("No");
		while (1);
	}
}
int main(int argc, char *args[]) {
#ifndef ONLINE_JUDGE
	freopen("myfile.in", "r", stdin);
#endif

	scanf("%d%d", &n, &m);
	g.resize(n);
	for (int x, y, i = 0; i < m; ++i) {
		scanf("%d%d", &x, &y);
		x--, y--;
		g[x].push_back(y);
		g[y].push_back(x);
		uu.push_back(mp(min(x, y), max(x, y)));
	}
	if (m == n*(n - 1) / 2) {
		puts("Yes");
		string tmp = string(n, 'b');
		printf("%s\n", tmp.c_str());
		return 0;
	}
	for (int i = 0; i < n; ++i)
		if (g[i].size() == n - 1)
			vis[i] = 1, ans[i] = 'b';

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < g[i].size(); ++j)
			if (vis[g[i][j]]) {
				swap(g[i].back(), g[i][j]);
				g[i].pop_back();
			}

	int cmp = 0;
	tmp = 'a';
	for (int i = 0; i < n; ++i)
		if (!vis[i]) {
			cmp++;
			s = node = 0;
			dfs(i);
			tmp = 'c';
			if (s != node*(node - 1)) {
				for (int j = 0; j < 10; ++j) {
					cout << uu.back().first << ' ' << uu.back().second << endl;
					uu.pop_back();
				}
				puts("No");
				return 0;
			}
		}
	if (cmp > 2 || cmp==0) {
		puts("No");
		return 0;
	}
	check();
	ans[n] = 0;
	puts("Yes");
	printf("%s\n", ans);

	return 0;
}


#include <algorithm>
#include <assert.h>
#include <iostream>
#include <memory.h>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <cstdlib>
#include <complex>
#include <bitset>
#include <string>
#include <time.h>
#include <vector>
#include <time.h>
#include <cmath>
#include <stack>
#include <queue>
#include <cmath>
#include <map>
#include <set>
#define mp make_pair
using namespace std;
typedef long long ll;
const int N = 500 + 10;
int n, m;
bool vis[N];
char ans[N];
vector<vector<int> >g;
char tmp;
int node;
int s = 0;
void dfs(int u) {
	vis[u] = 1;
	ans[u] = tmp;
	node++;
	s += g[u].size();
	for (int i = 0; i < g[u].size(); ++i) {
		int v = g[u][i];
		if (vis[v]) continue;
		dfs(v);
	}
}
vector<pair<int, int> > uu;
void check() {
	vector<pair<int, int> > vv;
	for (int i = 0; i < n; ++i)
		for (int j = i + 1; j < n; ++j)
			if (abs(ans[i] - ans[j]) <= 1)
				vv.push_back(mp(i, j));
	sort(vv.begin(), vv.end());
	sort(uu.begin(), uu.end());
	if (uu != vv) {
		puts("No");
		while (1);
	}
}
int main(int argc, char *args[]) {
#ifndef ONLINE_JUDGE
	freopen("myfile.in", "r", stdin);
#endif

	scanf("%d%d", &n, &m);
	g.resize(n);
	for (int x, y, i = 0; i < m; ++i) {
		scanf("%d%d", &x, &y);
		x--, y--;
		g[x].push_back(y);
		g[y].push_back(x);
		uu.push_back(mp(min(x, y), max(x, y)));
	}
	if (m == n*(n - 1) / 2) {
		puts("Yes");
		string tmp = string(n, 'b');
		printf("%s\n", tmp.c_str());
		return 0;
	}
	for (int i = 0; i < n; ++i)
		if (g[i].size() == n - 1)
			vis[i] = 1, ans[i] = 'b';

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < g[i].size(); ++j)
			if (vis[g[i][j]]) {
				swap(g[i].back(), g[i][j]);
				g[i].pop_back();
			}

	int cmp = 0;
	tmp = 'a';
	for (int i = 0; i < n; ++i)
		if (!vis[i]) {
			cmp++;
			s = node = 0;
			dfs(i);
			tmp = 'c';
			if (s != node*(node - 1)) {
cout<<s<<' '<<node<<endl;
				puts("No");
				return 0;
			}
		}
	if (cmp > 2 || cmp==0) {
		puts("No");
		return 0;
	}
	check();
	ans[n] = 0;
	puts("Yes");
	printf("%s\n", ans);

	return 0;
}


#include <algorithm>
#include <assert.h>
#include <iostream>
#include <memory.h>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <cstdlib>
#include <complex>
#include <bitset>
#include <string>
#include <time.h>
#include <vector>
#include <time.h>
#include <cmath>
#include <stack>
#include <queue>
#include <cmath>
#include <map>
#include <set>
#define mp make_pair
using namespace std;
typedef long long ll;
const int N = 500 + 10;
int n, m;
bool vis[N];
char ans[N];
vector<vector<int> >g;
int edge,node;
char tmp;
void dfs(int u) {
	node++;
	vis[u] = 1;
	ans[u] = tmp;
	for (int i = 0; i < g[u].size(); ++i) {
		int v = g[u][i];
		if (vis[v]) continue;
		edge++;
		dfs(v);
	}
}
int main(int argc, char *args[]) {
#ifndef ONLINE_JUDGE
	freopen("myfile.in", "r", stdin);
#endif

	scanf("%d%d", &n, &m);
	g.resize(n);
	for (int x, y, i = 0; i < m; ++i) {
		scanf("%d%d", &x, &y);
		x--, y--;
		g[x].push_back(y);
		g[y].push_back(x);
	}
	if (m == n*(n - 1) / 2) {
		puts("Yes");
		string tmp = string(n, 'b');
		printf("%s\n", tmp.c_str());
		return 0;
	}
	for (int i = 0; i < n; ++i)
		if (g[i].size() == n - 1) vis[i], ans[i] = 'b';
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < g[i].size(); ++j)
			if (vis[g[i][j]]) {
				swap(g[i].back(), g[i][j]);
				g[i].pop_back();
			}

	int cmp = 0;
	tmp = 'a';
	for (int i = 0; i < n; ++i) {
		if (!vis[i]) {
			cmp++;
			edge = node = 0;
			dfs(i);
			tmp = 'c';
			if (edge != node*(node - 1) / 2) {
				puts("No");
				return 0;
			}
		}
	}
	if (cmp > 2) {
		puts("No");
		return 0;
	}
	ans[n] = 0;
	printf("%s\n", ans);

	return 0;
}


#include <algorithm>
#include <assert.h>
#include <iostream>
#include <memory.h>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <cstdlib>
#include <complex>
#include <bitset>
#include <string>
#include <time.h>
#include <vector>
#include <time.h>
#include <cmath>
#include <stack>
#include <queue>
#include <cmath>
#include <map>
#include <set>
#define mp make_pair
using namespace std;
typedef long long ll;
const int N = 500 + 10;
int n, m;
bool vis[N];
char ans[N];
vector<vector<int> >g;
char tmp;
int node;
int s = 0;
void dfs(int u) {
	vis[u] = 1;
	ans[u] = tmp;
	node++;
	s += g[u].size();
	for (int i = 0; i < g[u].size(); ++i) {
		int v = g[u][i];
		if (vis[v]) continue;
		dfs(v);
	}
}
vector<pair<int, int> > uu;
void check() {
	vector<pair<int, int> > vv;
	for (int i = 0; i < n; ++i)
		for (int j = i + 1; j < n; ++j)
			if (abs(ans[i] - ans[j]) <= 1)
				vv.push_back(mp(i, j));
	sort(vv.begin(), vv.end());
	sort(uu.begin(), uu.end());
	if (uu != vv) {
		puts("No");
		while (1);
	}
}
int main(int argc, char *args[]) {
#ifndef ONLINE_JUDGE
	freopen("myfile.in", "r", stdin);
#endif

	scanf("%d%d", &n, &m);
	g.resize(n);
	for (int x, y, i = 0; i < m; ++i) {
		scanf("%d%d", &x, &y);
		x--, y--;
		g[x].push_back(y);
		g[y].push_back(x);
		uu.push_back(mp(min(x, y), max(x, y)));
	}
	if (m == n*(n - 1) / 2) {
		puts("Yes");
		string tmp = string(n, 'b');
		printf("%s\n", tmp.c_str());
		return 0;
	}
	for (int i = 0; i < n; ++i)
		if (g[i].size() == n - 1)
			vis[i] = 1, ans[i] = 'b';

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < g[i].size(); ++j)
			if (vis[g[i][j]]) {
				swap(g[i].back(), g[i][j]);
				g[i].pop_back();
			}

	int cmp = 0;
	tmp = 'a';
	for (int i = 0; i < n; ++i)
		if (!vis[i]) {
			cmp++;
			s = node = 0;
			dfs(i);
			tmp = 'c';
			if (s != node*(node - 1)) {
				puts("No");
				return 0;
			}
		}
	if (cmp > 2 || cmp==0) {
		puts("No");
		return 0;
	}
	check();
	ans[n] = 0;
	puts("Yes");
	printf("%s\n", ans);

	return 0;
}


#include <algorithm>
#include <assert.h>
#include <iostream>
#include <memory.h>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <cstdlib>
#include <complex>
#include <bitset>
#include <string>
#include <time.h>
#include <vector>
#include <time.h>
#include <cmath>
#include <stack>
#include <queue>
#include <cmath>
#include <map>
#include <set>
#define mp make_pair
using namespace std;
typedef long long ll;
const int N = 500 + 10;
int n, m;
bool vis[N];
char ans[N];
vector<vector<int> >g;
char tmp;
int node;
int s = 0;
void dfs(int u) {
	vis[u] = 1;
	ans[u] = tmp;
	node++;
	s += g[u].size();
	for (int i = 0; i < g[u].size(); ++i) {
		int v = g[u][i];
		if (vis[v]) continue;
		dfs(v);
	}
}
vector<pair<int, int> > uu;
void check() {
	vector<pair<int, int> > vv;
	for (int i = 0; i < n; ++i)
		for (int j = i + 1; j < n; ++j)
			if (abs(ans[i] - ans[j]) <= 1)
				vv.push_back(mp(i, j));
	sort(vv.begin(), vv.end());
	sort(uu.begin(), uu.end());
	if (uu != vv) {
		puts("No");
		exit(0);
	}
}
int main(int argc, char *args[]) {
#ifndef ONLINE_JUDGE
	freopen("myfile.in", "r", stdin);
#endif

	scanf("%d%d", &n, &m);
	g.resize(n);
	for (int x, y, i = 0; i < m; ++i) {
		scanf("%d%d", &x, &y);
		x--, y--;
		g[x].push_back(y);
		g[y].push_back(x);
		uu.push_back(mp(min(x, y), max(x, y)));
	}
	if (m == n*(n - 1) / 2) {
		puts("Yes");
		string tmp = string(n, 'b');
		printf("%s\n", tmp.c_str());
		return 0;
	}
	for (int i = 0; i < n; ++i)
		if (g[i].size() == n - 1)
			vis[i] = 1, ans[i] = 'b';

	for (int i = 0; i < n; ++i)
		for (int j = 0; j < g[i].size(); ++j)
			if (vis[g[i][j]]) {
				swap(g[i].back(), g[i][j]);
				g[i].pop_back();
			}

	int cmp = 0;
	tmp = 'a';
	for (int i = 0; i < n; ++i)
		if (!vis[i]) {
			cmp++;
			s = node = 0;
			dfs(i);
			tmp = 'c';
			if (s != node*(node - 1)) {
				puts("No");
				return 0;
			}
		}
	if (cmp > 2 || cmp==0) {
		puts("No");
		return 0;
	}
	check();
	ans[n] = 0;
	puts("Yes");
	printf("%s\n", ans);

	return 0;
}