#include namespace { #pragma GCC diagnostic ignored "-Wunused-function" #include #pragma GCC diagnostic warning "-Wunused-function" using namespace std; using namespace atcoder; #define rep(i,n) for(int i = 0; i < (int)(n); i++) #define rrep(i,n) for(int i = (int)(n) - 1; i >= 0; i--) #define all(x) begin(x), end(x) #define rall(x) rbegin(x), rend(x) template bool chmax(T& a, const T& b) { if (a < b) { a = b; return true; } else return false; } template bool chmin(T& a, const T& b) { if (b < a) { a = b; return true; } else return false; } using ll = long long; using P = pair; using VI = vector; using VVI = vector; using VL = vector; using VVL = vector; using mint = modint; } int main() { ios::sync_with_stdio(false); cin.tie(0); int tt; cin >> tt; while(tt--) { int n, p; cin >> n >> p; mint::set_mod(p); VVI a(n, VI(n)); rep(i, n) rep(j, n) cin >> a[i][j]; if (p == 2) { bool ok = true; rep(i, n) { int cnt = 0; rep(j, n) cnt += a[i][j] == -1; if (cnt >= 2) { ok = false; break; } if (cnt == 1) { rep(j, n) { if (a[i][j] == -1) a[i][j] = 1; else a[i][j] = 0; } } } if (!ok) { cout << 0 << '\n'; continue; } } else { int cnt = 0; rep(i, n) rep(j, n) cnt += a[i][j] == -1; if (cnt) { cout << 0 << '\n'; continue; } } vector d(n, vector(n)); rep(i, n) rep(j, n) { assert(a[i][j] >= 0); d[i][j] = a[i][j]; } auto rec = [&](auto self, vector> d) -> mint { if (d.empty()) return 1; int n = d.size(); mint coeff = 1; bool found = false; rep(i, n) if (d[i][0].val()) { found = true; swap(d[i], d[0]); if (i & 1) coeff *= -1; } if (!found) return 0; assert(d[0][0].val()); mint c = d[0][0]; mint ic = c.inv(); for(int i = 1; i < n; i++) { mint x = -d[i][0] * ic; rep(j, n) d[i][j] += d[0][j] * x; } coeff *= c; d.erase(d.begin()); rep(i, n - 1) d[i].erase(d[i].begin()); return self(self, move(d)) * coeff; }; mint ans = rec(rec, move(d)); cout << ans.val() << '\n'; } }