#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9 + 7;
const int maxn = 1005;
struct Edge {
  int u, v;
  Edge(int u, int v) : u(u), v(v) {}
};
struct Node {
  bool person[maxn], key[maxn];
  bool operator==(const Node &b) const {
    for (int i = (0); i < (maxn); ++i)
      if (person[i] != b.person[i]) return false;
    for (int i = (0); i < (maxn); ++i)
      if (key[i] != b.key[i]) return false;
    return true;
  }
};
int n, m, q, tot = 0;
vector<Edge> e;
map<string, int> mp;
pair<vector<int>, Node> before[maxn], after[maxn];
vector<pair<vector<int>, Node> > vec1, vec2;
inline int getId(string str) {
  if (mp.find(str) == mp.end()) mp[str] = tot++;
  return mp[str];
}
class Dsu {
 private:
  int fa[maxn];
  inline int findKey(int x, int u) { return node[find(u)].key[x]; }
  inline void addKey(int x, int u) {
    node[u].key[x] = true;
    return;
  }
  inline void addPerson(int x, int u) {
    node[u].person[x] = true;
    return;
  }
  inline bool combine(int u, int v) {
    u = find(u);
    v = find(v);
    if (u == v) return false;
    for (int i = (0); i < (maxn); ++i) node[v].key[i] |= node[u].key[i];
    for (int i = (0); i < (maxn); ++i) node[v].person[i] |= node[u].person[i];
    fa[u] = v;
    return true;
  }

 public:
  Node node[maxn];
  inline int find(int x) { return (x == fa[x]) ? (x) : (fa[x] = find(fa[x])); }
  Dsu() {}
  inline void init() {
    for (int i = (0); i < (q); ++i) {
      string name;
      int u, x, id;
      cin >> name >> u >> x;
      --u;
      id = getId(name);
      addPerson(id, u);
      for (int j = (0); j < (x); ++j) {
        int y;
        cin >> y;
        --y;
        addKey(y, u);
      }
    }
    for (int i = (0); i < (maxn); ++i) fa[i] = i;
    return;
  }
  inline void connect() {
    for (bool update = true; update;) {
      update = false;
      for (int i = (0); i < (m); ++i) {
        int u = e[i].u, v = e[i].v;
        if (findKey(i, u) || findKey(i, v)) {
          update |= combine(u, v);
        }
      }
    }
    return;
  }
} bef, aft;
int main() {
  mp.clear();
  cin >> n >> m >> q;
  for (int i = (0); i < (m); ++i) {
    int u, v;
    cin >> u >> v;
    --u;
    --v;
    e.push_back(Edge(u, v));
  }
  bef.init();
  bef.connect();
  aft.init();
  aft.connect();
  for (int i = (0); i < (n); ++i) {
    if (bef.find(i) == i) {
      before[i].second = bef.node[i];
    }
    before[bef.find(i)].first.push_back(i);
  }
  for (int i = (0); i < (n); ++i) {
    if (aft.find(i) == i) {
      after[i].second = aft.node[i];
    }
    after[aft.find(i)].first.push_back(i);
  }
  for (int i = (0); i < (n); ++i) {
    if (before[i].first.size()) {
      sort(before[i].first.begin(), before[i].first.end());
      vec1.push_back(before[i]);
    }
    if (after[i].first.size()) {
      sort(after[i].first.begin(), after[i].first.end());
      vec2.push_back(after[i]);
    }
  }
  if (vec1 == vec2)
    puts("YES");
  else
    puts("NO");
  return 0;
}
