#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
const int N = 1e5 + 10;
int a[N];
vector<int> ans[1001];
int n, al, cnt;
int hdi;
struct lst {
  int nxt, pre, ind;
} cur[N];
inline void del(int p) {
  if (cur[p].pre) {
    lst &b = cur[cur[p].pre];
    b.nxt = cur[p].nxt;
  }
  if (cur[p].nxt) {
    lst &b = cur[cur[p].nxt];
    b.pre = cur[p].pre;
  }
  if (!cur[p].pre) hdi = cur[p].nxt;
}
struct Tree_Array {
  int mxv[N], pos[N];
  inline void init() {
    memset(mxv, 0, (n + 1) * 4);
    memset(pos, 0, (n + 1) * 4);
  }
  inline void update(int x, int v, int ps) {
    while (x <= n) {
      if (v > mxv[x]) mxv[x] = v, pos[x] = ps;
      x += (x & (-x));
    }
  }
  pair<int, int> query(int x) {
    pair<int, int> res = pair<int, int>(0, 0);
    while (x) {
      if (mxv[x] > res.first) res = pair<int, int>(mxv[x], pos[x]);
      x -= (x & (-x));
    }
    return res;
  }
} T;
int vis[N], f[N], d[N], g[N];
int S[N], top, b[N], lt[N];
void divide() {
  S[top = 1] = 0x3f3f3f3f;
  b[1] = 0;
  for (int i = hdi; i; i = cur[i].nxt) {
    int pos = upper_bound(S + 1, S + top + 1, a[i]) - S;
    lt[i] = b[pos];
    b[pos] = i;
    S[pos] = a[i];
    if (pos == top) S[++top] = 0x3f3f3f3f, b[top] = 0;
  }
  for (register int i = 1; i <= top - 1; i += 1) {
    ++cnt;
    for (int j = b[i]; j; j = lt[j]) ans[cnt].push_back(a[j]), ++al;
  }
}
int main() {
  int t;
  scanf("%d", &t);
  while (t--) {
    scanf("%d", &n);
    for (register int i = 1; i <= n; i += 1) scanf("%d", a + i);
    for (register int i = 1; i <= n; i += 1) vis[i] = 0;
    for (register int i = 1; i <= 1000; i += 1) ans[i].clear();
    al = 0, cnt = 0;
    hdi = 1;
    for (register int i = 1; i <= n; i += 1) {
      cur[i].pre = i - 1;
      if (i < n) cur[i].nxt = i + 1;
      cur[i].ind = i;
    }
    cur[n].nxt = 0;
    while (al < n) {
      int mxv = 0, mxp = 0;
      T.init();
      for (int i = hdi; i; i = cur[i].nxt) {
        pair<int, int> q = T.query(a[i] - 1);
        f[i] = 1 + q.first;
        d[i] = q.second;
        T.update(a[i], f[i], i);
        if (f[i] > mxv) mxv = f[i], mxp = i;
      }
      if (1LL * (mxv) * (mxv + 1) > 2LL * (n - al)) {
        ++cnt;
        while (mxp) {
          del(mxp);
          ans[cnt].push_back(a[mxp]);
          mxp = d[mxp];
          ++al;
        }
      } else {
        divide();
        break;
      }
    }
    printf("%d\n", cnt);
    for (register int i = 1; i <= cnt; i += 1) {
      printf("%d ", ans[i].size());
      for (register int j = ans[i].size() - 1; j >= 0; j -= 1)
        printf("%d ", ans[i][j]);
      puts("");
    }
  }
  return 0;
}
