#include <bits/stdc++.h>
using namespace std;
struct E {
  int x, y;
  void in() { scanf("%d %d", &x, &y); }
} e[1010];
int fa[2][1010];
int find(int t, int x) {
  if (fa[t][x] != x) fa[t][x] = find(t, fa[t][x]);
  return fa[t][x];
}
map<string, int> at[2];
int key[2][1010];
int main() {
  int n, m, L;
  scanf("%d %d %d", &n, &m, &L);
  for (int i = 0; i < m; i++) e[i].in();
  for (int k = 0; k < 2; k++) {
    at[k].clear();
    for (int i = 0; i < L; i++) {
      string name;
      cin >> name;
      int x;
      scanf("%d", &x);
      at[k][name] = x;
      int total;
      scanf("%d", &total);
      while (total--) {
        int s;
        scanf("%d", &s);
        s--;
        key[k][s] = x;
      }
    }
    for (int i = 1; i <= n; i++) fa[k][i] = i;
    while (1) {
      bool doing = false;
      for (int i = 0; i < m; i++) {
        int x = e[i].x;
        int y = e[i].y;
        int fx = find(k, x);
        int fy = find(k, y);
        if (fx == fy) continue;
        int need = find(k, key[k][i]);
        if (need == fx || need == fy) {
          if (fx < fy)
            fa[k][fx] = fy;
          else
            fa[k][fy] = fx;
          doing = true;
        }
      }
      if (!doing) break;
    }
  }
  bool flag = true;
  for (int i = 1; i <= n; i++)
    if (find(0, i) != find(1, i)) flag = false;
  for (int i = 0; i < m; i++)
    if (find(0, key[0][i]) != find(1, key[1][i])) flag = false;
  for (map<string, int>::iterator ll = at[0].begin(); ll != at[0].end(); ll++) {
    string name = ll->first;
    if (find(0, at[0][name]) != find(1, at[1][name])) flag = false;
  }
  if (flag)
    printf("YES\n");
  else
    printf("NO\n");
  return 0;
}
