#include <bits/stdc++.h>
struct edge {
  int l, r;
  char used;
};
int main() {
  int N, M, K;
  scanf("%d %d %d", &N, &M, &K);
  static struct edge data[1005];
  int i, j;
  for (i = 0; i < M; i++) {
    scanf("%d %d", &(data[i].l), &(data[i].r));
    (data[i].l)--;
    (data[i].r)--;
    data[i].used = 0;
  }
  static char names[1005][15];
  static char name[15];
  static int room;
  int keys_cnt, cur_key;
  static int people1[1005];
  static int people2[1005];
  static int keys1[1005];
  static int keys2[1005];
  static int set1[1005];
  static int set2[1005];
  for (i = 0; i < K; i++) {
    scanf("\n");
    scanf("%s %d %d", names[i], &room, &keys_cnt);
    room--;
    people1[i] = room;
    for (j = 0; j < keys_cnt; j++) {
      scanf("%d", &cur_key);
      cur_key--;
      keys1[cur_key] = room;
    }
  }
  for (i = 0; i < K; i++) {
    scanf("\n");
    scanf("%s %d %d", name, &room, &keys_cnt);
    j = 0;
    while (strcmp(name, names[j])) j++;
    room--;
    people2[j] = room;
    for (j = 0; j < keys_cnt; j++) {
      scanf("%d", &cur_key);
      cur_key--;
      keys2[cur_key] = room;
    }
  }
  for (i = 0; i < N; i++) {
    set1[i] = i;
    set2[i] = i;
  }
  int from, to;
  while (1) {
    i = 0;
    while (i < M) {
      if ((!data[i].used) &&
          ((set1[data[i].l] == keys1[i]) || (set1[data[i].r] == keys1[i]))) {
        data[i].used = 1;
        if (set1[data[i].l] != set1[data[i].r]) {
          from = set1[data[i].l];
          to = set1[data[i].r];
          for (j = 0; j < N; j++) {
            if (set1[j] == from) set1[j] = to;
          }
          for (j = 0; j < M; j++) {
            if (keys1[j] == from) keys1[j] = to;
          }
          for (j = 0; j < K; j++) {
            if (people1[j] == from) people1[j] = to;
          }
        }
        break;
      }
      i++;
    }
    if (i == M) break;
  }
  for (i = 0; i < M; i++) data[i].used = 0;
  while (1) {
    i = 0;
    while (i < M) {
      if ((!data[i].used) &&
          ((set2[data[i].l] == keys2[i]) || (set2[data[i].r] == keys2[i]))) {
        data[i].used = 1;
        if (set2[data[i].l] != set2[data[i].r]) {
          from = set2[data[i].l];
          to = set2[data[i].r];
          for (j = 0; j < N; j++) {
            if (set2[j] == from) set2[j] = to;
          }
          for (j = 0; j < M; j++) {
            if (keys2[j] == from) keys2[j] = to;
          }
          for (j = 0; j < K; j++) {
            if (people2[j] == from) people2[j] = to;
          }
        }
        break;
      }
      i++;
    }
    if (i == M) break;
  }
  static int mapping1[1005];
  static int mapping2[1005];
  for (i = 0; i < N; i++) mapping1[i] = -1;
  for (i = 0; i < N; i++) mapping2[i] = -1;
  for (i = 0; i < N; i++) {
    if ((mapping1[set1[i]] == -1) && (mapping2[set2[i]] == -1)) {
      mapping1[set1[i]] = set2[i];
      mapping2[set2[i]] = set1[i];
    } else if ((mapping1[set1[i]] != set2[i]) ||
               (mapping2[set2[i]] != set1[i])) {
      printf("NO\n");
      return 0;
    }
  }
  for (i = 0; i < M; i++) {
    if ((mapping1[keys1[i]] != keys2[i]) || (mapping2[keys2[i]] != keys1[i])) {
      printf("NO\n");
      return 0;
    }
  }
  for (i = 0; i < K; i++) {
    if ((mapping1[people1[i]] != people2[i]) ||
        (mapping2[people2[i]] != people1[i])) {
      printf("NO\n");
      return 0;
    }
  }
  printf("YES\n");
  return 0;
}
