#include using namespace std; #include using namespace atcoder; using mint = atcoder::modint998244353; // using mint = double; #define rep(i, l, r) for (int i = (int)(l); i<(int)(r); i++) #define ll long long #define ld long double #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #define siz(x) (int)(x).size() template bool chmin(T& a, T b) { if (a > b) {a = b; return true;} return false; } template bool chmax(T& a, T b) { if (a < b) {a = b; return true;} return false; } const int inf = 1e9; const ll INF = 4e18; template using pq = priority_queue, less>; template using spq = priority_queue, greater>; vector di = {0, 0, 1, -1}; vector dj = {1, -1, 0, 0}; struct Edge { int to, cost; }; void solve() { int N, L; cin >> N >> L; vector D(N); for (int& d : D) cin >> d; int cnt = 0; if (L%2 == 0) { rep(i, 0, N) { if (D[i] < L / 2) { if (binary_search(all(D), D[i] + L / 2)) cnt++; } } } // cout << cnt << endl; vector inv(N+1); rep(i, 1, N+1) { inv[i] = mint(1) / i; } if (cnt <= 1) { //NG mint ans = 0; //全部埋めるまでにかかる回数 for (int i = 1; i <= N; i++) ans += N * inv[i]; cout << ans.val() << endl; return; } vector dp(cnt + 1, vector(3)); for (int i = cnt; i >= 0; i--) { for (int j = 2; j >= 0; j--) { if (j > i) continue; if (j == 2) { dp[i][j] = 0; continue; } int zero = cnt - i; int one = i - j; int two = j; mint blank = 2 * zero + one; //成功確率 mint p = blank / N; //コスト mint cost = 1 / p; //0 -> 1 if (zero > 0) dp[i][j] += dp[i+1][j] * mint(2 * zero) / blank; //1 -> 0 if (one > 0) dp[i][j] += dp[i][j+1] * mint(one) / blank; dp[i][j] += cost; } } cout << dp[0][0].val() << endl; } int main() { int T; cin >> T; while(T--) solve(); }