//题目的大意:有m个插头和n个插座..插头和插座匹配..中间可以通过调制器转换成其它匹配..
//最后问最多可以匹配多少对的问题.
//首先预处理把每个插头可以与哪个可以匹配的插头标记为1..不能匹配标记为0
//使用匈牙利算法一带就OK了..
//题目连接http://poj.org/problem?id=1087
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
const int inf = 0x3f3f3f;
const int MN = 200;
using namespace std;
char ct[MN][MN];
char cz[MN][MN],pzx[MN][MN],pzy[MN][MN];
int map[MN][MN],n,m,k;
int ppx[MN],ppy[MN];
bool mk[MN];
void find(int x ,char s[])
{
for(int i = 1 ; i <= m ; i++)
{
if(!strcmp(s,ct[i]))
{
map[x][i] = 1;
}
}
}
void pipe(int x , char s[])
{
for(int i = 1 ; i <= k ; i++)
{
if(!strcmp(s,pzy[i]))
{
find(x,pzx[i]);
pipe(x,pzx[i]);
}
}
}
bool path(int x)
{
for(int i = 1 ; i <= m ; i++)
{
if(map[x][i] && !mk[i])
{
mk[i] = 1;
if(ppy[i] == -1 || path(ppy[i]))
{
ppy[i] = x;
ppx[x] = i;
return 1;
}
}
}
return 0;
}
int Maxmatch()
{
int ans = 0;
memset(ppx,0xff,sizeof(ppx));
memset(ppy,0xff,sizeof(ppy));
for(int i = 1 ; i <= n ; i++)
{
memset(mk,0,sizeof(mk));
if(ppx[i] == -1)
{
ans += path(i);
}
}
return ans;
}
int main()
{
while(scanf("%d",&n) != EOF)
{
for(int i = 1 ; i <= n ; i++)
scanf("%s",cz[i]);
scanf("%d",&m);
char h[111];
for(int i = 1 ; i <= m ; i++)
{
scanf("%s",h);
scanf("%s",ct[i]);
}
scanf("%d",&k);
for(int i = 1 ; i <= k ; i++)
{
scanf("%s",pzx[i]);
scanf("%s",pzy[i]);
}
for(int i = 1 ; i <= n ; i++)
find(i,cz[i]);
for(int i = 1 ; i <= n ; i++)
pipe(i,cz[i]);
int ans = m - Maxmatch();
printf("%d\n",ans);
}
}
//最后问最多可以匹配多少对的问题.
//首先预处理把每个插头可以与哪个可以匹配的插头标记为1..不能匹配标记为0
//使用匈牙利算法一带就OK了..
//题目连接http://poj.org/problem?id=1087
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
const int inf = 0x3f3f3f;
const int MN = 200;
using namespace std;
char ct[MN][MN];
char cz[MN][MN],pzx[MN][MN],pzy[MN][MN];
int map[MN][MN],n,m,k;
int ppx[MN],ppy[MN];
bool mk[MN];
void find(int x ,char s[])
{
for(int i = 1 ; i <= m ; i++)
{
if(!strcmp(s,ct[i]))
{
map[x][i] = 1;
}
}
}
void pipe(int x , char s[])
{
for(int i = 1 ; i <= k ; i++)
{
if(!strcmp(s,pzy[i]))
{
find(x,pzx[i]);
pipe(x,pzx[i]);
}
}
}
bool path(int x)
{
for(int i = 1 ; i <= m ; i++)
{
if(map[x][i] && !mk[i])
{
mk[i] = 1;
if(ppy[i] == -1 || path(ppy[i]))
{
ppy[i] = x;
ppx[x] = i;
return 1;
}
}
}
return 0;
}
int Maxmatch()
{
int ans = 0;
memset(ppx,0xff,sizeof(ppx));
memset(ppy,0xff,sizeof(ppy));
for(int i = 1 ; i <= n ; i++)
{
memset(mk,0,sizeof(mk));
if(ppx[i] == -1)
{
ans += path(i);
}
}
return ans;
}
int main()
{
while(scanf("%d",&n) != EOF)
{
for(int i = 1 ; i <= n ; i++)
scanf("%s",cz[i]);
scanf("%d",&m);
char h[111];
for(int i = 1 ; i <= m ; i++)
{
scanf("%s",h);
scanf("%s",ct[i]);
}
scanf("%d",&k);
for(int i = 1 ; i <= k ; i++)
{
scanf("%s",pzx[i]);
scanf("%s",pzy[i]);
}
for(int i = 1 ; i <= n ; i++)
find(i,cz[i]);
for(int i = 1 ; i <= n ; i++)
pipe(i,cz[i]);
int ans = m - Maxmatch();
printf("%d\n",ans);
}
}