// Code by Heratino & Nelofus
// 星屑落ちて 華は散っても
// キラめく舞台に 生まれて変わる
// 新たな私は 未知なる運命
// 新たな私は まだ見ぬ戯曲
// 愛城華恋は 舞台に一人
// 愛城華恋は 次の舞台へ
#include <bits/stdc++.h>
using i64 = long long;
//{{{
template<typename T>
inline void chkmin(T &a, const T &b) {if (a > b) a = b;}
template<typename T>
inline void chkmax(T &a, const T &b) {if (a < b) a = b;}
//}}}
constexpr int N = 1 << 21;
constexpr int K = 21;
constexpr int mod = 1e9 + 7;
inline int fpow(int x, int k) {
int res = 1;
for (; k; k >>= 1, x = 1ll * x * x % mod)
if (k & 1)
res = 1ll * res * x % mod;
return res;
}
inline int C(i64 n, i64 m) {
int res = 1;
for (int i = n - m + 1; i <= n; i++)
res = 1ll * res * i % mod;
for (int i = 1; i <= m; i++)
res = 1ll * res * fpow(i, mod - 2) % mod;
return res;
}
inline int Add(const int &x, const int &y) {
return x + y >= mod ? x + y - mod : x + y;
}
inline int Sub(const int &x, const int &y) {
return x - y < 0 ? x - y + mod : x - y;
}
int a[N], b[N];
int l[K * K], r[K * K];
int f[K];
inline void oFWT(int *F, int p) {
for (int i = 1; i < (1 << p); i <<= 1) {
for (int j = 0; j < (1 << p); j += i * 2) {
for (int k = 0; k < i; k++) {
int t1 = F[0 * i + j + k], t2 = F[1 * i + j + k];
F[0 * i + j + k] = t1;
F[1 * i + j + k] = Add(t1, t2);
}
}
}
}
inline void iFWT(int *F, int p) {
for (int i = 1; i < (1 << p); i <<= 1) {
for (int j = 0; j < (1 << p); j += i * 2) {
for (int k = 0; k < i; k++) {
int t1 = F[0 * i + j + k], t2 = F[1 * i + j + k];
F[0 * i + j + k] = t1;
F[1 * i + j + k] = Sub(t2, t1);
}
}
}
}
int ans[K];
inline void solve() {
int n1, n2, m, k;
std::cin >> n1 >> n2 >> m >> k;
for (int i = 1; i <= m; i++)
ans[i] = C(n1 - 1, i - 1);
for (int s = 1; s < (1 << m); s++)
a[s] = ans[__builtin_popcount(s)];
for (int i = 1; i <= m; i++)
ans[i] = C(n2 - 1, i - 1);
for (int s = 1; s < (1 << m); s++)
b[s] = ans[__builtin_popcount(s)];
// for (int i = 0; i < (1 << m); i++)
// std::cerr << a[i] << " \n"[i == (1 << m) - 1];
for (int i = 0; i < m; i++)
f[i] = 0;
int ful = 0;
for (int i = 1; i <= k; i++) {
std::cin >> l[i] >> r[i];
l[i]--, r[i]--;
ful |= (1 << l[i]);
ful |= (1 << r[i]);
f[l[i]] |= (1 << r[i]);
f[r[i]] |= (1 << l[i]);
}
for (int s = 1; s < (1 << m); s++) {
for (int i = 0; i < m; i++)
if (!(s >> i & 1) && (s & f[i]) != f[i])
a[s] = b[s] = 0;
}
oFWT(a, m);
oFWT(b, m);
for (int s = 0; s < (1 << m); s++)
a[s] = 1ll * a[s] * b[s] % mod;
iFWT(a, m);
int answer = 0;
for (int s = 0; s < (1 << m); s++)
if ((s & ful) == ful)
answer = Add(answer, a[s]);
std::cout << answer << '\n';
}
int main() {
#ifdef HeratinoNelofus
freopen("input.txt", "r", stdin);
#endif
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int T;
std::cin >> T;
while (T--) solve();
return 0;
}