#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp> // Including tree_order_statistics_node_update
using namespace __gnu_pbds;
using namespace std;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
#define endl '\n'
#define int long long
const int N = 2e5, oo = 2e18, MOD = 998244353;
// 1 3 -> 3
// 3 4 -> 2
// 4 7 -> 2
// 5 8 -> 2
class SegTree {
private:
struct Node {
int content;
Node() { content = 0; }
Node(int data) { content = data; }
void update(int data) { content += data; }
};
int size;
vector<Node> tree;
void build(vector<int> &arr, int n, int ni, int lx, int rx) {
if (rx - lx == 1) {
if (lx < n)
tree[ni] = Node(arr[lx]);
return;
}
int mid = (lx + rx) / 2;
build(arr, n, 2 * ni + 1, lx, mid);
build(arr, n, 2 * ni + 2, mid, rx);
tree[ni] = merge(tree[2 * ni + 1], tree[2 * ni + 2]);
}
Node merge(Node a, Node b) { return Node(a.content + b.content); }
void update(int idx, int val, int ni, int lx, int rx) {
if (rx - lx == 1) {
tree[ni].update(val);
return;
}
int mid = (lx + rx) / 2;
if (idx < mid) {
update(idx, val, 2 * ni + 1, lx, mid);
} else {
update(idx, val, 2 * ni + 2, mid, rx);
}
tree[ni] = merge(tree[2 * ni + 1], tree[2 * ni + 2]);
}
Node get(int l, int r, int ni, int lx, int rx) {
if (rx <= l || lx >= r) {
return Node();
}
if (lx >= l && rx <= r) {
return tree[ni];
}
int mid = (lx + rx) / 2;
return merge(get(l, r, 2 * ni + 1, lx, mid), get(l, r, 2 * ni + 2, mid, rx));
}
public:
SegTree(vector<int> &arr) {
int n = arr.size();
size = 1;
while (size < n) {
size *= 2;
}
tree.assign(2 * size, Node());
build(arr, n, 0, 0, size);
}
void update(int idx, int val) { update(idx, val, 0, 0, size); }
int get(int l, int r) { return get(l, r + 1, 0, 0, size).content; }
};
struct coordinate_compression {
private:
vector<long long> comp; // A vector to store the unique, sorted elements for compression.
// A private method to perform compression by sorting and removing duplicates.
void compress() {
sort(comp.begin(), comp.end()); // Sort the vector to arrange elements in ascending order.
comp.erase(unique(comp.begin(), comp.end()), comp.end()); // Remove duplicates to keep only unique elements.
}
public:
// Constructor that initializes the compression vector with the input and compresses it.
coordinate_compression(vector<long long> & v) {
comp = v; // Copy the input vector to the internal 'comp' vector.
compress(); // Call the compress function to sort and remove duplicates.
}
int cnt() {
return comp.size();
}
// Method to get the compressed index of a given value.
int get_index(long long val) {
return lower_bound(comp.begin(), comp.end(), val) - comp.begin();
// Finds the position where 'val' fits in the sorted 'comp' vector.
// Subtracting comp.begin() gives the zero-based index of 'val'.
// If a 1-based index is needed, add +1 to the result.
}
// Method to get the original value from the compressed index.
int get_origin(size_t idx) {
return comp[idx]; // Returns the original value corresponding to the given index in the compressed vector.
}
};
void solve() {
int n, k; cin >> n >> k;
vector<pair<int, int>> a(n);
vector<int> c;
for (int i = 0; i < n ; i++) {
cin >> a[i].first >> a[i].second;
c.push_back(a[i].first);
c.push_back(a[i].second);
}
sort(a.begin(), a.end());
coordinate_compression comp(c);
for (int i = 0; i < n ; i++) {
a[i].first = comp.get_index(a[i].first);
a[i].second = comp.get_index(a[i].second);
}
int cnt = comp.cnt();
vector<int> b(cnt);
SegTree tree(b);
int ans = 1;
for (int i = 0; i < n; i++) {
int c = tree.get(a[i].first, cnt - 1);
if (c >= k) {
cout << 0 << endl;
return;
}
ans = (ans * (k - c)) % MOD;
tree.update(a[i].second, 1);
}
cout << ans << endl;
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
// #ifndef ONLINE_JUDGE
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
// #endif
int t; t = 1;
cin >> t;
while (t--) solve();
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CiNpbmNsdWRlIDxleHQvcGJfZHMvYXNzb2NfY29udGFpbmVyLmhwcD4gLy8gQ29tbW9uIGZpbGUKI2luY2x1ZGUgPGV4dC9wYl9kcy90cmVlX3BvbGljeS5ocHA+IC8vIEluY2x1ZGluZyB0cmVlX29yZGVyX3N0YXRpc3RpY3Nfbm9kZV91cGRhdGUKCnVzaW5nIG5hbWVzcGFjZSBfX2dudV9wYmRzOwp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdHlwZWRlZiB0cmVlPGludCxudWxsX3R5cGUsbGVzczxpbnQ+LHJiX3RyZWVfdGFnLHRyZWVfb3JkZXJfc3RhdGlzdGljc19ub2RlX3VwZGF0ZT4gb3JkZXJlZF9zZXQ7CgojZGVmaW5lIGVuZGwgICAgICdcbicKI2RlZmluZSBpbnQgICAgICBsb25nIGxvbmcKCmNvbnN0IGludCBOID0gMmU1LCBvbyA9IDJlMTgsIE1PRCA9IDk5ODI0NDM1MzsKCgovLyAxIDMgLT4gMwovLyAzIDQgLT4gMgovLyA0IDcgLT4gMgovLyA1IDggLT4gMgoKY2xhc3MgU2VnVHJlZSB7CnByaXZhdGU6CiAgICBzdHJ1Y3QgTm9kZSB7CiAgICAgICAgaW50IGNvbnRlbnQ7CgogICAgICAgIE5vZGUoKSB7IGNvbnRlbnQgPSAwOyB9CiAgICAgICAgTm9kZShpbnQgZGF0YSkgeyBjb250ZW50ID0gZGF0YTsgfQogICAgICAgIHZvaWQgdXBkYXRlKGludCBkYXRhKSB7IGNvbnRlbnQgKz0gZGF0YTsgfQogICAgfTsKCiAgICBpbnQgc2l6ZTsKICAgIHZlY3RvcjxOb2RlPiB0cmVlOwogICAgdm9pZCBidWlsZCh2ZWN0b3I8aW50PiAmYXJyLCBpbnQgbiwgaW50IG5pLCBpbnQgbHgsIGludCByeCkgewogICAgICAgIGlmIChyeCAtIGx4ID09IDEpIHsKICAgICAgICAgICAgaWYgKGx4IDwgbikKICAgICAgICAgICAgICAgIHRyZWVbbmldID0gTm9kZShhcnJbbHhdKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBpbnQgbWlkID0gKGx4ICsgcngpIC8gMjsKICAgICAgICBidWlsZChhcnIsIG4sIDIgKiBuaSArIDEsIGx4LCBtaWQpOwogICAgICAgIGJ1aWxkKGFyciwgbiwgMiAqIG5pICsgMiwgbWlkLCByeCk7CiAgICAgICAgdHJlZVtuaV0gPSBtZXJnZSh0cmVlWzIgKiBuaSArIDFdLCB0cmVlWzIgKiBuaSArIDJdKTsKICAgIH0KICAgIE5vZGUgbWVyZ2UoTm9kZSBhLCBOb2RlIGIpIHsgcmV0dXJuIE5vZGUoYS5jb250ZW50ICsgYi5jb250ZW50KTsgfQogICAgdm9pZCB1cGRhdGUoaW50IGlkeCwgaW50IHZhbCwgaW50IG5pLCBpbnQgbHgsIGludCByeCkgewogICAgICAgIGlmIChyeCAtIGx4ID09IDEpIHsKICAgICAgICAgICAgdHJlZVtuaV0udXBkYXRlKHZhbCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgaW50IG1pZCA9IChseCArIHJ4KSAvIDI7CiAgICAgICAgaWYgKGlkeCA8IG1pZCkgewogICAgICAgICAgICB1cGRhdGUoaWR4LCB2YWwsIDIgKiBuaSArIDEsIGx4LCBtaWQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHVwZGF0ZShpZHgsIHZhbCwgMiAqIG5pICsgMiwgbWlkLCByeCk7CiAgICAgICAgfQogICAgICAgIHRyZWVbbmldID0gbWVyZ2UodHJlZVsyICogbmkgKyAxXSwgdHJlZVsyICogbmkgKyAyXSk7CiAgICB9CiAgICAgTm9kZSBnZXQoaW50IGwsIGludCByLCBpbnQgbmksIGludCBseCwgaW50IHJ4KSB7CiAgICAgICAgaWYgKHJ4IDw9IGwgfHwgbHggPj0gcikgewogICAgICAgICAgICByZXR1cm4gTm9kZSgpOwogICAgICAgIH0KICAgICAgICBpZiAobHggPj0gbCAmJiByeCA8PSByKSB7CiAgICAgICAgICAgIHJldHVybiB0cmVlW25pXTsKICAgICAgICB9CiAgICAgICAgaW50IG1pZCA9IChseCArIHJ4KSAvIDI7CiAgICAgICAgcmV0dXJuIG1lcmdlKGdldChsLCByLCAyICogbmkgKyAxLCBseCwgbWlkKSwgZ2V0KGwsIHIsIDIgKiBuaSArIDIsIG1pZCwgcngpKTsKICAgIH0KCnB1YmxpYzoKICAgIFNlZ1RyZWUodmVjdG9yPGludD4gJmFycikgewogICAgICAgIGludCBuID0gYXJyLnNpemUoKTsKICAgICAgICBzaXplID0gMTsKICAgICAgICB3aGlsZSAoc2l6ZSA8IG4pIHsKICAgICAgICAgICAgc2l6ZSAqPSAyOwogICAgICAgIH0KICAgICAgICB0cmVlLmFzc2lnbigyICogc2l6ZSwgTm9kZSgpKTsKICAgICAgICBidWlsZChhcnIsIG4sIDAsIDAsIHNpemUpOwogICAgfQogICAgdm9pZCB1cGRhdGUoaW50IGlkeCwgaW50IHZhbCkgeyB1cGRhdGUoaWR4LCB2YWwsIDAsIDAsIHNpemUpOyB9CiAgICBpbnQgZ2V0KGludCBsLCBpbnQgcikgeyByZXR1cm4gZ2V0KGwsIHIgKyAxLCAwLCAwLCBzaXplKS5jb250ZW50OyB9Cn07CgpzdHJ1Y3QgY29vcmRpbmF0ZV9jb21wcmVzc2lvbiB7CnByaXZhdGU6CiAgICB2ZWN0b3I8bG9uZyBsb25nPiBjb21wOyAvLyBBIHZlY3RvciB0byBzdG9yZSB0aGUgdW5pcXVlLCBzb3J0ZWQgZWxlbWVudHMgZm9yIGNvbXByZXNzaW9uLgogCiAgICAvLyBBIHByaXZhdGUgbWV0aG9kIHRvIHBlcmZvcm0gY29tcHJlc3Npb24gYnkgc29ydGluZyBhbmQgcmVtb3ZpbmcgZHVwbGljYXRlcy4KICAgIHZvaWQgY29tcHJlc3MoKSB7CiAgICAgICAgc29ydChjb21wLmJlZ2luKCksIGNvbXAuZW5kKCkpOyAvLyBTb3J0IHRoZSB2ZWN0b3IgdG8gYXJyYW5nZSBlbGVtZW50cyBpbiBhc2NlbmRpbmcgb3JkZXIuCiAgICAgICAgY29tcC5lcmFzZSh1bmlxdWUoY29tcC5iZWdpbigpLCBjb21wLmVuZCgpKSwgY29tcC5lbmQoKSk7IC8vIFJlbW92ZSBkdXBsaWNhdGVzIHRvIGtlZXAgb25seSB1bmlxdWUgZWxlbWVudHMuCiAgICB9CiAKcHVibGljOgogICAgLy8gQ29uc3RydWN0b3IgdGhhdCBpbml0aWFsaXplcyB0aGUgY29tcHJlc3Npb24gdmVjdG9yIHdpdGggdGhlIGlucHV0IGFuZCBjb21wcmVzc2VzIGl0LgogICAgY29vcmRpbmF0ZV9jb21wcmVzc2lvbih2ZWN0b3I8bG9uZyBsb25nPiAmIHYpIHsKICAgICAgICBjb21wID0gdjsgLy8gQ29weSB0aGUgaW5wdXQgdmVjdG9yIHRvIHRoZSBpbnRlcm5hbCAnY29tcCcgdmVjdG9yLgogICAgICAgIGNvbXByZXNzKCk7IC8vIENhbGwgdGhlIGNvbXByZXNzIGZ1bmN0aW9uIHRvIHNvcnQgYW5kIHJlbW92ZSBkdXBsaWNhdGVzLgogICAgfQogICAgaW50IGNudCgpIHsKICAgICAgICByZXR1cm4gY29tcC5zaXplKCk7CiAgICB9CiAgICAvLyBNZXRob2QgdG8gZ2V0IHRoZSBjb21wcmVzc2VkIGluZGV4IG9mIGEgZ2l2ZW4gdmFsdWUuCiAgICBpbnQgZ2V0X2luZGV4KGxvbmcgbG9uZyB2YWwpIHsKICAgICAgICByZXR1cm4gbG93ZXJfYm91bmQoY29tcC5iZWdpbigpLCBjb21wLmVuZCgpLCB2YWwpIC0gY29tcC5iZWdpbigpOyAKICAgICAgICAvLyBGaW5kcyB0aGUgcG9zaXRpb24gd2hlcmUgJ3ZhbCcgZml0cyBpbiB0aGUgc29ydGVkICdjb21wJyB2ZWN0b3IuCiAgICAgICAgLy8gU3VidHJhY3RpbmcgY29tcC5iZWdpbigpIGdpdmVzIHRoZSB6ZXJvLWJhc2VkIGluZGV4IG9mICd2YWwnLgogICAgICAgIC8vIElmIGEgMS1iYXNlZCBpbmRleCBpcyBuZWVkZWQsIGFkZCArMSB0byB0aGUgcmVzdWx0LgogICAgfQogCiAgICAvLyBNZXRob2QgdG8gZ2V0IHRoZSBvcmlnaW5hbCB2YWx1ZSBmcm9tIHRoZSBjb21wcmVzc2VkIGluZGV4LgogICAgaW50IGdldF9vcmlnaW4oc2l6ZV90IGlkeCkgewogICAgICAgIHJldHVybiBjb21wW2lkeF07IC8vIFJldHVybnMgdGhlIG9yaWdpbmFsIHZhbHVlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIGluZGV4IGluIHRoZSBjb21wcmVzc2VkIHZlY3Rvci4KICAgIH0KfTsKCiAKCnZvaWQgc29sdmUoKSB7CiAgICBpbnQgbiwgazsgY2luID4+IG4gPj4gazsKICAgIHZlY3RvcjxwYWlyPGludCwgaW50Pj4gYShuKTsKICAgIHZlY3RvcjxpbnQ+IGM7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IG4gOyBpKyspIHsKICAgICAgICBjaW4gPj4gYVtpXS5maXJzdCA+PiBhW2ldLnNlY29uZDsKICAgICAgICBjLnB1c2hfYmFjayhhW2ldLmZpcnN0KTsKICAgICAgICBjLnB1c2hfYmFjayhhW2ldLnNlY29uZCk7CiAgICB9CiAgICBzb3J0KGEuYmVnaW4oKSwgYS5lbmQoKSk7CiAgICBjb29yZGluYXRlX2NvbXByZXNzaW9uIGNvbXAoYyk7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IG4gOyBpKyspIHsKICAgICAgICBhW2ldLmZpcnN0ID0gY29tcC5nZXRfaW5kZXgoYVtpXS5maXJzdCk7CiAgICAgICAgYVtpXS5zZWNvbmQgPSBjb21wLmdldF9pbmRleChhW2ldLnNlY29uZCk7CiAgICB9CiAgICBpbnQgY250ID0gY29tcC5jbnQoKTsKICAgIHZlY3RvcjxpbnQ+IGIoY250KTsKICAgIFNlZ1RyZWUgdHJlZShiKTsKICAgIGludCBhbnMgPSAxOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICBpbnQgYyA9IHRyZWUuZ2V0KGFbaV0uZmlyc3QsIGNudCAtIDEpOwogICAgICAgIGlmIChjID49IGspIHsKICAgICAgICAgICAgY291dCA8PCAwIDw8IGVuZGw7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgYW5zID0gKGFucyAqIChrIC0gYykpICUgTU9EOwogICAgICAgIHRyZWUudXBkYXRlKGFbaV0uc2Vjb25kLCAxKTsKICAgIH0KICAgIGNvdXQgPDwgYW5zIDw8IGVuZGw7Cn0KCgpzaWduZWQgbWFpbigpIHsKICAgIGlvc19iYXNlOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpOyAKICAgIGNpbi50aWUoTlVMTCk7IGNvdXQudGllKE5VTEwpOwogICAgLy8gI2lmbmRlZiBPTkxJTkVfSlVER0UgCiAgICAvLyAgICBmcmVvcGVuKCJpbnB1dC50eHQiLCAiciIsIHN0ZGluKTsgCiAgICAvLyAgICBmcmVvcGVuKCJvdXRwdXQudHh0IiwgInciLCBzdGRvdXQpOyAKICAgIC8vICNlbmRpZiAKICAgIGludCB0OyB0ID0gMTsKICAgIGNpbiA+PiB0OwogICAgd2hpbGUgKHQtLSkgc29sdmUoKTsKICAgIHJldHVybiAwOwp9Cg==