#include <bits/stdc++.h>
using namespace std;
pair<int, int> E[1005];
list<pair<int, int> > adj[1005];
int F[1005];
int find(int v) {
  if (F[v] != v) F[v] = find(F[v]);
  return F[v];
}
int SS[1005];
int persRoom[1005];
int keyRoom[1005];
int main() {
  map<string, int> MA;
  int N, M, K;
  cin >> N >> M >> K;
  for (int i = 1; i <= M; i++) cin >> E[i].first >> E[i].second;
  for (int i = 0; i < (K); i++) {
    string name;
    int room, keys;
    cin >> name >> room >> keys;
    persRoom[i] = room;
    MA[name] = i;
    for (int j = 0; j < (keys); j++) {
      int k;
      cin >> k;
      adj[room].push_back(E[k]);
      keyRoom[k] = room;
    }
  }
  queue<pair<int, int> > Q;
  for (int i = 1; i <= N; i++)
    for (list<pair<int, int> >::iterator it = adj[i].begin();
         it != adj[i].end(); it++)
      if (it->first == i || it->second == i) Q.push(*it);
  for (int i = 1; i <= N; i++) F[i] = i;
  while (!Q.empty()) {
    pair<int, int> e = Q.front();
    Q.pop();
    int s1 = find(e.first);
    int s2 = find(e.second);
    if (s1 == s2) continue;
    for (list<pair<int, int> >::iterator it = adj[s1].begin();
         it != adj[s1].end(); it++)
      if (find(it->first) == s2 || find(it->second) == s2) Q.push(*it);
    for (list<pair<int, int> >::iterator it = adj[s2].begin();
         it != adj[s2].end(); it++)
      if (find(it->first) == s1 || find(it->second) == s1) Q.push(*it);
    adj[s1].splice(adj[s1].begin(), adj[s2]);
    F[s2] = s1;
  }
  for (int i = 1; i <= N; i++) {
    adj[i].clear();
    SS[i] = find(i);
  }
  bool flag = true;
  for (int i = 0; i < (K); i++) {
    string name;
    int room;
    int keys;
    cin >> name >> room >> keys;
    flag &= (find(room) == find(persRoom[MA[name]]));
    for (int j = 0; j < (keys); j++) {
      int k;
      cin >> k;
      flag &= (find(room) == find(keyRoom[k]));
      adj[room].push_back(E[k]);
    }
  }
  for (int i = 1; i <= N; i++)
    for (list<pair<int, int> >::iterator it = adj[i].begin();
         it != adj[i].end(); it++)
      if (it->first == i || it->second == i) Q.push(*it);
  for (int i = 1; i <= N; i++) F[i] = i;
  while (!Q.empty()) {
    pair<int, int> e = Q.front();
    Q.pop();
    int s1 = find(e.first);
    int s2 = find(e.second);
    if (s1 == s2) continue;
    for (list<pair<int, int> >::iterator it = adj[s1].begin();
         it != adj[s1].end(); it++)
      if (find(it->first) == s2 || find(it->second) == s2) Q.push(*it);
    for (list<pair<int, int> >::iterator it = adj[s2].begin();
         it != adj[s2].end(); it++)
      if (find(it->first) == s1 || find(it->second) == s1) Q.push(*it);
    adj[s1].splice(adj[s1].begin(), adj[s2]);
    F[s2] = s1;
  }
  for (int i = 1; i <= N; i++)
    for (int j = 1; j <= N; j++)
      flag &= ((SS[i] == SS[j]) == (find(i) == find(j)));
  if (flag)
    cout << "YES" << endl;
  else
    cout << "NO" << endl;
}
