#include <bits/stdc++.h>
using namespace std;
long long rdtsc() {
  long long tmp;
  asm("rdtsc" : "=A"(tmp));
  return tmp;
}
inline int myrand() { return abs((rand() << 15) ^ rand()); }
inline int rnd(int x) { return myrand() % x; }
const int INF = (int)1.01e9;
const long double EPS = 1e-9;
void precalc() {}
const int maxn = 13;
int n, m, q;
int near[maxn];
int valid[1 << maxn];
bool read() {
  if (scanf("%d%d%d", &n, &m, &q) < 3) {
    return 0;
  }
  for (int i = 0; i < n; ++i) {
    near[i] = 0;
  }
  for (int i = 0; i < m; ++i) {
    int s, t;
    scanf("%d%d", &s, &t);
    --s, --t;
    near[s] ^= (1 << t);
    near[t] ^= (1 << s);
  }
  for (int i = 0; i < (1 << n); ++i) {
    valid[i] = 1;
  }
  for (int i = 0; i < q; ++i) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    --a, --b, --c;
    int whole = ((1 << a) | (1 << b) | (1 << c));
    for (int mask = 0; mask < (1 << n); ++mask) {
      if (((mask >> c) & 1) || (((mask >> a) & 1) && ((mask >> b) & 1))) {
        if ((mask & whole) != whole) {
          valid[mask] = 0;
        }
      }
    }
  }
  return 1;
}
long long dp[1 << maxn][maxn];
long long dp1[1 << maxn][maxn + 1];
void solve() {
  for (int mask = 0; mask < (1 << n); ++mask) {
    for (int v = 0; v <= n; ++v) {
      dp1[mask][v] = 0;
    }
  }
  dp1[0][n] = 1;
  for (int mask = 1; mask < (1 << n); ++mask) {
    for (int v = 0; v < n; ++v) {
      long long &cur = dp[mask][v];
      cur = 0;
      if (!valid[mask] || !((mask >> v) & 1)) {
        continue;
      }
      int neari = (near[v] & mask);
      int nearo = (near[v] ^ neari);
      if (nearo && (nearo & (nearo - 1))) {
        continue;
      }
      int ntype = nearo ? __builtin_popcount(nearo - 1) : n;
      for (int itert = 0; itert < 2; ++itert) {
        int type = !itert ? v : n;
        cur += dp1[mask ^ (1 << v)][type];
      }
      int first = (((1 << n) - 1) ^ mask);
      for (int other = first;; other = ((other - 1) & first)) {
        for (int type = 0; type <= n; ++type) {
          if (type < n && ntype < n && type != ntype) {
            continue;
          }
          long long &curd1 = dp1[other][type];
          if (!curd1) {
            continue;
          }
          dp1[mask ^ other][min(ntype, type)] += cur * curd1;
        }
        if (!other) {
          break;
        }
      }
    }
  }
  printf(
      "%lld"
      "\n",
      dp[(1 << n) - 1][0]);
}
int main() {
  srand(rdtsc());
  precalc();
  while (1) {
    if (!read()) {
      break;
    }
    solve();
  }
  return 0;
}
