#include <bits/stdc++.h>
#pragma GCC optimize "-O3"
using namespace std;
using pii = pair<int, int>;
using ll = long long;
using ld = long double;
const ld eps = 1e-9;
const int N = 5010, M = 510, inf = 1e9;
ll mod = 1e9 + 7, seed = 1009;
int GetRand() { return rand() * RAND_MAX + rand(); }
struct Treap {
  Treap *l = nullptr, *r = nullptr;
  ll sum;
  int value, sz = 1, x, y = GetRand();
  Treap() {}
  Treap(int x_, int value_) {
    x = x_;
    sum = value = value_;
  }
};
typedef pair<Treap*, Treap*> ptt;
ll Sum(Treap* cur) { return cur ? cur->sum : 0; }
int Size(Treap* cur) { return cur ? cur->sz : 0; }
void Upd(Treap* cur) {
  if (!cur) return;
  cur->sz = Size(cur->l) + Size(cur->r) + 1;
  cur->sum = Sum(cur->l) + Sum(cur->r) + cur->value;
}
ptt Split(Treap* cur, int x) {
  if (!cur) return {nullptr, nullptr};
  if (cur->x < x) {
    auto tmp = Split(cur->r, x);
    cur->r = tmp.first;
    Upd(cur);
    return {cur, tmp.second};
  } else {
    auto tmp = Split(cur->l, x);
    cur->l = tmp.second;
    Upd(cur);
    return {tmp.first, cur};
  }
}
Treap* Merge(Treap* a, Treap* b) {
  if (!a) return b;
  if (!b) return a;
  if (a->y > b->y) {
    a->r = Merge(a->r, b);
    Upd(a);
    return a;
  } else {
    b->l = Merge(a, b->l);
    Upd(b);
    return b;
  }
}
ll GetSum(Treap* cur, int l, int r, int lt, int rt) {
  if (l > r) return 0;
  if (l == lt && r == rt) return cur->sum;
  int ind = lt + Size(cur->l);
  ll sum = 0;
  if (ind >= l && ind <= r) sum = cur->value;
  sum += GetSum(cur->l, l, min(ind - 1, r), lt, ind - 1);
  sum += GetSum(cur->r, max(ind + 1, l), r, ind + 1, rt);
  return sum;
}
void Solve() {
  int n, m, a;
  ll t;
  pii ans = {0, 1};
  map<int, vector<int>> mp;
  set<int> st;
  Treap* root = nullptr;
  scanf("%d%d%lld", &n, &m, &t);
  for (int i = 0; i < n; ++i) {
    scanf("%d", &a);
    mp[a].push_back(i);
  }
  for (auto& x : mp) {
    for (auto& y : x.second) {
      Treap* tmp = new Treap(y, x.first);
      auto splt = Split(root, y);
      root = Merge(splt.first, tmp);
      root = Merge(root, splt.second);
      st.insert(y);
    }
    while (!st.empty()) {
      int dbl = (st.size() / m - 1) * m;
      if (st.size() % m) dbl += m;
      ll sum = GetSum(root, 0, dbl - 1, 0, st.size() - 1) * 2LL +
               GetSum(root, dbl, st.size() - 1, 0, st.size() - 1);
      if (sum > t) {
        root = Split(root, *st.rbegin()).first;
        st.erase(--st.end());
      } else
        break;
    }
    if (st.size() > ans.first) ans = {(int)st.size(), x.first};
  }
  printf("%d %d\n", ans.first, ans.second);
}
int main() {
  int t;
  scanf("%d", &t);
  while (t--) Solve();
  return 0;
}
