You are on page 1of 5

@sup777exams @sup777exams

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

class T2 {
InputStream is;
PrintWriter out;
String INPUT = "";

void solve()
{
int mod = 1000000007;
for(int T = ni();T > 0;T--){
int n = ni(), m = ni(), K = ni();
int[] from = new int[m];
int[] to = new int[m];
for(int i = 0;i < m;i++){
from[i] = ni()-1;
to[i] = ni()-1;
}
int[][] g = packU(n, from, to);
long s1 = pow(2, n-2, mod) * m % mod;
long es = 0;
for(int[] row : g){
es += (long)row.length*(row.length-1)/2;
}
es %= mod;
long all = (long)m*(m-1)/2%mod;
long s11 = (pow(2, n-3, mod) * (es%mod) + pow(2, n-4,
mod) * ((all-es)%mod))%mod;
if(s11 < 0)s11 += mod;

long e3 = 0;
// A-B,A-C,A-D
for(int[] row : g){
e3 += (long)row.length*(row.length-1)*(row.length-
2)/6;
}
e3 %= mod;
long eh = 0;
// A-B,A-C,C-D
for(int i = 0;i < n;i++){
for(int e : g[i]){
if(i < e){
eh += (long)(g[i].length-1) *
(long)(g[e].length-1)%mod;
}
}
}

// A-B,A-C,C-A
long et = count3Cycles(g);
eh -= et*3;
eh %= mod;
if(eh < 0)eh += mod;

// A-B,A-C,X-Y

t.me/f_a_a_n_g_777
@sup777exams @sup777exams

// sum_{b,c} (m-2-(deg[a]-2)-(deg[b]-1)-(deg[c]-1)
//
long e2 = 0;
for(int[] row : g){
e2 += (long)row.length*(row.length-1)/2*(m-
row.length+2);
for(int e : row){
e2 -= (long)g[e].length*(row.length-1)%mod;
}
e2 %= mod;
if(e2 < 0)e2 += mod;
}
e2 += et*3;
e2 %= mod;

long ez = (long)m*(m-1)*(m-2)/6 - e3 - eh - et - e2;


ez %= mod;
if(ez < 0)ez += mod;

long s111 = (pow(2, n-3, mod) * et + pow(2, n-4, mod) *


(eh+e3) + pow(2, n-5, mod) * e2 + pow(2, n-6, mod) * ez) % mod;
if(s111 < 0)s111 += mod;
tr(et, eh, e3, e2, ez);

long s2 = s1;
long s21 = s11;
long s3 = s1;
if(K == 1){
out.println(s1);
}else if(K == 2){
out.println((s2 + 2*s11) % mod);
}else{
out.println((s3 + 6*s21 + 6*s111) % mod);
}
}
}

public static long count3Cycles(int[][] g)


{
int n = g.length;
// sort by (degree, id) ascending.
long[] ord = new long[n];
for(int i = 0;i < n;i++)ord[i] = (long)g[i].length<<32|i;
Arrays.sort(ord);
int[] map = new int[n];
for(int i = 0;i < n;i++)map[(int)ord[i]] = i;
g = trans(g, map);
for(int[] row : g)Arrays.sort(row);

long c3 = 0;
boolean[] nei = new boolean[n];
for(int i = n-1;i >= 0;i--){
for(int e : g[i])nei[e] = true;
for(int e : g[i]){
if(e >= i)break;
for(int f : g[e]){
if(f >= e)break;
if(nei[f])c3++;
}
}

t.me/f_a_a_n_g_777
@sup777exams @sup777exams

for(int e : g[i])nei[e] = false;


}

return c3;
}

private static int[][] trans(int[][] g, int[] map)


{
int n = g.length;
int[][] ret = new int[n][];
for(int i = 0;i < n;i++){
ret[map[i]] = new int[g[i].length];
for(int j = 0;j < g[i].length;j++){
ret[map[i]][j] = map[g[i][j]];
}
}
return ret;
}

public static long pow(long a, long n, long mod) {


// a %= mod;
long ret = 1;
int x = 63 - Long.numberOfLeadingZeros(n);
for (; x >= 0; x--) {
ret = ret * ret % mod;
if (n << 63 - x < 0)
ret = ret * a % mod;
}
return ret;
}

static int[][] packU(int n, int[] from, int[] to) {


int[][] g = new int[n][];
int[] p = new int[n];
for (int f : from)
p[f]++;
for (int t : to)
p[t]++;
for (int i = 0; i < n; i++)
g[i] = new int[p[i]];
for (int i = 0; i < from.length; i++) {
g[from[i]][--p[from[i]]] = to[i];
g[to[i]][--p[to[i]]] = from[i];
}
return g;
}

void run() throws Exception


{
is = INPUT.isEmpty() ? System.in : new
ByteArrayInputStream(INPUT.getBytes());
out = new PrintWriter(System.out);

long s = System.currentTimeMillis();
solve();
out.flush();
if(!INPUT.isEmpty())tr(System.currentTimeMillis()-s+"ms");
}

t.me/f_a_a_n_g_777
@sup777exams @sup777exams

public static void main(String[] args) throws Exception { new


T2().run(); }

private byte[] inbuf = new byte[1024];


public int lenbuf = 0, ptrbuf = 0;

private int readByte()


{
if(lenbuf == -1)throw new InputMismatchException();
if(ptrbuf >= lenbuf){
ptrbuf = 0;
try { lenbuf = is.read(inbuf); } catch (IOException e) {
throw new InputMismatchException(); }
if(lenbuf <= 0)return -1;
}
return inbuf[ptrbuf++];
}

private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126);


}
private int skip() { int b; while((b = readByte()) != -1 &&
isSpaceChar(b)); return b; }

private double nd() { return Double.parseDouble(ns()); }


private char nc() { return (char)skip(); }

private String ns()


{
int b = skip();
StringBuilder sb = new StringBuilder();
while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) &&
b != ' ')
sb.appendCodePoint(b);
b = readByte();
}
return sb.toString();
}

private char[] ns(int n)


{
char[] buf = new char[n];
int b = skip(), p = 0;
while(p < n && !(isSpaceChar(b))){
buf[p++] = (char)b;
b = readByte();
}
return n == p ? buf : Arrays.copyOf(buf, p);
}

private char[][] nm(int n, int m)


{
char[][] map = new char[n][];
for(int i = 0;i < n;i++)map[i] = ns(m);
return map;
}

private int[] na(int n)


{
int[] a = new int[n];
for(int i = 0;i < n;i++)a[i] = ni();

t.me/f_a_a_n_g_777
@sup777exams @sup777exams

return a;
}

private int ni()


{
int num = 0, b;
boolean minus = false;
while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b
== '-'));
if(b == '-'){
minus = true;
b = readByte();
}

while(true){
if(b >= '0' && b <= '9'){
num = num * 10 + (b - '0');
}else{
return minus ? -num : num;
}
b = readByte();
}
}

private long nl()


{
long num = 0;
int b;
boolean minus = false;
while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b
== '-'));
if(b == '-'){
minus = true;
b = readByte();
}

while(true){
if(b >= '0' && b <= '9'){
num = num * 10 + (b - '0');
}else{
return minus ? -num : num;
}
b = readByte();
}
}

private void tr(Object... o) { if(INPUT.length() >


0)System.out.println(Arrays.deepToString(o)); }
}

t.me/f_a_a_n_g_777

You might also like