#include <bits/stdc++.h>
using namespace std;
const int N = 5e5;
const int inf = 0x3f3f3f3f;
namespace IO {
inline long long read() {
  long long s = 0, ww = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') ww = -1;
    ch = getchar();
  }
  while ('0' <= ch && ch <= '9') {
    s = 10 * s + ch - '0';
    ch = getchar();
  }
  return s * ww;
}
inline void write(long long x) {
  if (x < 0) putchar('-'), x = -x;
  if (x > 9) write(x / 10);
  putchar('0' + x % 10);
}
};  // namespace IO
using namespace IO;
int n, z;
int a[N + 5], p[N + 5], up[N + 5];
vector<int> pos[N + 5];
struct SegTree {
  int minn[4 * N + 5], flag[4 * N + 5];
  inline void pushup(int u) {
    minn[u] = min(minn[(u << 1)], minn[((u << 1) | 1)]);
  }
  inline void pushdown(int u) {
    if (flag[u] == 0) return;
    int lc = (u << 1), rc = ((u << 1) | 1);
    flag[lc] += flag[u], minn[lc] += flag[u];
    flag[rc] += flag[u], minn[rc] += flag[u];
    flag[u] = 0;
  }
  void build(int u, int l, int r) {
    flag[u] = 0;
    if (l == r) {
      minn[u] = l - 1;
      return;
    }
    int m = (l + r) >> 1;
    build((u << 1), l, m), build(((u << 1) | 1), m + 1, r);
    pushup(u);
  }
  void ud(int u, int l, int r, int ql, int qr, int dx) {
    if (l == ql && r == qr) {
      flag[u] += dx, minn[u] += dx;
      return;
    }
    pushdown(u);
    int m = (l + r) >> 1;
    if (qr <= m)
      ud((u << 1), l, m, ql, qr, dx);
    else if (ql > m)
      ud(((u << 1) | 1), m + 1, r, ql, qr, dx);
    else
      ud((u << 1), l, m, ql, m, dx),
          ud(((u << 1) | 1), m + 1, r, m + 1, qr, dx);
    pushup(u);
  }
  int query(int u, int l, int r, int ql, int qr) {
    if (l == ql && r == qr) return minn[u];
    pushdown(u);
    int m = (l + r) >> 1;
    if (qr <= m)
      return query((u << 1), l, m, ql, qr);
    else if (ql > m)
      return query(((u << 1) | 1), m + 1, r, ql, qr);
    else
      return min(query((u << 1), l, m, ql, m),
                 query(((u << 1) | 1), m + 1, r, m + 1, qr));
  }
} T;
void clear() {
  z = 0;
  up[0] = inf;
  for (register int i = 1; i <= n + 1; i++) up[i] = -1;
  for (register int i = 1; i <= n; i++) {
    pos[i].resize(0);
    pos[i].push_back(0);
  }
}
void solve() {
  n = read();
  clear();
  for (register int i = 1; i <= n; i++) {
    a[i] = read();
    if (a[i] == 0) p[++z] = i;
  }
  T.build(1, 1, n);
  for (register int i = 1; i <= z; i++) {
    for (register int j = p[i - 1] + 1; j < p[i]; j++) {
      int id = a[j];
      int lastpos = pos[id][pos[id].size() - 1];
      pos[id].push_back(j);
      if (lastpos > p[i - 1]) continue;
      int L = 1, R = i;
      while (L < R) {
        int mid = (L + R) >> 1;
        if (p[mid] <= lastpos)
          L = mid + 1;
        else
          R = mid;
      }
      if (L <= i - 1) T.ud(1, 1, n, L, i - 1, 1);
    }
    if (2 * i - 2 >= z) {
      int x = T.query(1, 1, n, 1, i);
      up[z + 1 - i] = x + z - i;
    }
  }
  for (register int i = 1; i <= z; i++) up[i] = min(up[i], up[i - 1]);
  int ans = 0;
  while (ans + 1 <= up[ans + 1]) ans++;
  write(ans), putchar('\n');
}
int main() {
  int Tc = read();
  while (Tc--) solve();
  return 0;
}
