#include <bits/stdc++.h>
#define rep(i, l, r) for (int i = l; i <= r; i ++)
#define per(i, r, l) for (int i = r; i >= l; i --)
using namespace std;
const int _ = 2e5 + 5, mod = 1e9 + 7;


/*
注意我们将 .... 称为自由赋值的地方，[   ] 称为被锁定的地方所形成的连通块。
[ ] 内部的复制方案数实际上就是一个容斥，即求相邻两个都合法的方案数即可。
... 是怎么赋值的？
实际上来说：
考虑其两边的连通块：
..... [

]...
左边不取，右边随便取，都可以做到 ；左边取，也可以做到 
...[ 
同理。 
]...[ 
 c
左边取了，那就是 v^c
左边不取，那就是 (v - 1)v * v^{2v - 2} * [(v - 1) * v + 1] 
*/
int n, m, v;
int fac[_], ifac[_], fa[_], b[_], c[_];
struct node {
	int c, d;
	bool operator < (const node &x) const {
		return c < x.c;
	}
} a[_]; 
int power(int x, int y) {
	int r = 1;
	if (y < 0) return 0;
	for ( ; y; y >>= 1, x = 1ll * x * x % mod)
		if (y & 1) r = 1ll * x * r % mod;
	return r;
}
int find (int x) {
	return x == fa[x] ? x : fa[x] = find(fa[x]);
} 
void Luciy() {
	scanf("%d%d%d", &n, &m, &v);
	fac[0] = ifac[0] = 1;
	rep(i, 1, m) fac[i] = 1ll * fac[i - 1] * i % mod, ifac[i] = power(fac[i], mod - 2);
	int ans = 1;
	rep(i, 1, m) fa[i] = i, scanf("%d %d", &a[i].c, &a[i].d);
	sort(a + 1, a + 1 + m);
	map <int, int> mp;
	rep(i, 1, m) mp[a[i].c] = a[i].d;
	rep(i, 1, m) if (mp[a[i].c] != a[i].d) { puts("0"); return ; }
	
	if (n <= 13) {
		ans = 0;
		rep(i, 1, n) c[i] = b[i] = 0;
		rep(i, 1, m) b[a[i].c] = a[i].d;
		vector <int> toa(n + 1, 0), tob(n + 1, 0);
		
		auto dfs = [&](auto &self, int st) -> void {
			if (st == n) {
				bool f = 1;
				rep(i, 1, n) c[i] = b[i];
				rep(i, 1, n - 1) {
					if (c[i] == toa[i]) {
						if (b[i + 1] != tob[i] && b[i + 1]) {
							f = 0; break ;
						}
						c[i + 1] = tob[i];
					}
				}
				ans += f;
				return ;
			}	
			rep(c1, 1, v) rep(c2, 1, v) {
				toa[st] = c1, tob[st] = c2;
				self(self, st + 1);
			}
		} ;	
		dfs(dfs, 1);
		cout << ans << '\n';
		return ;
	}
	m = 0;
	for (auto it : mp) a[++ m].c = it.first, a[m].d = it.second; 
	
	
	int l = 0, r = 0, c = 0;
	
	c = a[1].c - 1;
	if (c)
		ans = 1ll * ans * power(v, c * 2) % mod;

	c = n - a[m].c;
	if (c)
		ans = 1ll * ans * power(v, c * 2) % mod;
	
	auto binom = [&](int x, int y) -> int {
		return 1ll * fac[x] * ifac[y] % mod * ifac[x - y] % mod;
	} ;
	auto calc = [&](int l, int r) -> int {
		int ret = power(v, (r - l) * 2) % mod;
		rep(i, 1, (r - l)) {
			int cf = (1ll * power(v - 1, i) * binom(r - l, i) % mod * power(v, (r - l - i) * 2) % mod);
			if (i & 1) ret += (mod - cf), ret %= mod;
			else ret += cf, ret %= mod;
		}
		return ret;
	} ;
	
	l = r = a[1].c;
	rep(i, 1, m) {
		if (a[i].c == a[i - 1].c + 1 && i > 1) {
			fa[find(i)] = find(i - 1);
		} 
	}
	rep(i, 2, m) {
		int x = find(i - 1), y = find(i);
		if (x != y) {
			if (l) ans = 1ll * ans * calc(l, r) % mod;
			int l1 = a[i - 1].c, r1 = a[i].c, f = 0;
			(f = 1ll * (v - 1) * v % mod * power(v, 2 * (r1 - l1 - 1)) % mod) %= mod;
			(f += 1ll * power(v, r1 - l1 - 1)) %= mod;
			ans = 1ll * ans * f % mod;
			l = a[i].c;	
		}
		r = a[i].c; 
	}
	if (l != r) {
		ans = 1ll * ans * calc(l, r) % mod;
	}
	cout << ans << '\n';
}
int main() {
	freopen("assign.in", "r", stdin);
	freopen("assign.out", "w", stdout);
	int T; 
	cin >> T;
	while (T --)
		Luciy();
	return 0;
}
/*
1
12 2 2
7 2
7 2

*/

