← Home
package main

import (
	"io"
	"os"
	"strconv"
)

func nextInt(data []byte, idx *int) int {
	n := len(data)
	for *idx < n && (data[*idx] < '0' || data[*idx] > '9') {
		*idx++
	}
	val := 0
	for *idx < n && data[*idx] >= '0' && data[*idx] <= '9' {
		val = val*10 + int(data[*idx]-'0')
		*idx++
	}
	return val
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func queryPrefix(tree []int, node, l, r, q int) int {
	if q <= 0 {
		return 0
	}
	if r <= q {
		return tree[node]
	}
	m := (l + r) >> 1
	if q <= m {
		return queryPrefix(tree, node<<1, l, m, q)
	}
	left := tree[node<<1]
	right := queryPrefix(tree, node<<1|1, m+1, r, q)
	if left > right {
		return left
	}
	return right
}

func updatePoint(tree []int, node, l, r, pos, val int) {
	if l == r {
		if val > tree[node] {
			tree[node] = val
		}
		return
	}
	m := (l + r) >> 1
	if pos <= m {
		updatePoint(tree, node<<1, l, m, pos, val)
	} else {
		updatePoint(tree, node<<1|1, m+1, r, pos, val)
	}
	if tree[node<<1] > tree[node<<1|1] {
		tree[node] = tree[node<<1]
	} else {
		tree[node] = tree[node<<1|1]
	}
}

func findFirstGE(tree []int, node, l, r, start, val int) int {
	if r < start || tree[node] < val {
		return 0
	}
	if l == r {
		return l
	}
	m := (l + r) >> 1
	if start <= m {
		res := findFirstGE(tree, node<<1, l, m, start, val)
		if res != 0 {
			return res
		}
	}
	return findFirstGE(tree, node<<1|1, m+1, r, start, val)
}

func updateRangeMax(lazy []int, node, l, r, ql, qr, val int) {
	if qr < l || r < ql {
		return
	}
	if ql <= l && r <= qr {
		if val > lazy[node] {
			lazy[node] = val
		}
		return
	}
	m := (l + r) >> 1
	if ql <= m {
		updateRangeMax(lazy, node<<1, l, m, ql, qr, val)
	}
	if qr > m {
		updateRangeMax(lazy, node<<1|1, m+1, r, ql, qr, val)
	}
}

func queryPointMax(lazy []int, node, l, r, pos, acc int) int {
	if lazy[node] > acc {
		acc = lazy[node]
	}
	if l == r {
		return acc
	}
	m := (l + r) >> 1
	if pos <= m {
		return queryPointMax(lazy, node<<1, l, m, pos, acc)
	}
	return queryPointMax(lazy, node<<1|1, m+1, r, pos, acc)
}

func bitUpdate(bit []int, idx, val int) {
	for idx < len(bit) {
		if val > bit[idx] {
			bit[idx] = val
		}
		idx += idx & -idx
	}
}

func bitQuery(bit []int, idx int) int {
	res := 0
	for idx > 0 {
		if bit[idx] > res {
			res = bit[idx]
		}
		idx -= idx & -idx
	}
	return res
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	ptr := 0
	t := nextInt(data, &ptr)
	out := make([]byte, 0, t*4)

	for ; t > 0; t-- {
		n := nextInt(data, &ptr)
		a := make([]int, n)
		for i := 0; i < n; i++ {
			a[i] = nextInt(data, &ptr)
		}

		treeA := make([]int, 4*n+5)
		treeZero := make([]int, 4*n+5)
		bit := make([]int, n+2)

		ans := 1

		for i, v := range a {
			curA := queryPrefix(treeA, 1, 1, n, v)
			lastGreater := 0
			if v < n {
				lastGreater = bitQuery(bit, n-v)
			}
			lastZero := queryPointMax(treeZero, 1, 1, n, v, 0)

			add := 0
			if lastGreater > lastZero {
				add = 1
			}

			L := curA + add + 1
			if L > ans {
				ans = L
			}

			idx := findFirstGE(treeA, 1, 1, n, v, L)
			r := n
			if idx != 0 {
				r = idx - 1
			}
			if v <= r {
				updateRangeMax(treeZero, 1, 1, n, v, r, i+1)
			}

			updatePoint(treeA, 1, 1, n, v, L)
			bitUpdate(bit, n-v+1, i+1)
		}

		out = strconv.AppendInt(out, int64(ans), 10)
		out = append(out, '\n')
	}

	os.Stdout.Write(out)
}