#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i)) #define rer(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i)) #define reu(i,l,u) for(int (i)=(int)(l);(i)<(int)(u);++(i)) #if defined(_MSC_VER) || __cplusplus > 199711L #define aut(r,v) auto r = (v) #else #define aut(r,v) __typeof(v) r = (v) #endif #define each(it,o) for(aut(it, (o).begin()); it != (o).end(); ++ it) #define all(o) (o).begin(), (o).end() #define pb(x) push_back(x) #define mp(x,y) make_pair((x),(y)) #define mset(m,v) memset(m,v,sizeof(m)) #define INF 0x3f3f3f3f #define INFL 0x3f3f3f3f3f3f3f3fLL using namespace std; typedef vector vi; typedef pair pii; typedef vector > vpii; typedef long long ll; template inline void amin(T &x, U y) { if(y < x) x = y; } template inline void amax(T &x, U y) { if(x < y) x = y; } struct UnionFind { vector data; void init(int n) { data.assign(n, -1); } bool unionSet(int x, int y) { x = root(x); y = root(y); if(x != y) { if(data[y] < data[x]) swap(x, y); data[x] += data[y]; data[y] = x; } return x != y; } bool findSet(int x, int y) { return root(x) == root(y); } int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); } int size(int x) { return -data[root(x)]; } }; template struct ModInt { static const int Mod = MOD; unsigned x; ModInt() : x(0) {} ModInt(signed sig) { int sigt = sig % MOD; if(sigt < 0) sigt += MOD; x = sigt; } ModInt(signed long long sig) { int sigt = sig % MOD; if(sigt < 0) sigt += MOD; x = sigt; } int get() const { return (int)x; } ModInt &operator+=(ModInt that) { if((x += that.x) >= MOD) x -= MOD; return *this; } ModInt &operator-=(ModInt that) { if((x += MOD - that.x) >= MOD) x -= MOD; return *this; } ModInt &operator*=(ModInt that) { x = (unsigned long long)x * that.x % MOD; return *this; } ModInt operator+(ModInt that) const { return ModInt(*this) += that; } ModInt operator-(ModInt that) const { return ModInt(*this) -= that; } ModInt operator*(ModInt that) const { return ModInt(*this) *= that; } }; typedef ModInt<1000000007> mint; int naivegetdist(int i, int p, int t, const vector &g) { if(i == t) return 0; each(j, g[i]) if(*j != p) { int d = naivegetdist(*j, i, t, g); if(d != -1) return d + 1; } return -1; } int naivegetsize(int i, int p, const vector &g) { int r = 1; each(j, g[i]) if(*j != p) { r += naivegetsize(*j, i, g); } return r; } int main() { static mint C[1000 + 1][1000 + 1]; for(int i = 0; i <= 1000; i ++) { C[i][0] = 1; for(int j = 1; j <= i; j ++) C[i][j] = C[i - 1][j - 1] + C[i - 1][j]; } int T; scanf("%d", &T); for(int ii = 0; ii < T; ++ ii) { int N; int K; scanf("%d%d", &N, &K); vector c(N); for(int i = 0; i < N; ++ i) { scanf("%d", &c[i]); } UnionFind uf; uf.init(N); int cycles = 0; vpii cycleEdges; vector g(N); rep(i, N) { if(uf.unionSet(i, c[i])) { g[i].push_back(c[i]); g[c[i]].push_back(i); } else { cycleEdges.push_back(mp(i, c[i])); } } vpii sizes; each(i, cycleEdges) { int cycle = 1 + naivegetdist(i->first, -1, i->second, g); int size = naivegetsize(i->first, -1, g); sizes.push_back(mp(size, cycle)); } vector dp(N + 1); dp[N] = 1; rep(i, sizes.size()) { int size = sizes[i].first, cycle = sizes[i].second; for(int j = 0; j <= N; ++ j) { mint x = dp[j]; if(x.get() == 0) continue; dp[j] = mint(); rer(k, 0, size - 1) { mint a = x * (C[size][k] - (k >= cycle ? C[size - cycle][k - cycle] : mint())); if(k % 2 == 0) dp[j - k] += a; else dp[j - k] -= a; } rer(k, cycle, size) { mint a = x * C[size - cycle][k - cycle]; if(k % 2 == 0) dp[j - (k - 1)] += a; else dp[j - (k - 1)] -= a; } } } mint ans; mint coeff = 1; rer(j, 0, N) { ans += dp[j] * coeff; coeff *= K; } printf("%d\n", ans.get()); } return 0; }