import sys
def fill(graph):

    dp=[[True,True,True] for _ in range(n+1)]
    l=[-1 for i in range(n+1)]
    from collections import defaultdict
    vis=defaultdict(int)
    count1,count2,count3=0,0,0
    for i in graph:
        if dp[i][0]:
            #fill
            l[i],count1=1,count1+1
            vis[i]=1
            for j in graph[i]:
                if vis[j]==1:
                    return [-1]
                dp[j][0]=False
        elif dp[i][1]:
            #fill
            l[i]=2
            count2+=1
            vis[i]=2
            for j in graph[i]:
                if vis[j]==2:
                    return [-1]
                dp[j][1]=False
        elif dp[i][2]:
            #fill
            l[i]=3
            count3+=1
            vis[i]=3
            for j in graph[i]:
                if vis[j]==3:
                    return [-1]
                dp[j][2]=False
        else:
            return [-1]
    l.pop(0)
    if count1==0 or count2==0 or count3==0:
        return [-1]
    return l
n,m=map(int,sys.stdin.readline().split())
from collections import defaultdict
graph=defaultdict(list)
for i in range(m):
    a,b=map(int,sys.stdin.readline().split())
    graph[a].append(b)
    graph[b].append(a)
k=fill(graph)
print(*k)


def fill(graph):

    dp=[[True,True,True] for _ in range(n+1)]
    l=[-1 for i in range(n+1)]
    count1,count2,count3=0,0,0
    for i in graph:
        if dp[i][0]:
            #fill
            l[i],count1=1,count1+1
            for j in graph[i]:
                dp[j][0]=False
        elif dp[i][1]:
            #fill
            l[i]=2
            count2+=1
            for j in graph[i]:
                dp[j][1]=False
        elif dp[i][2]:
            #fill
            l[i]=3
            count3+=1
            for j in graph[i]:
                dp[j][2]=False
        else:
            return [-1]

    if count1==0 or count2==0 or count3==0:
        return [-1]
    l.pop(0)
    return l
n,m=map(int,input().split())
from collections import defaultdict
graph=defaultdict(list)
for i in range(m):
    a,b=map(int,input().split())
    graph[a].append(b)
    graph[b].append(a)
k=fill(graph)
print(*k)


import sys
def fill(graph):

    dp=[[True,True,True] for _ in range(n+1)]
    l=[-1 for i in range(n+1)]
    count1,count2,count3=0,0,0
    for i in graph:
        if dp[i][0]:
            #fill
            l[i],count1=1,count1+1
            for j in graph[i]:
                dp[j][0]=False
        elif dp[i][1]:
            #fill
            l[i]=2
            count2+=1
            for j in graph[i]:
                dp[j][1]=False
        elif dp[i][2]:
            #fill
            l[i]=3
            count3+=1
            for j in graph[i]:
                dp[j][2]=False
        else:
            return [-1]

    if count1==0 or count2==0 or count3==0:
        return [-1]
    l.pop(0)
    return l
n,m=map(int,sys.stdin.readline().split())
from collections import defaultdict
graph=defaultdict(list)
for i in range(m):
    a,b=map(int,sys.stdin.readline().split())
    graph[a].append(b)
    graph[b].append(a)
k=fill(graph)
print(*k)


import sys
def fill(graph):

    dp=[[True,True,True] for _ in range(n+1)]
    l=[-1 for i in range(n+1)]
    count1,count2,count3=0,0,0
    for i in graph:
        if dp[i][0]:
            #fill
            l[i],count1=1,count1+1
            for j in graph[i]:
                dp[j][0]=False
        elif dp[i][1]:
            #fill
            l[i]=2
            count2+=1
            for j in graph[i]:
                dp[j][1]=False
        elif dp[i][2]:
            #fill
            l[i]=3
            count3+=1
            for j in graph[i]:
                dp[j][2]=False
        else:
            return [-1]

    if count1==0 or count2==0 or count3==0:
        return [-1]
    return l
n,m=map(int,sys.stdin.readline().split())
from collections import defaultdict
graph=defaultdict(list)
for i in range(m):
    a,b=map(int,sys.stdin.readline().split())
    graph[a].append(b)
    graph[b].append(a)
k=fill(graph)
print(*k)


import sys
def fill(graph,n):

    dp=[[True,True,True] for _ in range(n+1)]
    l=[-1 for i in range(n+1)]
    from collections import defaultdict
    vis=defaultdict(int)
    count1,count2,count3=0,0,0
    for i in graph:
        if dp[i][0]:
            #fill
            l[i],count1=1,count1+1
            vis[i]=1
            for j in graph[i]:
                dp[j][0]=False
        elif dp[i][1]:
            #fill
            l[i]=2
            count2+=1
            vis[i]=2
            for j in graph[i]:
                dp[j][1]=False
        elif dp[i][2]:
            #fill
            l[i]=3
            count3+=1
            vis[i]=3
            for j in graph[i]:
                dp[j][2]=False
        else:
            return [-1]

    if count1==0 or count2==0 or count3==0:
        return [-1]
    if count1+count2+count3!=n:
        return [-1]
    if count1*count2+count2*count3+count1*count3!=m:
        return [-1]
    l.pop(0)
    for i in l:
        if i==-1:
            return [-1]
    return l
n,m=map(int,sys.stdin.readline().split())
from collections import defaultdict
graph=defaultdict(list)
for i in range(m):
    a,b=map(int,sys.stdin.readline().split())
    graph[a].append(b)
    graph[b].append(a)
k=fill(graph,n)
print(*k)


import sys
input = sys.stdin.readline

def r1():
    return int(input())
def rm():
    return map(int, input().split())

n, m = rm()
d = {}
for i in range(m):
    x, y = rm()

    if x not in d:
        d[x] = set()
    d[x].add(y)

    if y not in d:
        d[y] = set()
    d[y].add(x)

bc = d[1]
if len(bc) == 0:
    print(-1)
    exit()

ac = d[next(iter(bc))]
if len(ac) == 0:
    print(-1)
    exit()

c = bc & ac
a = ac - c
b = bc - c

ab = a | b

na = len(a)
nb = len(b)
nc = len(c)
if na + nb + nc != n:
    print(-1)
else:
    for x in a:
        if d[x] != bc:
            print(-1)
            exit()
    for x in b:
        if d[x] != ac:
            print(-1)
            exit()
    for x in c:
        if d[x] != ab:
            print(-1)
            exit()
    r = ['' for i in range(n)]
    for x in a:
        r[x-1] = '1'
    for x in b:
        r[x-1] = '2'
    for x in c:
        r[x-1] = '3'
    print(" ".join(r))


import sys
input = sys.stdin.readline

def r1():
    return int(input())
def rm():
    return map(int, input().split())

n, m = rm()
d = {}
for i in range(m):
    x, y = rm()

    if x not in d:
        d[x] = set()
    d[x].add(y)

    if y not in d:
        d[y] = set()
    d[y].add(x)

bc = d.get(1, [])
if len(bc) == 0:
    print(-1)
    exit()

ac = d.get(next(iter(bc)), [])
if len(ac) == 0:
    print(-1)
    exit()

c = bc & ac
a = ac - c
b = bc - c

ab = a | b

na = len(a)
nb = len(b)
nc = len(c)
if na + nb + nc != n or na == 0 or nb == 0 or nc == 0:
    print(-1)
else:
    for x in a:
        if d.get(x, []) != bc:
            print(-1)
            exit()
    for x in b:
        if d.get(x, []) != ac:
            print(-1)
            exit()
    for x in c:
        if d.get(x, []) != ab:
            print(-1)
            exit()
    r = ['' for i in range(n)]
    for x in a:
        r[x-1] = '1'
    for x in b:
        r[x-1] = '2'
    for x in c:
        r[x-1] = '3'
    print(" ".join(r))


import sys
input = sys.stdin.readline

n,m=map(int,input().split())
E=[set() for i in range(n+1)]

for i in range(m):
    x,y=map(int,input().split())
    E[x].add(y)
    E[y].add(x)

Group=[i for i in range(n+1)]

def find(x):
    while Group[x] != x:
        x=Group[x]
    return x

def Union(x,y):
    if find(x) != find(y):
        Group[find(y)]=Group[find(x)]=min(find(y),find(x))

SCORE=0
for i in range(1,n+1):
    if find(i)==i:
        SCORE+=1
        if SCORE>=6:
            print(-1)
            sys.exit()

        for j in range(i+1,n+1):
            if j in E[i]:
                continue
            else:
                Union(i,j)

FD=[find(i) for i in range(n+1)]
if len(set(FD[1:]))!=3:
    print(-1)
    sys.exit()

for i in range(n+1):
    for j in E[i]:
        if FD[i]==FD[j]:
            print(-1)
            sys.exit()

compression_dict={a: ind for ind, a in enumerate(sorted(set(FD[1:])))}
ANS=[compression_dict[a]+1 for a in FD[1:]]

print(*ANS)


import sys
input = sys.stdin.readline

n,m=map(int,input().split())
E=[set() for i in range(n+1)]
ECOUNT=[0]*(n+1)

for i in range(m):
    x,y=map(int,input().split())
    E[x].add(y)
    E[y].add(x)
    ECOUNT[x]+=1
    ECOUNT[y]+=1

Group=[i for i in range(n+1)]

def find(x):
    while Group[x] != x:
        x=Group[x]
    return x

def Union(x,y):
    if find(x) != find(y):
        Group[find(y)]=Group[find(x)]=min(find(y),find(x))

SCORE=0
for i in range(1,n+1):
    if find(i)==i:
        SCORE+=1
        if SCORE>=4:
            print(-1)
            sys.exit()

        for j in range(i+1,n+1):
            if j in E[i]:
                continue
            else:
                Union(i,j)

FD=[find(i) for i in range(n+1)]
if len(set(FD[1:]))!=3:
    print(-1)
    sys.exit()

for i in range(n+1):
    for j in E[i]:
        if FD[i]==FD[j]:
            print(-1)
            sys.exit()

compression_dict={a: ind for ind, a in enumerate(sorted(set(FD)))}
ANS=[compression_dict[a] for a in FD]

VFD=[0,0,0]
EFD=[0,0,0]
for i in range(1,n+1):
    VFD[ANS[i]-1]+=1
    EFD[ANS[i]-1]+=ECOUNT[i]

for i in range(3):
    VS=0
    for j in range(3):
        if i==j:
            continue
        VS+=VFD[i]*VFD[j]

    if EFD[i]==VS:
        continue
    else:
        print(-1)
        sys.exit()

print(*ANS[1:])


import sys
input = sys.stdin.readline

n,m=map(int,input().split())
E=[set() for i in range(n+1)]

for i in range(m):
    x,y=map(int,input().split())
    E[x].add(y)
    E[y].add(x)

Group=[i for i in range(n+1)]

def find(x):
    while Group[x] != x:
        x=Group[x]
    return x

def Union(x,y):
    if find(x) != find(y):
        Group[find(y)]=Group[find(x)]=min(find(y),find(x))

#SCORE=0
for i in range(1,n+1):
    #if find(i)==i:
    #    SCORE+=1
    #    if SCORE>=4:
    #        print(-1)
    #        sys.exit()

        for j in range(i+1,n+1):
            if j in E[i]:
                continue
            else:
                Union(i,j)

FD=[find(i) for i in range(n+1)]
if len(set(FD[1:]))!=3:
    print(-1)
    sys.exit()

for i in range(n+1):
    for j in E[i]:
        if FD[i]==FD[j]:
            print(-1)
            sys.exit()

compression_dict={a: ind for ind, a in enumerate(sorted(set(FD[1:])))}
ANS=[compression_dict[a]+1 for a in FD[1:]]

print(*ANS)


import sys
input = sys.stdin.readline

n,m=map(int,input().split())
E=[set() for i in range(n+1)]
ECOUNT=[0]*(n+1)

for i in range(m):
    x,y=map(int,input().split())
    E[x].add(y)
    E[y].add(x)
    ECOUNT[x]+=1
    ECOUNT[y]+=1

Group=[i for i in range(n+1)]

def find(x):
    while Group[x] != x:
        x=Group[x]
    return x

def Union(x,y):
    if find(x) != find(y):
        Group[find(y)]=Group[find(x)]=min(find(y),find(x))

SCORE=0
for i in range(1,n+1):
    if find(i)==i:
        SCORE+=1
        if SCORE>=6:
            print(-1)
            sys.exit()

        for j in range(i+1,n+1):
            if j in E[i]:
                continue
            else:
                Union(i,j)

FD=[find(i) for i in range(n+1)]
if len(set(FD[1:]))!=3:
    print(-1)
    sys.exit()

for i in range(n+1):
    for j in E[i]:
        if FD[i]==FD[j]:
            print(-1)
            sys.exit()

compression_dict={a: ind for ind, a in enumerate(sorted(set(FD)))}
ANS=[compression_dict[a] for a in FD]

VFD=[0,0,0]
EFD=[0,0,0]
for i in range(1,n+1):
    VFD[ANS[i]-1]+=1
    EFD[ANS[i]-1]+=ECOUNT[i]

for i in range(3):
    VS=0
    for j in range(3):
        if i==j:
            continue
        VS+=VFD[i]*VFD[j]

    if EFD[i]==VS:
        continue
    else:
        print(-1)
        sys.exit()

print(*ANS[1:])


import sys
input = sys.stdin.readline

n,m=map(int,input().split())
E=[set() for i in range(n+1)]

for i in range(m):
    x,y=map(int,input().split())
    E[x].add(y)
    E[y].add(x)

Group=[i for i in range(n+1)]

def find(x):
    while Group[x] != x:
        x=Group[x]
    return x

def Union(x,y):
    if find(x) != find(y):
        Group[find(y)]=Group[find(x)]=min(find(y),find(x))

SCORE=0
for i in range(1,n+1):
    if find(i)==i:
        SCORE+=1
        if SCORE>=4:
            print(-1)
            sys.exit()

        for j in range(1,n+1):
            if j in E[i]:
                continue
            else:
                Union(i,j)

FD=[find(i) for i in range(n+1)]
if len(set(FD[1:]))!=3:
    print(-1)
    sys.exit()

for i in range(n+1):
    for j in E[i]:
        if FD[i]==FD[j]:
            print(-1)
            sys.exit()

compression_dict={a: ind for ind, a in enumerate(sorted(set(FD[1:])))}
ANS=[compression_dict[a]+1 for a in FD[1:]]

print(*ANS)


import sys
input = sys.stdin.readline

n,m=map(int,input().split())
E=[set() for i in range(n+1)]

for i in range(m):
    x,y=map(int,input().split())
    E[x].add(y)
    E[y].add(x)

Group=[i for i in range(n+1)]

def find(x):
    while Group[x] != x:
        x=Group[x]
    return x

def Union(x,y):
    if find(x) != find(y):
        Group[find(y)]=Group[find(x)]=min(find(y),find(x))

#SCORE=0
for i in range(1,n+1):
    if find(i)==i:
        #SCORE+=1
        #if SCORE>=4:
        #    print(-1)
        #    sys.exit()

        for j in range(1,n+1):
            if j in E[i]:
                continue
            else:
                Union(i,j)

FD=[find(i) for i in range(n+1)]
if len(set(FD))!=4:
    print(-1)
    sys.exit()

for i in range(n+1):
    for j in E[i]:
        if FD[i]==FD[j]:
            print(-1)
            sys.exit()

compression_dict={a: ind for ind, a in enumerate(sorted(set(FD)))}
ANS=[compression_dict[a] for a in FD]

print(*ANS[1:])


import sys
input = sys.stdin.readline

n,m=map(int,input().split())
E=[set() for i in range(n+1)]

for i in range(m):
    x,y=map(int,input().split())
    E[x].add(y)
    E[y].add(x)

Group=[i for i in range(n+1)]

def find(x):
    while Group[x] != x:
        x=Group[x]
    return x

def Union(x,y):
    if find(x) != find(y):
        Group[find(y)]=Group[find(x)]=min(find(y),find(x))

SCORE=0
for i in range(1,n+1):
    if find(i)==i:
        SCORE+=1
        if SCORE>=4:
            print(-1)
            sys.exit()

        for j in range(1,n+1):
            if j in E[i]:
                continue
            else:
                Union(i,j)

FD=[find(i) for i in range(n+1)]
if len(set(FD))!=4:
    print(-1)
    sys.exit()

for i in range(n+1):
    for j in E[i]:
        if FD[i]==FD[j]:
            print(-1)
            sys.exit()

compression_dict={a: ind for ind, a in enumerate(sorted(set(FD)))}
ANS=[compression_dict[a] for a in FD]

print(*ANS[1:])


import sys
input = sys.stdin.readline

n,m=map(int,input().split())
E=[set() for i in range(n+1)]

for i in range(m):
    x,y=map(int,input().split())
    E[x].add(y)
    E[y].add(x)

Group=[i for i in range(n+1)]

def find(x):
    while Group[x] != x:
        x=Group[x]
    return x

def Union(x,y):
    if find(x) != find(y):
        Group[find(y)]=Group[find(x)]=min(find(y),find(x))

SCORE=0
for i in range(1,n+1):
    if find(i)==i:
        SCORE+=1
        if SCORE>=4:
            print(-1)
            sys.exit()

        for j in range(1,n+1):
            if j in E[i]:
                continue
            else:
                Union(i,j)

FD=[find(i) for i in range(n+1)]
if len(set(FD))!=4:
    print(-1)
    sys.exit()

for i in range(n):
    for j in E[i]:
        if FD[i]==FD[j]:
            print(-1)
            sys.exit()

compression_dict={a: ind for ind, a in enumerate(sorted(set(FD)))}
ANS=[compression_dict[a] for a in FD]

print(*ANS[1:])


import sys,math,itertools
from collections import Counter,deque,defaultdict
from bisect import bisect_left,bisect_right
from heapq import heappop,heappush,heapify
mod = 10**9+7
INF = float('inf')
def inp(): return int(sys.stdin.readline())
def inpl(): return list(map(int, sys.stdin.readline().split()))

n,m = inpl()
e = [[] for _ in range(n)]
for _ in range(m):
    a,b = inpl()
    a,b = a-1,b-1
    e[a].append(b)
    e[b].append(a)
se = set()
for i in range(n):
    e[i].sort()
    se.add(tuple(e[i]))
if len(se) != 3:
    print(-1)
else:
    d = {}
    for i,x in enumerate(list(se)):
        d[x] = i+1
    res = [-1] * n
    cnt = [0,0,0]
    for i in range(n):
        tmp = d[tuple(e[i])]
        cnt[tmp-1] += 1
        res[i] = tmp
    for key in list(d):
        ind = d[key]
        if len(key) + cnt[ind-1] != n:
            print(-1)
            break
    else:print(*res)


import sys,math,itertools
from collections import Counter,deque,defaultdict
from bisect import bisect_left,bisect_right
from heapq import heappop,heappush,heapify
mod = 10**9+7
INF = float('inf')
def inp(): return int(sys.stdin.readline())
def inpl(): return list(map(int, sys.stdin.readline().split()))

n,m = inpl()
e = [[] for _ in range(n)]
for _ in range(m):
    a,b = inpl()
    a,b = a-1,b-1
    e[a].append(b)
    e[b].append(a)
se = set()
for i in range(n):
    e[i].sort()
    se.add(tuple(e[i]))
if len(se) != 3:
    print(-1)
else:
    d = {}
    for i,x in enumerate(list(se)):
        d[x] = i+1
    res = [-1] * n
    for i in range(n):
        tmp = d[tuple(e[i])]
        res[i] = tmp
    print(*res)


''' CODED WITH LOVE BY SATYAM KUMAR '''

from sys import stdin, stdout
import heapq
import cProfile, math
from collections import Counter, defaultdict, deque
from bisect import bisect_left, bisect, bisect_right
import itertools
from copy import deepcopy
from fractions import Fraction
import sys, threading
import operator as op
from functools import reduce
import sys

sys.setrecursionlimit(10 ** 6)  # max depth of recursion
threading.stack_size(2 ** 27)  # new thread will get stack of such size
fac_warm_up = False
printHeap = str()
memory_constrained = False
P = 10 ** 9 + 7

class MergeFind:
    def __init__(self, n):
        self.parent = list(range(n))
        self.size = [1] * n
        self.num_sets = n
        self.lista = [[_] for _ in range(n)]

    def find(self, a):
        to_update = []
        while a != self.parent[a]:
            to_update.append(a)
            a = self.parent[a]
        for b in to_update:
            self.parent[b] = a
        return self.parent[a]

    def merge(self, a, b):
        a = self.find(a)
        b = self.find(b)
        if a == b:
            return
        if self.size[a] < self.size[b]:
            a, b = b, a
        self.num_sets -= 1
        self.parent[b] = a
        self.size[a] += self.size[b]
        self.lista[a] += self.lista[b]

    def set_size(self, a):
        return self.size[self.find(a)]

    def __len__(self):
        return self.num_sets

def display(string_to_print):
    stdout.write(str(string_to_print) + "\n")

def prime_factors(n):  # n**0.5 complex
    factors = dict()
    for i in range(2, math.ceil(math.sqrt(n)) + 1):
        while n % i == 0:
            if i in factors:
                factors[i] += 1
            else:
                factors[i] = 1
            n = n // i
    if n > 2:
        factors[n] = 1
    return (factors)

def all_factors(n):
    return set(reduce(list.__add__,
                      ([i, n // i] for i in range(1, int(n ** 0.5) + 1) if n % i == 0)))

def fibonacci_modP(n, MOD):
    if n < 2: return 1
    return (cached_fn(fibonacci_modP, (n + 1) // 2, MOD) * cached_fn(fibonacci_modP, n // 2, MOD) + cached_fn(
        fibonacci_modP, (n - 1) // 2, MOD) * cached_fn(fibonacci_modP, (n - 2) // 2, MOD)) % MOD

def factorial_modP_Wilson(n, p):
    if (p <= n):
        return 0
    res = (p - 1)
    for i in range(n + 1, p):
        res = (res * cached_fn(InverseEuler, i, p)) % p
    return res

def binary(n, digits=20):
    b = bin(n)[2:]
    b = '0' * (digits - len(b)) + b
    return b

def is_prime(n):
    """Returns True if n is prime."""
    if n < 4:
        return True
    if n % 2 == 0:
        return False
    if n % 3 == 0:
        return False
    i = 5
    w = 2
    while i * i <= n:
        if n % i == 0:
            return False
        i += w
        w = 6 - w
    return True

def generate_primes(n):
    prime = [True for i in range(n + 1)]
    p = 2
    while p * p <= n:
        if prime[p]:
            for i in range(p * 2, n + 1, p):
                prime[i] = False
        p += 1
    return prime

factorial_modP = []

def warm_up_fac(MOD):
    global factorial_modP, fac_warm_up
    if fac_warm_up: return
    factorial_modP = [1 for _ in range(fac_warm_up_size + 1)]
    for i in range(2, fac_warm_up_size):
        factorial_modP[i] = (factorial_modP[i - 1] * i) % MOD
    fac_warm_up = True

def InverseEuler(n, MOD):
    return pow(n, MOD - 2, MOD)

def nCr(n, r, MOD):
    global fac_warm_up, factorial_modP
    if not fac_warm_up:
        warm_up_fac(MOD)
        fac_warm_up = True
    return (factorial_modP[n] * (
            (pow(factorial_modP[r], MOD - 2, MOD) * pow(factorial_modP[n - r], MOD - 2, MOD)) % MOD)) % MOD

def get_int():
    return int(stdin.readline().strip())

def get_tuple():
    return map(int, stdin.readline().split())

def get_list():
    return list(map(int, stdin.readline().split()))

memory = dict()

def clear_cache():
    global memory
    memory = dict()

def cached_fn(fn, *args):
    global memory
    if args in memory:
        return memory[args]
    else:
        result = fn(*args)
        memory[args] = result
        return result

def ncr(n, r):
    return math.factorial(n) / (math.factorial(n - r) * math.factorial(r))

def binary_search(i, li):
    fn = lambda x: li[x] - x // i
    x = -1
    b = len(li)
    while b >= 1:
        while b + x < len(li) and fn(b + x) > 0:  # Change this condition 2 to whatever you like
            x += b
        b = b // 2
    return x

# -------------------------------------------------------------- MAIN PROGRAM

TestCases = False
optimise_for_recursion = True  # Can not be used clubbed with TestCases WHen using recursive functions, use Python 3

def main():
    n, m = get_tuple()
    adj = [set() for _ in range(n)]
    full_set = set(range(n))
    for _ in range(m):
        x, y = get_tuple()
        adj[x-1].add(y-1)
        adj[y-1].add(x-1)
    red = full_set.difference(adj[0])
    red.add(0)
    green_blue = adj[0]
    for node in red:
        if adj[node] != green_blue:
            print(-1)
            return
    b = green_blue.pop()
    green = adj[b].difference(red)
    green_blue.add(b)
    blue = green_blue.difference(green)
    for node in green:
        if adj[node] != blue.union(red):
            print(-1)
            return
    res = [0 for _ in range(n)]
    for i, st in enumerate([red, green, blue]):
        for index in st:
            res[index] = i+1
    if min(res)==0:
        print(-1)
    else:
        print(" ".join(map(str, res)))

# --------------------------------------------------------------------- END=

if TestCases:
    for i in range(get_int()):
        main()
else:
    main() if not optimise_for_recursion else threading.Thread(target=main).start()


''' CODED WITH LOVE BY SATYAM KUMAR '''

from sys import stdin, stdout
import heapq
import cProfile, math
from collections import Counter, defaultdict, deque
from bisect import bisect_left, bisect, bisect_right
import itertools
from copy import deepcopy
from fractions import Fraction
import sys, threading
import operator as op
from functools import reduce
import sys

sys.setrecursionlimit(10 ** 6)  # max depth of recursion
threading.stack_size(2 ** 27)  # new thread will get stack of such size
fac_warm_up = False
printHeap = str()
memory_constrained = False
P = 10 ** 9 + 7

class MergeFind:
    def __init__(self, n):
        self.parent = list(range(n))
        self.size = [1] * n
        self.num_sets = n
        self.lista = [[_] for _ in range(n)]

    def find(self, a):
        to_update = []
        while a != self.parent[a]:
            to_update.append(a)
            a = self.parent[a]
        for b in to_update:
            self.parent[b] = a
        return self.parent[a]

    def merge(self, a, b):
        a = self.find(a)
        b = self.find(b)
        if a == b:
            return
        if self.size[a] < self.size[b]:
            a, b = b, a
        self.num_sets -= 1
        self.parent[b] = a
        self.size[a] += self.size[b]
        self.lista[a] += self.lista[b]

    def set_size(self, a):
        return self.size[self.find(a)]

    def __len__(self):
        return self.num_sets

def display(string_to_print):
    stdout.write(str(string_to_print) + "\n")

def prime_factors(n):  # n**0.5 complex
    factors = dict()
    for i in range(2, math.ceil(math.sqrt(n)) + 1):
        while n % i == 0:
            if i in factors:
                factors[i] += 1
            else:
                factors[i] = 1
            n = n // i
    if n > 2:
        factors[n] = 1
    return (factors)

def all_factors(n):
    return set(reduce(list.__add__,
                      ([i, n // i] for i in range(1, int(n ** 0.5) + 1) if n % i == 0)))

def fibonacci_modP(n, MOD):
    if n < 2: return 1
    return (cached_fn(fibonacci_modP, (n + 1) // 2, MOD) * cached_fn(fibonacci_modP, n // 2, MOD) + cached_fn(
        fibonacci_modP, (n - 1) // 2, MOD) * cached_fn(fibonacci_modP, (n - 2) // 2, MOD)) % MOD

def factorial_modP_Wilson(n, p):
    if (p <= n):
        return 0
    res = (p - 1)
    for i in range(n + 1, p):
        res = (res * cached_fn(InverseEuler, i, p)) % p
    return res

def binary(n, digits=20):
    b = bin(n)[2:]
    b = '0' * (digits - len(b)) + b
    return b

def is_prime(n):
    """Returns True if n is prime."""
    if n < 4:
        return True
    if n % 2 == 0:
        return False
    if n % 3 == 0:
        return False
    i = 5
    w = 2
    while i * i <= n:
        if n % i == 0:
            return False
        i += w
        w = 6 - w
    return True

def generate_primes(n):
    prime = [True for i in range(n + 1)]
    p = 2
    while p * p <= n:
        if prime[p]:
            for i in range(p * 2, n + 1, p):
                prime[i] = False
        p += 1
    return prime

factorial_modP = []

def warm_up_fac(MOD):
    global factorial_modP, fac_warm_up
    if fac_warm_up: return
    factorial_modP = [1 for _ in range(fac_warm_up_size + 1)]
    for i in range(2, fac_warm_up_size):
        factorial_modP[i] = (factorial_modP[i - 1] * i) % MOD
    fac_warm_up = True

def InverseEuler(n, MOD):
    return pow(n, MOD - 2, MOD)

def nCr(n, r, MOD):
    global fac_warm_up, factorial_modP
    if not fac_warm_up:
        warm_up_fac(MOD)
        fac_warm_up = True
    return (factorial_modP[n] * (
            (pow(factorial_modP[r], MOD - 2, MOD) * pow(factorial_modP[n - r], MOD - 2, MOD)) % MOD)) % MOD

def get_int():
    return int(stdin.readline().strip())

def get_tuple():
    return map(int, stdin.readline().split())

def get_list():
    return list(map(int, stdin.readline().split()))

memory = dict()

def clear_cache():
    global memory
    memory = dict()

def cached_fn(fn, *args):
    global memory
    if args in memory:
        return memory[args]
    else:
        result = fn(*args)
        memory[args] = result
        return result

def ncr(n, r):
    return math.factorial(n) / (math.factorial(n - r) * math.factorial(r))

def binary_search(i, li):
    fn = lambda x: li[x] - x // i
    x = -1
    b = len(li)
    while b >= 1:
        while b + x < len(li) and fn(b + x) > 0:  # Change this condition 2 to whatever you like
            x += b
        b = b // 2
    return x

# -------------------------------------------------------------- MAIN PROGRAM

TestCases = False
optimise_for_recursion = True  # Can not be used clubbed with TestCases WHen using recursive functions, use Python 3

def main():
    n, m = get_tuple()
    adj = [set() for _ in range(n)]
    full_set = set(range(n))
    for _ in range(m):
        x, y = get_tuple()
        adj[x-1].add(y-1)
        adj[y-1].add(x-1)
    red = full_set.difference(adj[0])
    red.add(0)
    green_blue = adj[0]
    for node in red:
        if adj[node] != green_blue:
            print(-1)
            return
    if len(green_blue)==0:
        print(-1)
        return
    b = green_blue.pop()
    green = adj[b].difference(red)
    green_blue.add(b)
    blue = green_blue.difference(green)
    for node in blue:
        if adj[node] != green.union(red):
            print(-1)
            return
    for node in green:
        if adj[node] != blue.union(red):
            print(-1)
            return
    res = [0 for _ in range(n)]
    for i, st in enumerate([red, green, blue]):
        for index in st:
            res[index] = i+1
    if min(res)==0 or min(map(len, [red, green, blue]))==0:
        print(-1)
    else:
        print(" ".join(map(str, res)))

# --------------------------------------------------------------------- END=

if TestCases:
    for i in range(get_int()):
        main()
else:
    main() if not optimise_for_recursion else threading.Thread(target=main).start()


''' CODED WITH LOVE BY SATYAM KUMAR '''

from sys import stdin, stdout
import heapq
import cProfile, math
from collections import Counter, defaultdict, deque
from bisect import bisect_left, bisect, bisect_right
import itertools
from copy import deepcopy
from fractions import Fraction
import sys, threading
import operator as op
from functools import reduce
import sys

sys.setrecursionlimit(10 ** 6)  # max depth of recursion
threading.stack_size(2 ** 27)  # new thread will get stack of such size
fac_warm_up = False
printHeap = str()
memory_constrained = False
P = 10 ** 9 + 7

class MergeFind:
    def __init__(self, n):
        self.parent = list(range(n))
        self.size = [1] * n
        self.num_sets = n
        self.lista = [[_] for _ in range(n)]

    def find(self, a):
        to_update = []
        while a != self.parent[a]:
            to_update.append(a)
            a = self.parent[a]
        for b in to_update:
            self.parent[b] = a
        return self.parent[a]

    def merge(self, a, b):
        a = self.find(a)
        b = self.find(b)
        if a == b:
            return
        if self.size[a] < self.size[b]:
            a, b = b, a
        self.num_sets -= 1
        self.parent[b] = a
        self.size[a] += self.size[b]
        self.lista[a] += self.lista[b]

    def set_size(self, a):
        return self.size[self.find(a)]

    def __len__(self):
        return self.num_sets

def display(string_to_print):
    stdout.write(str(string_to_print) + "\n")

def prime_factors(n):  # n**0.5 complex
    factors = dict()
    for i in range(2, math.ceil(math.sqrt(n)) + 1):
        while n % i == 0:
            if i in factors:
                factors[i] += 1
            else:
                factors[i] = 1
            n = n // i
    if n > 2:
        factors[n] = 1
    return (factors)

def all_factors(n):
    return set(reduce(list.__add__,
                      ([i, n // i] for i in range(1, int(n ** 0.5) + 1) if n % i == 0)))

def fibonacci_modP(n, MOD):
    if n < 2: return 1
    return (cached_fn(fibonacci_modP, (n + 1) // 2, MOD) * cached_fn(fibonacci_modP, n // 2, MOD) + cached_fn(
        fibonacci_modP, (n - 1) // 2, MOD) * cached_fn(fibonacci_modP, (n - 2) // 2, MOD)) % MOD

def factorial_modP_Wilson(n, p):
    if (p <= n):
        return 0
    res = (p - 1)
    for i in range(n + 1, p):
        res = (res * cached_fn(InverseEuler, i, p)) % p
    return res

def binary(n, digits=20):
    b = bin(n)[2:]
    b = '0' * (digits - len(b)) + b
    return b

def is_prime(n):
    """Returns True if n is prime."""
    if n < 4:
        return True
    if n % 2 == 0:
        return False
    if n % 3 == 0:
        return False
    i = 5
    w = 2
    while i * i <= n:
        if n % i == 0:
            return False
        i += w
        w = 6 - w
    return True

def generate_primes(n):
    prime = [True for i in range(n + 1)]
    p = 2
    while p * p <= n:
        if prime[p]:
            for i in range(p * 2, n + 1, p):
                prime[i] = False
        p += 1
    return prime

factorial_modP = []

def warm_up_fac(MOD):
    global factorial_modP, fac_warm_up
    if fac_warm_up: return
    factorial_modP = [1 for _ in range(fac_warm_up_size + 1)]
    for i in range(2, fac_warm_up_size):
        factorial_modP[i] = (factorial_modP[i - 1] * i) % MOD
    fac_warm_up = True

def InverseEuler(n, MOD):
    return pow(n, MOD - 2, MOD)

def nCr(n, r, MOD):
    global fac_warm_up, factorial_modP
    if not fac_warm_up:
        warm_up_fac(MOD)
        fac_warm_up = True
    return (factorial_modP[n] * (
            (pow(factorial_modP[r], MOD - 2, MOD) * pow(factorial_modP[n - r], MOD - 2, MOD)) % MOD)) % MOD

def get_int():
    return int(stdin.readline().strip())

def get_tuple():
    return map(int, stdin.readline().split())

def get_list():
    return list(map(int, stdin.readline().split()))

memory = dict()

def clear_cache():
    global memory
    memory = dict()

def cached_fn(fn, *args):
    global memory
    if args in memory:
        return memory[args]
    else:
        result = fn(*args)
        memory[args] = result
        return result

def ncr(n, r):
    return math.factorial(n) / (math.factorial(n - r) * math.factorial(r))

def binary_search(i, li):
    fn = lambda x: li[x] - x // i
    x = -1
    b = len(li)
    while b >= 1:
        while b + x < len(li) and fn(b + x) > 0:  # Change this condition 2 to whatever you like
            x += b
        b = b // 2
    return x

# -------------------------------------------------------------- MAIN PROGRAM

TestCases = False
optimise_for_recursion = True  # Can not be used clubbed with TestCases WHen using recursive functions, use Python 3

def main():
    n, m = get_tuple()
    adj = [set() for _ in range(n)]
    full_set = set(range(n))
    for _ in range(m):
        x, y = get_tuple()
        adj[x-1].add(y-1)
        adj[y-1].add(x-1)
    red = full_set.difference(adj[0])
    red.add(0)
    green_blue = adj[0]
    for node in red:
        if adj[node] != green_blue:
            print(-1)
            return
    b = green_blue.pop()
    green = adj[b].difference(red)
    green_blue.add(b)
    blue = green_blue.difference(green)
    for node in green:
        if adj[node] != blue.union(red):
            print(-1)
            return
    res = [0 for _ in range(n)]
    #print(red, green, blue)
    for i, st in enumerate([red, green, blue]):
        for index in st:
            res[index] = i+1
    if min(res)==0:
        print(-1)
    else:
        print(" ".join(map(str, res)))

# --------------------------------------------------------------------- END=

if TestCases:
    for i in range(get_int()):
        main()
else:
    main() if not optimise_for_recursion else threading.Thread(target=main).start()


''' CODED WITH LOVE BY SATYAM KUMAR '''

from sys import stdin, stdout
import heapq
import cProfile, math
from collections import Counter, defaultdict, deque
from bisect import bisect_left, bisect, bisect_right
import itertools
from copy import deepcopy
from fractions import Fraction
import sys, threading
import operator as op
from functools import reduce
import sys

sys.setrecursionlimit(10 ** 6)  # max depth of recursion
threading.stack_size(2 ** 27)  # new thread will get stack of such size
fac_warm_up = False
printHeap = str()
memory_constrained = False
P = 10 ** 9 + 7

class MergeFind:
    def __init__(self, n):
        self.parent = list(range(n))
        self.size = [1] * n
        self.num_sets = n
        self.lista = [[_] for _ in range(n)]

    def find(self, a):
        to_update = []
        while a != self.parent[a]:
            to_update.append(a)
            a = self.parent[a]
        for b in to_update:
            self.parent[b] = a
        return self.parent[a]

    def merge(self, a, b):
        a = self.find(a)
        b = self.find(b)
        if a == b:
            return
        if self.size[a] < self.size[b]:
            a, b = b, a
        self.num_sets -= 1
        self.parent[b] = a
        self.size[a] += self.size[b]
        self.lista[a] += self.lista[b]

    def set_size(self, a):
        return self.size[self.find(a)]

    def __len__(self):
        return self.num_sets

def display(string_to_print):
    stdout.write(str(string_to_print) + "\n")

def prime_factors(n):  # n**0.5 complex
    factors = dict()
    for i in range(2, math.ceil(math.sqrt(n)) + 1):
        while n % i == 0:
            if i in factors:
                factors[i] += 1
            else:
                factors[i] = 1
            n = n // i
    if n > 2:
        factors[n] = 1
    return (factors)

def all_factors(n):
    return set(reduce(list.__add__,
                      ([i, n // i] for i in range(1, int(n ** 0.5) + 1) if n % i == 0)))

def fibonacci_modP(n, MOD):
    if n < 2: return 1
    return (cached_fn(fibonacci_modP, (n + 1) // 2, MOD) * cached_fn(fibonacci_modP, n // 2, MOD) + cached_fn(
        fibonacci_modP, (n - 1) // 2, MOD) * cached_fn(fibonacci_modP, (n - 2) // 2, MOD)) % MOD

def factorial_modP_Wilson(n, p):
    if (p <= n):
        return 0
    res = (p - 1)
    for i in range(n + 1, p):
        res = (res * cached_fn(InverseEuler, i, p)) % p
    return res

def binary(n, digits=20):
    b = bin(n)[2:]
    b = '0' * (digits - len(b)) + b
    return b

def is_prime(n):
    """Returns True if n is prime."""
    if n < 4:
        return True
    if n % 2 == 0:
        return False
    if n % 3 == 0:
        return False
    i = 5
    w = 2
    while i * i <= n:
        if n % i == 0:
            return False
        i += w
        w = 6 - w
    return True

def generate_primes(n):
    prime = [True for i in range(n + 1)]
    p = 2
    while p * p <= n:
        if prime[p]:
            for i in range(p * 2, n + 1, p):
                prime[i] = False
        p += 1
    return prime

factorial_modP = []

def warm_up_fac(MOD):
    global factorial_modP, fac_warm_up
    if fac_warm_up: return
    factorial_modP = [1 for _ in range(fac_warm_up_size + 1)]
    for i in range(2, fac_warm_up_size):
        factorial_modP[i] = (factorial_modP[i - 1] * i) % MOD
    fac_warm_up = True

def InverseEuler(n, MOD):
    return pow(n, MOD - 2, MOD)

def nCr(n, r, MOD):
    global fac_warm_up, factorial_modP
    if not fac_warm_up:
        warm_up_fac(MOD)
        fac_warm_up = True
    return (factorial_modP[n] * (
            (pow(factorial_modP[r], MOD - 2, MOD) * pow(factorial_modP[n - r], MOD - 2, MOD)) % MOD)) % MOD

def get_int():
    return int(stdin.readline().strip())

def get_tuple():
    return map(int, stdin.readline().split())

def get_list():
    return list(map(int, stdin.readline().split()))

memory = dict()

def clear_cache():
    global memory
    memory = dict()

def cached_fn(fn, *args):
    global memory
    if args in memory:
        return memory[args]
    else:
        result = fn(*args)
        memory[args] = result
        return result

def ncr(n, r):
    return math.factorial(n) / (math.factorial(n - r) * math.factorial(r))

def binary_search(i, li):
    fn = lambda x: li[x] - x // i
    x = -1
    b = len(li)
    while b >= 1:
        while b + x < len(li) and fn(b + x) > 0:  # Change this condition 2 to whatever you like
            x += b
        b = b // 2
    return x

# -------------------------------------------------------------- MAIN PROGRAM

TestCases = False
optimise_for_recursion = True  # Can not be used clubbed with TestCases WHen using recursive functions, use Python 3

def main():
    n, m = get_tuple()
    adj = [set() for _ in range(n)]
    full_set = set(range(n))
    for _ in range(m):
        x, y = get_tuple()
        adj[x-1].add(y-1)
        adj[y-1].add(x-1)
    red = full_set.difference(adj[0])
    red.add(0)
    green_blue = adj[0]
    for node in red:
        if adj[node] != green_blue:
            print(-1)
            return
    if len(green_blue)==0:
        print(-1)
        return
    b = green_blue.pop()
    green = adj[b].difference(red)
    green_blue.add(b)
    blue = green_blue.difference(green)
    for node in green:
        if adj[node] != blue.union(red):
            print(-1)
            return
    res = [0 for _ in range(n)]
    for i, st in enumerate([red, green, blue]):
        for index in st:
            res[index] = i+1
    if min(res)==0 or min(map(len, [red, green, blue]))==0:
        print(-1)
    else:
        print(" ".join(map(str, res)))

# --------------------------------------------------------------------- END=

if TestCases:
    for i in range(get_int()):
        main()
else:
    main() if not optimise_for_recursion else threading.Thread(target=main).start()


''' CODED WITH LOVE BY SATYAM KUMAR '''

from sys import stdin, stdout
import heapq
import cProfile, math
from collections import Counter, defaultdict, deque
from bisect import bisect_left, bisect, bisect_right
import itertools
from copy import deepcopy
from fractions import Fraction
import sys, threading
import operator as op
from functools import reduce
import sys

sys.setrecursionlimit(10 ** 6)  # max depth of recursion
threading.stack_size(2 ** 27)  # new thread will get stack of such size
fac_warm_up = False
printHeap = str()
memory_constrained = False
P = 10 ** 9 + 7

class MergeFind:
    def __init__(self, n):
        self.parent = list(range(n))
        self.size = [1] * n
        self.num_sets = n
        self.lista = [[_] for _ in range(n)]

    def find(self, a):
        to_update = []
        while a != self.parent[a]:
            to_update.append(a)
            a = self.parent[a]
        for b in to_update:
            self.parent[b] = a
        return self.parent[a]

    def merge(self, a, b):
        a = self.find(a)
        b = self.find(b)
        if a == b:
            return
        if self.size[a] < self.size[b]:
            a, b = b, a
        self.num_sets -= 1
        self.parent[b] = a
        self.size[a] += self.size[b]
        self.lista[a] += self.lista[b]

    def set_size(self, a):
        return self.size[self.find(a)]

    def __len__(self):
        return self.num_sets

def display(string_to_print):
    stdout.write(str(string_to_print) + "\n")

def prime_factors(n):  # n**0.5 complex
    factors = dict()
    for i in range(2, math.ceil(math.sqrt(n)) + 1):
        while n % i == 0:
            if i in factors:
                factors[i] += 1
            else:
                factors[i] = 1
            n = n // i
    if n > 2:
        factors[n] = 1
    return (factors)

def all_factors(n):
    return set(reduce(list.__add__,
                      ([i, n // i] for i in range(1, int(n ** 0.5) + 1) if n % i == 0)))

def fibonacci_modP(n, MOD):
    if n < 2: return 1
    return (cached_fn(fibonacci_modP, (n + 1) // 2, MOD) * cached_fn(fibonacci_modP, n // 2, MOD) + cached_fn(
        fibonacci_modP, (n - 1) // 2, MOD) * cached_fn(fibonacci_modP, (n - 2) // 2, MOD)) % MOD

def factorial_modP_Wilson(n, p):
    if (p <= n):
        return 0
    res = (p - 1)
    for i in range(n + 1, p):
        res = (res * cached_fn(InverseEuler, i, p)) % p
    return res

def binary(n, digits=20):
    b = bin(n)[2:]
    b = '0' * (digits - len(b)) + b
    return b

def is_prime(n):
    """Returns True if n is prime."""
    if n < 4:
        return True
    if n % 2 == 0:
        return False
    if n % 3 == 0:
        return False
    i = 5
    w = 2
    while i * i <= n:
        if n % i == 0:
            return False
        i += w
        w = 6 - w
    return True

def generate_primes(n):
    prime = [True for i in range(n + 1)]
    p = 2
    while p * p <= n:
        if prime[p]:
            for i in range(p * 2, n + 1, p):
                prime[i] = False
        p += 1
    return prime

factorial_modP = []

def warm_up_fac(MOD):
    global factorial_modP, fac_warm_up
    if fac_warm_up: return
    factorial_modP = [1 for _ in range(fac_warm_up_size + 1)]
    for i in range(2, fac_warm_up_size):
        factorial_modP[i] = (factorial_modP[i - 1] * i) % MOD
    fac_warm_up = True

def InverseEuler(n, MOD):
    return pow(n, MOD - 2, MOD)

def nCr(n, r, MOD):
    global fac_warm_up, factorial_modP
    if not fac_warm_up:
        warm_up_fac(MOD)
        fac_warm_up = True
    return (factorial_modP[n] * (
            (pow(factorial_modP[r], MOD - 2, MOD) * pow(factorial_modP[n - r], MOD - 2, MOD)) % MOD)) % MOD

def get_int():
    return int(stdin.readline().strip())

def get_tuple():
    return map(int, stdin.readline().split())

def get_list():
    return list(map(int, stdin.readline().split()))

memory = dict()

def clear_cache():
    global memory
    memory = dict()

def cached_fn(fn, *args):
    global memory
    if args in memory:
        return memory[args]
    else:
        result = fn(*args)
        memory[args] = result
        return result

def ncr(n, r):
    return math.factorial(n) / (math.factorial(n - r) * math.factorial(r))

def binary_search(i, li):
    fn = lambda x: li[x] - x // i
    x = -1
    b = len(li)
    while b >= 1:
        while b + x < len(li) and fn(b + x) > 0:  # Change this condition 2 to whatever you like
            x += b
        b = b // 2
    return x

# -------------------------------------------------------------- MAIN PROGRAM

TestCases = False
optimise_for_recursion = True  # Can not be used clubbed with TestCases WHen using recursive functions, use Python 3

def main():
    n, m = get_tuple()
    adj = [set() for _ in range(n)]
    full_set = set(range(n))
    for _ in range(m):
        x, y = get_tuple()
        adj[x-1].add(y-1)
        adj[y-1].add(x-1)
    red = full_set.difference(adj[0])
    red.add(0)
    green_blue = adj[0]
    for node in red:
        if adj[node] != green_blue:
            print(-1)
            return
    b = green_blue.pop()
    green = adj[b].difference(red)
    green_blue.add(b)
    blue = green_blue.difference(green)
    for node in green:
        if adj[node] != blue.union(red):
            print(-1)
            return
    res = [0 for _ in range(n)]
    for i, st in enumerate([red, green, blue]):
        for index in st:
            res[index] = i+1
    if min(res)==0 or min(map(len, [red, green, blue]))==0:
        print(-1)
    else:
        print(" ".join(map(str, res)))

# --------------------------------------------------------------------- END=

if TestCases:
    for i in range(get_int()):
        main()
else:
    main() if not optimise_for_recursion else threading.Thread(target=main).start()


import sys
input = sys.stdin.readline
from collections import deque
n, m = [int(item) for item in input().split()]
ab = []
edges = [[] for _ in range(n)]

for i in range(m):
    a, b = [int(item) for item in input().split()]
    a -= 1; b -= 1
    edges[a].append(b)
    edges[b].append(a)
    ab.append((a, b))

groupA = [1] * n
for a, b in ab:
    if a == 0:
        groupA[b] = 0
    elif b == 0:
        groupA[a] = 0
par = None
for i, item in enumerate(groupA):
    if item == 0:
        par = i
        break
if par == None:
    print(-1)
    exit()

groupB = [1] * n
for a, b in ab:
    if a == par:
        groupB[b] = 0
    elif b == par:
        groupB[a] = 0

par = None
for i, (p, q) in enumerate(zip(groupA, groupB)):
    if p == 0 and q == 0:
        par = i
        break
if par == None:
    print(-1)
    exit()

groupC = [1] * n
for a, b in ab:
    if a == par:
        groupC[b] = 0
    elif b == par:
        groupC[a] = 0

# Check edge num
sumA = sum(groupA)
sumB = sum(groupB)
sumC = sum(groupC)
e_abc = [0, n - sumA, n - sumB, n - sumC]
edge_num = sumA * sumB + sumB * sumC + sumC * sumA
if edge_num != m:
    print(-1)
    exit()

# Answer
setA = set()
setB = set()
setC = set()
group = [groupA, groupB, groupC]
ret = []
for i, (ga, gb, gc) in enumerate(zip(groupA, groupB, groupC)):
    total = ga + gb + gc
    if total != 1:
        print(-1)
        exit()
    if ga:
        ret.append(1)
        setA.add(i)
    elif gb:
        ret.append(2)
        setB.add(i)
    else:
        ret.append(3)
        setC.add(i)
s_ABC = [set(), setA, setB, setC]
for i, item in enumerate(ret):
    if e_abc[item] != len(edges[i]):
        print(-1)
        exit()
    for node in edges[i]:
        if node in s_ABC[item]:
            print(-1)
            exit()
print(" ".join([str(item) for item in ret]))


import sys
input = sys.stdin.readline
# from collections import deque
n, m = [int(item) for item in input().split()]
ab = []
# edges = [[] for _ in range(n)]

for i in range(m):
    a, b = [int(item) for item in input().split()]
    a -= 1; b -= 1
    # edges[a].append(b)
    # edges[b].append(a)
    ab.append((a, b))

groupA = [1] * n
for a, b in ab:
    if a == 0:
        groupA[b] = 0
    elif b == 0:
        groupA[a] = 0
par = None
for i, item in enumerate(groupA):
    if item == 0:
        par = i
        break
if par == None:
    print(-1)
    exit()

groupB = [1] * n
for a, b in ab:
    if a == par:
        groupB[b] = 0
    elif b == par:
        groupB[a] = 0

par = None
for i, (p, q) in enumerate(zip(groupA, groupB)):
    if p == 0 and q == 0:
        par = i
        break
if par == None:
    print(-1)
    exit()

groupC = [1] * n
for a, b in ab:
    if a == par:
        groupC[b] = 0
    elif b == par:
        groupC[a] = 0

# Check edge num
sumA = sum(groupA)
sumB = sum(groupB)
sumC = sum(groupC)
edge_num = sumA * sumB + sumB * sumC + sumC * sumA
if edge_num != m:
    print(-1)
    exit()

# Answer
group = [groupA, groupB, groupC]
ret = []
for ga, gb, gc in zip(groupA, groupB, groupC):
    total = ga + gb + gc
    if total != 1:
        print(-1)
        exit()
    if ga:
        ret.append(1)
    elif gb:
        ret.append(2)
    else:
        ret.append(3)
print(" ".join([str(item) for item in ret]))


# from collections import deque
n, m = [int(item) for item in input().split()]
ab = []
# edges = [[] for _ in range(n)]

for i in range(m):
    a, b = [int(item) for item in input().split()]
    a -= 1; b -= 1
    # edges[a].append(b)
    # edges[b].append(a)
    ab.append((a, b))

groupA = [1] * n
for a, b in ab:
    if a == 0:
        groupA[b] = 0
    elif b == 0:
        groupA[a] = 0
par = None
for i, item in enumerate(groupA):
    if item == 0:
        par = i
        break
if par == None:
    print(-1)
    exit()

groupB = [1] * n
for a, b in ab:
    if a == par:
        groupB[b] = 0
    elif b == par:
        groupB[a] = 0

par = None
for i, (p, q) in enumerate(zip(groupA, groupB)):
    if p == 0 and q == 0:
        par = i
        break
if par == None:
    print(-1)
    exit()

groupC = [1] * n
for a, b in ab:
    if a == par:
        groupC[b] = 0
    elif b == par:
        groupC[a] = 0

sumA = sum(groupA)
sumB = sum(groupB)
sumC = sum(groupC)
edge_num = sumA * sumB + sumB * sumC + sumC * sumA
if edge_num != m:
    print(-1)
    exit()
group = [groupA, groupB, groupC]
ret = []
for i in range(n):
    ans = -1
    for j in range(3):
        if group[j][i]:
            if ans != -1:
                print(-1)
                exit()
            ans = j + 1
    ret.append(ans)
print(" ".join([str(item) for item in ret]))


import sys
input = sys.stdin.readline
from collections import deque
n, m = [int(item) for item in input().split()]
ab = []
edges = [[] for _ in range(n)]

for i in range(m):
    a, b = [int(item) for item in input().split()]
    a -= 1; b -= 1
    edges[a].append(b)
    edges[b].append(a)
    ab.append((a, b))

groupA = [1] * n
for a, b in ab:
    if a == 0:
        groupA[b] = 0
    elif b == 0:
        groupA[a] = 0
par = None
for i, item in enumerate(groupA):
    if item == 0:
        par = i
        break
if par == None:
    print(-1)
    exit()

groupB = [1] * n
for a, b in ab:
    if a == par:
        groupB[b] = 0
    elif b == par:
        groupB[a] = 0

par = None
for i, (p, q) in enumerate(zip(groupA, groupB)):
    if p == 0 and q == 0:
        par = i
        break
if par == None:
    print(-1)
    exit()

groupC = [1] * n
for a, b in ab:
    if a == par:
        groupC[b] = 0
    elif b == par:
        groupC[a] = 0

# Check edge num
sumA = sum(groupA)
sumB = sum(groupB)
sumC = sum(groupC)
e_abc = [0, n - sumA, n - sumB, n - sumC]
edge_num = sumA * sumB + sumB * sumC + sumC * sumA
if edge_num != m:
    print(-1)
    exit()

# Answer
group = [groupA, groupB, groupC]
ret = []
for ga, gb, gc in zip(groupA, groupB, groupC):
    total = ga + gb + gc
    if total != 1:
        print(-1)
        exit()
    if ga:
        ret.append(1)
    elif gb:
        ret.append(2)
    else:
        ret.append(3)
for i, item in enumerate(ret):
    if e_abc[item] != len(edges[i]):
        print(-1)
        exit()
print(" ".join([str(item) for item in ret]))


import sys
input = sys.stdin.readline
import collections

def tripartite(n, edges):
    graph = {}
    for i in range(n): graph[i] = set()
    for e1, e2 in edges:
        graph[e1].add(e2)
        graph[e2].add(e1)

    visited = [False] * n
    q = collections.deque()
    q.append(0)
    while q:
        lenq = len(q)
        for _ in range(lenq):
            cur = q.popleft()
            if visited[cur]: continue
            visited[cur] = True
            for nei in graph[cur]: q.append(nei)

    if not all(visited): return [-1] # graph is not single connected

    colors = [0] * n
    q = collections.deque()
    color = 1
    for i in range(n):
        if colors[i] != 0: continue
        q.append(i)
        while q:
            lenq = len(q)
            for _ in range(lenq):
                cur = q.popleft()
                if colors[cur] != 0: continue
                colors[cur] = color
                for nei in graph[cur]: q.append(nei)
            color = 3 - color
    #print(colors)
    for i in range(n):
        if colors[i] != 1: colors[i] = 0
    #print(colors)
    for i in range(n):
        if colors[i] != 0: continue
        q.append(i)
        color = 2
        while q:
            lenq = len(q)
            for _ in range(lenq):
                cur = q.popleft()
                if colors[cur] != 0:
                    if colors[cur] == 1: continue
                    if colors[cur] == color: continue # visited node
                    if colors[cur] != color: return [-1] # visited node with contradiction
                colors[cur] = color
                for nei in graph[cur]: q.append(nei)
            #print(colors)
            color = 5 - color

    if len(set(colors)) < 3: return [-1]

    counter = collections.Counter(colors)
    for i in range(n):
        if len(graph[i]) < n - counter[colors[i]]: return [-1]

    return colors

def main():
    n, m = input().split()
    n, m = int(n), int(m)
    edges = []
    for _ in range(m):
        e1, e2 = input().split()
        edges.append((int(e1) - 1, int(e2) - 1))
    print(' '.join(map(str, tripartite(n, edges))))

if __name__ == '__main__':
    main()


import sys
input = sys.stdin.readline
import collections

def tripartite(n, edges):
    graph = {}
    for i in range(n): graph[i] = set()
    for e1, e2 in edges:
        graph[e1].add(e2)
        graph[e2].add(e1)

    colors = [0] * n
    q = collections.deque()
    color = 1
    for i in range(n):
        if colors[i] != 0: continue
        q.append(i)
        while q:
            lenq = len(q)
            for _ in range(lenq):
                cur = q.popleft()
                if colors[cur] != 0: continue
                colors[cur] = color
                for nei in graph[cur]: q.append(nei)
            color = 3 - color
    if any(c == 0 for c in colors): return [-1] # graph is not single connected
    for i in range(n):
        if colors[i] != 1: colors[i] = 0
    #print(colors)
    for i in range(n):
        if colors[i] != 0: continue
        q.append(i)
        color = 2
        while q:
            lenq = len(q)
            for _ in range(lenq):
                cur = q.popleft()
                if colors[cur] != 0:
                    if colors[cur] == 1: continue
                    if colors[cur] == color: continue # visited node
                    if colors[cur] != color: return [-1] # visited node with contradiction
                colors[cur] = color
                for nei in graph[cur]: q.append(nei)
            #print(colors)
            color = 5 - color

    return colors

def main():
    n, m = input().split()
    n, m = int(n), int(m)
    edges = []
    for _ in range(m):
        e1, e2 = input().split()
        edges.append((int(e1) - 1, int(e2) - 1))
    print(' '.join(map(str, tripartite(n, edges))))

if __name__ == '__main__':
    main()


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define INF 0x7f7f7f7f
#define LL_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
int n;
int a[200005];

void solve() {
    cin >> n;
    for(int i=0;i<n;i++) {
        cin >> a[i];
    }
    int ans = 0;
    for(int i=1;i<n;i++) {
        if(a[i] > a[i+1]) ans++;
    }
    cout << max(1, ans) << endl;
}

int main(void) {
    int t;
    cin >> t;
    while(t--) solve();
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define INF 0x7f7f7f7f
#define LL_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
int n;
int ans;
int a[200005];

void solve() {
    ans = 0;
    cin >> n;
    vector<int> v;
    for(int i=0;i<n;i++) {
        cin >> a[i];
    }
    int cnt = 1;
    int k = 1;
    for(int i=2;i<n;i++) {
        if(a[i] < a[i-1]) {
            v.pb(k);
            cnt++;
            k = 0;
        }
        k++;
    }
    v.pb(k);
    int ans = 0;
    int m = v.size();
    int num = 1;
    for(int i=0;i<m;) {
        if(i >= m) break;
        ans++;
        int tmp = 0;
        for(int j=i;j<min(i+num, m);j++) tmp += v[i];
        i += num;
        num = tmp;
    }
    cout << ans << endl;
}

int main(void) {
    int t;
    cin >> t;
    while(t--) solve();
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define INF 0x7f7f7f7f
#define LL_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
int n;
int ans;
int a[200005];
vector<vector<int>> v;

void dfs(int i, int d) {
    ans = max(ans, d);
    for(int j : v[i]) {
        dfs(j, d+1);
    }
}

void solve() {
    ans = 0;
    cin >> n;
    v.clear();
    v.resize(n+1);
    for(int i=0;i<n;i++) {
        cin >> a[i];
    }
    vector<int> par(n+1);
    for(int i=1;i<n;i++) {
        if(a[i-1] == 1 || a[i] < a[i-1]) {
            v[a[i-1]].pb(a[i]);
            par[a[i]] = a[i-1];
        }
        else {
            int here = par[a[i-1]];
            while(here != 1 && a[i] > here) here = par[here];
            par[a[i]] = here;
            v[here].pb(a[i]);
        }
    }
    dfs(1, 0);
    cout << ans << endl;
}

int main(void) {
    int t;
    cin >> t;
    while(t--) solve();
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define INF 0x7f7f7f7f
#define LL_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
int n;
int ans;
int a[200005];
vector<vector<int>> v;

void dfs(int i, int d) {
    ans = max(ans, d);
    for(int j : v[i]) {
        dfs(j, d+1);
    }
}

void solve() {
    ans = 0;
    cin >> n;
    v.clear();
    v.resize(n+1);
    for(int i=0;i<n;i++) {
        cin >> a[i];
    }
    vector<int> par(n+1);
    for(int i=1;i<n;i++) {
        if(a[i-1] == 1 || a[i] < a[i-1]) {
            v[a[i-1]].pb(a[i]);
            par[a[i]] = a[i-1];
        }
        else {
            int here = par[a[i-1]];
            par[a[i]] = here;
            v[here].pb(a[i]);
        }
    }
    dfs(1, 0);
    cout << ans << endl;
}

int main(void) {
    int t;
    cin >> t;
    while(t--) solve();
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define INF 0x7f7f7f7f
#define LL_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
int n;
int ans;
int a[200005];

void solve() {
    ans = 0;
    cin >> n;
    vector<int> v;
    for(int i=0;i<n;i++) {
        cin >> a[i];
    }
    int cnt = 1;
    int k = 1;
    for(int i=2;i<n;i++) {
        if(a[i] < a[i-1]) {
            v.pb(k);
            cnt++;
            k = 0;
        }
        k++;
    }
    v.pb(k);
    int ans = 0;
    int m = v.size();
    int num = 1;
    for(int i=0;i<m;) {
        if(i >= m) break;
        ans++;
        int tmp = 0;
        for(int j=i;j<min(i+num, m);j++) tmp += v[j];
        i += num;
        num = tmp;
    }
    cout << ans << endl;
}

int main(void) {
    int t;
    cin >> t;
    while(t--) solve();
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define INF 0x7f7f7f7f
#define LL_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
int n;
int a[200005];

void solve() {
    cin >> n;
    for(int i=0;i<n;i++) {
        cin >> a[i];
    }
    int ans = 1;
    for(int i=1;i<n-1;i++) {
        if(a[i] > a[i+1]) ans++;
    }
    cout << ans << endl;
}

int main(void) {
    int t;
    cin >> t;
    while(t--) solve();
    return 0;
}


#include <iostream>
using namespace std;
int main()
{
    long long int t,n,a[200001],i,q,x;
    scanf("%lld",&t);
    for(q=1;q<=t;q++)
    {
     x=1;
     scanf("%lld",&n);
     for(i=1;i<=n;i++)
     {scanf("%lld",&a[i]);}
     i=2;
     while(i<=n)
     {
      while(a[i]<=a[i+1]&&i<=n-1)
      {i++;}
      x++;
      i++;
     }
     printf("%lld\n",x);
    }
    return 0;
}


#include <iostream>
using namespace std;
int main()
{
    long long int t,n,a[200001],i,q,x;
    scanf("%lld",&t);
    for(q=1;q<=t;q++)
    {
     x=1;
     scanf("%lld",&n);
     for(i=1;i<=n;i++)
     {scanf("%lld",&a[i]);}
     i=2;
     while(i<=n)
     {
      while(a[i]<=a[i+1]&&i<=n-1)
      {i++;}
      x++;
      i++;
     }
     printf("%lld\n",x-1);
    }
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
using namespace std;
#define SPEED ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define ll long long
#define pb push_back
#define nn cout<<"\n"
#define MOD 1000000007
#define endl "\n"
#define all(a)      (a).begin(),(a).end()
#define here cout<<"I'm here\n";
#define F first
#define S second
#define pii pair<int,int>
#define pll pair<long long int , long long int>
#define debug(x) cerr<<#x<<'='<<(x)<<endl;

// ------- PBDS ------ //
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<string,null_type,less<string>,rb_tree_tag,tree_order_statistics_node_update> pbds;
/*
    change first and third parameters of tree for any datatype
    s : {1, 5, 6, 17, 88}
    s.order_of_key(6) = 2
    *(s.find_by_order(2)) = 6
*/
// ------- PBDS ------ //

clock_t time_p=clock();
void purvansh11()
{
    time_p=clock()-time_p;
    cerr<<"Time Taken : "<<(float)(time_p)/CLOCKS_PER_SEC<<"\n";
}
/*

    ===============FENWICK TREE=====================
    https://www.hackerearth.com/practice/notes/binary-indexed-tree-or-fenwick-tree/

    ------BIT update (add "delta" at index "x") -------------

    void update(int x, int delta)

    BIT[p] = A[f] + A[g] + ... + A[m]
    which means that pth index of BIT contains
    the sum of some consecutive elements in A
    if we want to update some element of A,
    we need to update all those BIT indexes
    which contains that element of A
    which can be accessed by [x += x&-x]

    start with xth index as BIT[x]
    would always contain A[x] and then update
    x+=x&-x

    for(; x <= n; x += x&-x)
        BIT[x] += delta;

    -----BIT query ("the sum of first "x" elements in array")-----
        int query(int x){
            int sum = 0;
            for(; x > 0; x -= x&-x)
                sum += BIT[x];
            return sum;
        }
        Dry run
        -- query(14)
        -- BIT[14] = A[14] + A[13]
        -- x -= x&-x => x = 14 - 2 => x = 12
        -- BIT[12] = A[12] + ... + A[9]
        -- x -= x&-x => x = 12 - 4 => x = 8
        -- BIT[8] = A[8] + ... + A[1]

*/

/*
    ============BINARY EXPONENTIATION  -- O(log2(b))==============
    for 3^11 : as 11 -> 1011, we mean 3^8 * 3^2 * 3^1
*/
ll power(ll a, ll b) {
    ll ans = 1;
    ll num = a;
    while (b > 0) {
        if (b & 1) ans = ((ans % MOD) * (num % MOD)) % MOD;
        num = ((num % MOD) * (num % MOD)) % MOD;
        b /= 2;
    }
    return ans;
}

/*-------------------------------------------CODE STARTS HERE----------------------------------------------*/

void fun(){
    ll n;
    cin>>n;
    vector<ll> v(n);
    for(auto &itr:v) cin>>itr;
    ll level = 1;
    for(ll i=1;i<n;i++){
        if(v[i] < v[i-1]) level++;
    }
    cout<<level<<endl;
}

int32_t main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    ll t = 1;
    cin>>t;
    while(t--){
        fun();
    }

    purvansh11();
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
using namespace std;
#define SPEED ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define ll long long
#define pb push_back
#define nn cout<<"\n"
#define MOD 1000000007
#define endl "\n"
#define all(a)      (a).begin(),(a).end()
#define here cout<<"I'm here\n";
#define F first
#define S second
#define pii pair<int,int>
#define pll pair<long long int , long long int>
#define debug(x) cerr<<#x<<'='<<(x)<<endl;

// ------- PBDS ------ //
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<string,null_type,less<string>,rb_tree_tag,tree_order_statistics_node_update> pbds;
/*
    change first and third parameters of tree for any datatype
    s : {1, 5, 6, 17, 88}
    s.order_of_key(6) = 2
    *(s.find_by_order(2)) = 6
*/
// ------- PBDS ------ //

clock_t time_p=clock();
void purvansh11()
{
    time_p=clock()-time_p;
    cerr<<"Time Taken : "<<(float)(time_p)/CLOCKS_PER_SEC<<"\n";
}
/*

    ===============FENWICK TREE=====================
    https://www.hackerearth.com/practice/notes/binary-indexed-tree-or-fenwick-tree/

    ------BIT update (add "delta" at index "x") -------------

    void update(int x, int delta)

    BIT[p] = A[f] + A[g] + ... + A[m]
    which means that pth index of BIT contains
    the sum of some consecutive elements in A
    if we want to update some element of A,
    we need to update all those BIT indexes
    which contains that element of A
    which can be accessed by [x += x&-x]

    start with xth index as BIT[x]
    would always contain A[x] and then update
    x+=x&-x

    for(; x <= n; x += x&-x)
        BIT[x] += delta;

    -----BIT query ("the sum of first "x" elements in array")-----
        int query(int x){
            int sum = 0;
            for(; x > 0; x -= x&-x)
                sum += BIT[x];
            return sum;
        }
        Dry run
        -- query(14)
        -- BIT[14] = A[14] + A[13]
        -- x -= x&-x => x = 14 - 2 => x = 12
        -- BIT[12] = A[12] + ... + A[9]
        -- x -= x&-x => x = 12 - 4 => x = 8
        -- BIT[8] = A[8] + ... + A[1]

*/

/*
    ============BINARY EXPONENTIATION  -- O(log2(b))==============
    for 3^11 : as 11 -> 1011, we mean 3^8 * 3^2 * 3^1
*/
ll power(ll a, ll b) {
    ll ans = 1;
    ll num = a;
    while (b > 0) {
        if (b & 1) ans = ((ans % MOD) * (num % MOD)) % MOD;
        num = ((num % MOD) * (num % MOD)) % MOD;
        b /= 2;
    }
    return ans;
}

/*-------------------------------------------CODE STARTS HERE----------------------------------------------*/

void fun(){
    ll n;
    cin>>n;
    vector<ll> v(n);
    for(auto &itr:v) cin>>itr;
    // if(n==2){
    //     cout<<1<<endl;
    //     return;
    // }
    vector<ll> nodes;
    ll cnt = 0;
    nodes.pb(1);

    for(ll i=1;i<n;i++){
        if(v[i] > v[i-1]){
            cnt++;
        }
        else{
            nodes.pb(cnt);
            cnt=1;
        }
    }

    nodes.pb(cnt);
    // for(auto ele:nodes) cout<<ele<<" "; nn;
    ll availible = nodes[1];
    ll height = 1;
    for(ll i=2;i<nodes.size();){
        ll new_av = 0;
        ll j;
        height++;
        for(j=i;j<min((ll)(nodes.size()),i+availible);j++){
            new_av += nodes[j];
        }
        i+=new_av;
        availible = new_av;
    }
    cout<<height<<endl;
}

int32_t main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    ll t = 1;
    cin>>t;
    while(t--){
        fun();
    }

    purvansh11();
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
using namespace std;
#define SPEED ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define ll long long
#define pb push_back
#define nn cout<<"\n"
#define MOD 1000000007
#define endl "\n"
#define all(a)      (a).begin(),(a).end()
#define here cout<<"I'm here\n";
#define F first
#define S second
#define pii pair<int,int>
#define pll pair<long long int , long long int>
#define debug(x) cerr<<#x<<'='<<(x)<<endl;

// ------- PBDS ------ //
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<string,null_type,less<string>,rb_tree_tag,tree_order_statistics_node_update> pbds;
/*
    change first and third parameters of tree for any datatype
    s : {1, 5, 6, 17, 88}
    s.order_of_key(6) = 2
    *(s.find_by_order(2)) = 6
*/
// ------- PBDS ------ //

clock_t time_p=clock();
void purvansh11()
{
    time_p=clock()-time_p;
    cerr<<"Time Taken : "<<(float)(time_p)/CLOCKS_PER_SEC<<"\n";
}
/*

    ===============FENWICK TREE=====================
    https://www.hackerearth.com/practice/notes/binary-indexed-tree-or-fenwick-tree/

    ------BIT update (add "delta" at index "x") -------------

    void update(int x, int delta)

    BIT[p] = A[f] + A[g] + ... + A[m]
    which means that pth index of BIT contains
    the sum of some consecutive elements in A
    if we want to update some element of A,
    we need to update all those BIT indexes
    which contains that element of A
    which can be accessed by [x += x&-x]

    start with xth index as BIT[x]
    would always contain A[x] and then update
    x+=x&-x

    for(; x <= n; x += x&-x)
        BIT[x] += delta;

    -----BIT query ("the sum of first "x" elements in array")-----
        int query(int x){
            int sum = 0;
            for(; x > 0; x -= x&-x)
                sum += BIT[x];
            return sum;
        }
        Dry run
        -- query(14)
        -- BIT[14] = A[14] + A[13]
        -- x -= x&-x => x = 14 - 2 => x = 12
        -- BIT[12] = A[12] + ... + A[9]
        -- x -= x&-x => x = 12 - 4 => x = 8
        -- BIT[8] = A[8] + ... + A[1]

*/

/*
    ============BINARY EXPONENTIATION  -- O(log2(b))==============
    for 3^11 : as 11 -> 1011, we mean 3^8 * 3^2 * 3^1
*/
ll power(ll a, ll b) {
    ll ans = 1;
    ll num = a;
    while (b > 0) {
        if (b & 1) ans = ((ans % MOD) * (num % MOD)) % MOD;
        num = ((num % MOD) * (num % MOD)) % MOD;
        b /= 2;
    }
    return ans;
}

/*-------------------------------------------CODE STARTS HERE----------------------------------------------*/

void fun(){
    ll n;
    cin>>n;
    vector<ll> v(n);
    for(auto &itr:v) cin>>itr;
    // if(n==2){
    //     cout<<1<<endl;
    //     return;
    // }
    vector<ll> nodes;
    ll cnt = 0;
    nodes.pb(1);

    for(ll i=1;i<n;i++){
        if(v[i] > v[i-1]){
            cnt++;
        }
        else{
            nodes.pb(cnt);
            cnt=1;
        }
    }

    nodes.pb(cnt);
    // for(auto ele:nodes) cout<<ele<<" "; nn;
    ll availible = nodes[1];
    ll height = 1;
    for(ll i=2;i<nodes.size();){
        ll new_av = 0;
        ll j;
        height++;
        for(j=i;j<min(i+availible,(ll)(nodes.size()));j++){
            new_av += nodes[j];
        }
        if(i!=n-1 and i+new_av >= nodes.size()){
            height++;
            break;
        }
        i+=new_av;

        availible = new_av;
    }
    if(!left) height++;
    cout<<height<<endl;
}

int32_t main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    ll t = 1;
    cin>>t;
    while(t--){
        fun();
    }

    purvansh11();
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
using namespace std;
#define SPEED ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define ll long long
#define pb push_back
#define nn cout<<"\n"
#define MOD 1000000007
#define endl "\n"
#define all(a)      (a).begin(),(a).end()
#define here cout<<"I'm here\n";
#define F first
#define S second
#define pii pair<int,int>
#define pll pair<long long int , long long int>
#define debug(x) cerr<<#x<<'='<<(x)<<endl;

// ------- PBDS ------ //
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<string,null_type,less<string>,rb_tree_tag,tree_order_statistics_node_update> pbds;
/*
    change first and third parameters of tree for any datatype
    s : {1, 5, 6, 17, 88}
    s.order_of_key(6) = 2
    *(s.find_by_order(2)) = 6
*/
// ------- PBDS ------ //

clock_t time_p=clock();
void purvansh11()
{
    time_p=clock()-time_p;
    cerr<<"Time Taken : "<<(float)(time_p)/CLOCKS_PER_SEC<<"\n";
}
/*

    ===============FENWICK TREE=====================
    https://www.hackerearth.com/practice/notes/binary-indexed-tree-or-fenwick-tree/

    ------BIT update (add "delta" at index "x") -------------

    void update(int x, int delta)

    BIT[p] = A[f] + A[g] + ... + A[m]
    which means that pth index of BIT contains
    the sum of some consecutive elements in A
    if we want to update some element of A,
    we need to update all those BIT indexes
    which contains that element of A
    which can be accessed by [x += x&-x]

    start with xth index as BIT[x]
    would always contain A[x] and then update
    x+=x&-x

    for(; x <= n; x += x&-x)
        BIT[x] += delta;

    -----BIT query ("the sum of first "x" elements in array")-----
        int query(int x){
            int sum = 0;
            for(; x > 0; x -= x&-x)
                sum += BIT[x];
            return sum;
        }
        Dry run
        -- query(14)
        -- BIT[14] = A[14] + A[13]
        -- x -= x&-x => x = 14 - 2 => x = 12
        -- BIT[12] = A[12] + ... + A[9]
        -- x -= x&-x => x = 12 - 4 => x = 8
        -- BIT[8] = A[8] + ... + A[1]

*/

/*
    ============BINARY EXPONENTIATION  -- O(log2(b))==============
    for 3^11 : as 11 -> 1011, we mean 3^8 * 3^2 * 3^1
*/
ll power(ll a, ll b) {
    ll ans = 1;
    ll num = a;
    while (b > 0) {
        if (b & 1) ans = ((ans % MOD) * (num % MOD)) % MOD;
        num = ((num % MOD) * (num % MOD)) % MOD;
        b /= 2;
    }
    return ans;
}

/*-------------------------------------------CODE STARTS HERE----------------------------------------------*/

void fun(){
    ll n;
    cin>>n;
    vector<ll> v(n);
    for(auto &itr:v) cin>>itr;
    // ll level = 1;
    queue<ll> q;
    q.push(1);
    ll level[200001];
    ll ind = 1;
    level[1] = 0;
    ll ans = 0;
    // ll times =0;
    while(!q.empty()){
        // if(times > 100) break;
        auto ele = q.front();
        q.pop();
        for(;ind<n;ind++){
            q.push(v[ind]);
            level[v[ind]] = 1 + level[ele];
            ans = max(ans,level[v[ind]]);
            if(v[ind-1] > v[ind]) {
                // cout<<v[ind]<<" ";
                level[v[ind]] = 2 + level[ele];
                ind++;
                break;
            }
        }
    }
    // nn;
    ans = max(ans,level[v[n-1]]);
    // for(auto ele:v) cout<<level[ele]<<" "; nn;
    cout<<ans<<endl;
}

int32_t main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    ll t = 1;
    cin>>t;
    while(t--){
        fun();
    }

    purvansh11();
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
using namespace std;
#define SPEED ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define ll long long
#define pb push_back
#define nn cout<<"\n"
#define MOD 1000000007
#define endl "\n"
#define all(a)      (a).begin(),(a).end()
#define here cout<<"I'm here\n";
#define F first
#define S second
#define pii pair<int,int>
#define pll pair<long long int , long long int>
#define debug(x) cerr<<#x<<'='<<(x)<<endl;

// ------- PBDS ------ //
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<string,null_type,less<string>,rb_tree_tag,tree_order_statistics_node_update> pbds;
/*
    change first and third parameters of tree for any datatype
    s : {1, 5, 6, 17, 88}
    s.order_of_key(6) = 2
    *(s.find_by_order(2)) = 6
*/
// ------- PBDS ------ //

clock_t time_p=clock();
void purvansh11()
{
    time_p=clock()-time_p;
    cerr<<"Time Taken : "<<(float)(time_p)/CLOCKS_PER_SEC<<"\n";
}
/*

    ===============FENWICK TREE=====================
    https://www.hackerearth.com/practice/notes/binary-indexed-tree-or-fenwick-tree/

    ------BIT update (add "delta" at index "x") -------------

    void update(int x, int delta)

    BIT[p] = A[f] + A[g] + ... + A[m]
    which means that pth index of BIT contains
    the sum of some consecutive elements in A
    if we want to update some element of A,
    we need to update all those BIT indexes
    which contains that element of A
    which can be accessed by [x += x&-x]

    start with xth index as BIT[x]
    would always contain A[x] and then update
    x+=x&-x

    for(; x <= n; x += x&-x)
        BIT[x] += delta;

    -----BIT query ("the sum of first "x" elements in array")-----
        int query(int x){
            int sum = 0;
            for(; x > 0; x -= x&-x)
                sum += BIT[x];
            return sum;
        }
        Dry run
        -- query(14)
        -- BIT[14] = A[14] + A[13]
        -- x -= x&-x => x = 14 - 2 => x = 12
        -- BIT[12] = A[12] + ... + A[9]
        -- x -= x&-x => x = 12 - 4 => x = 8
        -- BIT[8] = A[8] + ... + A[1]

*/

/*
    ============BINARY EXPONENTIATION  -- O(log2(b))==============
    for 3^11 : as 11 -> 1011, we mean 3^8 * 3^2 * 3^1
*/
ll power(ll a, ll b) {
    ll ans = 1;
    ll num = a;
    while (b > 0) {
        if (b & 1) ans = ((ans % MOD) * (num % MOD)) % MOD;
        num = ((num % MOD) * (num % MOD)) % MOD;
        b /= 2;
    }
    return ans;
}

/*-------------------------------------------CODE STARTS HERE----------------------------------------------*/

void fun(){
    ll n;
    cin>>n;
    vector<ll> v(n);
    for(auto &itr:v) cin>>itr;
    // if(n==2){
    //     cout<<1<<endl;
    //     return;
    // }
    vector<ll> nodes;
    ll cnt = 0;
    nodes.pb(1);

    for(ll i=1;i<n;i++){
        if(v[i] > v[i-1]){
            cnt++;
        }
        else{
            nodes.pb(cnt);
            cnt=1;
        }
    }
    nodes.pb(cnt);
    // for(auto ele:nodes) cout<<ele<<" "; nn;
    ll have = 1;
    ll height = 0;
    for(ll i=1;i<nodes.size();){
        height++;
        for(ll j=have ; j>=1 ; j--){
            have--;
            have += nodes[i];
            i++;
            if(i==nodes.size()) break;
        }
    }
    cout<<height<<endl;
}

int32_t main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    ll t = 1;
    cin>>t;
    while(t--){
        fun();
    }

    purvansh11();
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
using namespace std;
#define SPEED ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define ll long long
#define pb push_back
#define nn cout<<"\n"
#define MOD 1000000007
#define endl "\n"
#define all(a)      (a).begin(),(a).end()
#define here cout<<"I'm here\n";
#define F first
#define S second
#define pii pair<int,int>
#define pll pair<long long int , long long int>
#define debug(x) cerr<<#x<<'='<<(x)<<endl;

// ------- PBDS ------ //
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<string,null_type,less<string>,rb_tree_tag,tree_order_statistics_node_update> pbds;
/*
    change first and third parameters of tree for any datatype
    s : {1, 5, 6, 17, 88}
    s.order_of_key(6) = 2
    *(s.find_by_order(2)) = 6
*/
// ------- PBDS ------ //

clock_t time_p=clock();
void purvansh11()
{
    time_p=clock()-time_p;
    cerr<<"Time Taken : "<<(float)(time_p)/CLOCKS_PER_SEC<<"\n";
}
/*

    ===============FENWICK TREE=====================
    https://www.hackerearth.com/practice/notes/binary-indexed-tree-or-fenwick-tree/

    ------BIT update (add "delta" at index "x") -------------

    void update(int x, int delta)

    BIT[p] = A[f] + A[g] + ... + A[m]
    which means that pth index of BIT contains
    the sum of some consecutive elements in A
    if we want to update some element of A,
    we need to update all those BIT indexes
    which contains that element of A
    which can be accessed by [x += x&-x]

    start with xth index as BIT[x]
    would always contain A[x] and then update
    x+=x&-x

    for(; x <= n; x += x&-x)
        BIT[x] += delta;

    -----BIT query ("the sum of first "x" elements in array")-----
        int query(int x){
            int sum = 0;
            for(; x > 0; x -= x&-x)
                sum += BIT[x];
            return sum;
        }
        Dry run
        -- query(14)
        -- BIT[14] = A[14] + A[13]
        -- x -= x&-x => x = 14 - 2 => x = 12
        -- BIT[12] = A[12] + ... + A[9]
        -- x -= x&-x => x = 12 - 4 => x = 8
        -- BIT[8] = A[8] + ... + A[1]

*/

/*
    ============BINARY EXPONENTIATION  -- O(log2(b))==============
    for 3^11 : as 11 -> 1011, we mean 3^8 * 3^2 * 3^1
*/
ll power(ll a, ll b) {
    ll ans = 1;
    ll num = a;
    while (b > 0) {
        if (b & 1) ans = ((ans % MOD) * (num % MOD)) % MOD;
        num = ((num % MOD) * (num % MOD)) % MOD;
        b /= 2;
    }
    return ans;
}

/*-------------------------------------------CODE STARTS HERE----------------------------------------------*/

void fun(){
    ll n;
    cin>>n;
    vector<ll> v(n);
    for(auto &itr:v) cin>>itr;
    // if(n==2){
    //     cout<<1<<endl;
    //     return;
    // }
    vector<ll> nodes;
    ll cnt = 0;
    nodes.pb(1);

    for(ll i=1;i<n;i++){
        if(v[i] > v[i-1]){
            cnt++;
        }
        else{
            nodes.pb(cnt);
            cnt=1;
        }
    }

    nodes.pb(cnt);
    // for(auto ele:nodes) cout<<ele<<" "; nn;
    ll availible = nodes[1];
    ll height = 1;
    for(ll i=2;i<nodes.size();){
        ll new_av = 0;
        ll j;
        height++;
        for(j=i;j<min(i+availible,(ll)(nodes.size()));j++){
            new_av += nodes[j];
        }
        if(i!=nodes.size()-1 and i+new_av >= nodes.size()){
            height++;
            break;
        }
        i+=new_av;

        availible = new_av;
    }
    if(!left) height++;
    cout<<height<<endl;
}

int32_t main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    ll t = 1;
    cin>>t;
    while(t--){
        fun();
    }

    purvansh11();
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
using namespace std;
#define SPEED ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define ll long long
#define pb push_back
#define nn cout<<"\n"
#define MOD 1000000007
#define endl "\n"
#define all(a)      (a).begin(),(a).end()
#define here cout<<"I'm here\n";
#define F first
#define S second
#define pii pair<int,int>
#define pll pair<long long int , long long int>
#define debug(x) cerr<<#x<<'='<<(x)<<endl;

// ------- PBDS ------ //
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<string,null_type,less<string>,rb_tree_tag,tree_order_statistics_node_update> pbds;
/*
    change first and third parameters of tree for any datatype
    s : {1, 5, 6, 17, 88}
    s.order_of_key(6) = 2
    *(s.find_by_order(2)) = 6
*/
// ------- PBDS ------ //

clock_t time_p=clock();
void purvansh11()
{
    time_p=clock()-time_p;
    cerr<<"Time Taken : "<<(float)(time_p)/CLOCKS_PER_SEC<<"\n";
}
/*

    ===============FENWICK TREE=====================
    https://www.hackerearth.com/practice/notes/binary-indexed-tree-or-fenwick-tree/

    ------BIT update (add "delta" at index "x") -------------

    void update(int x, int delta)

    BIT[p] = A[f] + A[g] + ... + A[m]
    which means that pth index of BIT contains
    the sum of some consecutive elements in A
    if we want to update some element of A,
    we need to update all those BIT indexes
    which contains that element of A
    which can be accessed by [x += x&-x]

    start with xth index as BIT[x]
    would always contain A[x] and then update
    x+=x&-x

    for(; x <= n; x += x&-x)
        BIT[x] += delta;

    -----BIT query ("the sum of first "x" elements in array")-----
        int query(int x){
            int sum = 0;
            for(; x > 0; x -= x&-x)
                sum += BIT[x];
            return sum;
        }
        Dry run
        -- query(14)
        -- BIT[14] = A[14] + A[13]
        -- x -= x&-x => x = 14 - 2 => x = 12
        -- BIT[12] = A[12] + ... + A[9]
        -- x -= x&-x => x = 12 - 4 => x = 8
        -- BIT[8] = A[8] + ... + A[1]

*/

/*
    ============BINARY EXPONENTIATION  -- O(log2(b))==============
    for 3^11 : as 11 -> 1011, we mean 3^8 * 3^2 * 3^1
*/
ll power(ll a, ll b) {
    ll ans = 1;
    ll num = a;
    while (b > 0) {
        if (b & 1) ans = ((ans % MOD) * (num % MOD)) % MOD;
        num = ((num % MOD) * (num % MOD)) % MOD;
        b /= 2;
    }
    return ans;
}

/*-------------------------------------------CODE STARTS HERE----------------------------------------------*/

void fun(){
    ll n;
    cin>>n;
    vector<ll> v(n);
    for(auto &itr:v) cin>>itr;
    // if(n==2){
    //     cout<<1<<endl;
    //     return;
    // }
    vector<ll> nodes;
    ll cnt = 0;
    nodes.pb(1);

    for(ll i=1;i<n;i++){
        if(v[i] > v[i-1]){
            cnt++;
        }
        else{
            nodes.pb(cnt);
            cnt=1;
        }
    }

    nodes.pb(cnt);
    // for(auto ele:nodes) cout<<ele<<" "; nn;
    ll availible = nodes[1];
    ll height = 1;
    for(ll i=2;i<nodes.size();){
        ll new_av = 0;
        ll j;
        height++;
        for(j=i;j<min((ll)(nodes.size()),i+availible);j++){
            new_av += nodes[j];
        }
        i+=new_av;
        if(i >= nodes.size()){
            height++;
        }
        availible = new_av;
    }
    cout<<height<<endl;
}

int32_t main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    ll t = 1;
    cin>>t;
    while(t--){
        fun();
    }

    purvansh11();
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vii vector<int>

int main() {
    int t; cin>>t;
    while(t--){
        int n, i, j, h=0, c=1000000; cin>>n; int a[n];
        for(i=0; i<n; i++) cin>>a[i];
        for(i=2; i<n; i++){
            if(a[i]<a[i-1]) h++;
            else {c=min(h, c); h=0;}
            if(i==n-1) c=min(h, c);
        }
        if(c==1000000) c=0;
        cout<<c+1<<endl;
    }
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vii vector<int>

int main() {
    int t; cin>>t;
    while(t--){
        int n, i, j, h=1, c=0; cin>>n; int a[n];
        for(i=0; i<n; i++) cin>>a[i];
        j=n;
        for(i=1; i<n; i++){
                if(a[i]!=a[i-1]+1){
                    c++;
                    int k=i+1;
                    while(a[k]!=a[i-1]+1 && k<n-1){
                        if(a[k]>a[k+1]) h++;
                        k++;
                    }
                j=min(j, h);
                i=k;
            }}
        if(!c) j=0;
        cout<<j+1<<endl;
    }
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vii vector<int>

int main() {
    int t; cin>>t;
    while(t--){
        int n, i, j, h=1, c=0; cin>>n; int a[n];
        for(i=0; i<n; i++) cin>>a[i];
        j=n;
        for(i=1; i<n; i++){
                if(a[i]!=a[i-1]+1){
                    c++;
                    int k=i+1;
                    while(a[k]!=a[i-1]+1 && k<n){
                        if(a[k-1]>a[k]) h++;
                        k++;
                    }
                j=min(j, h);
                i=k;
            }}
        if(!c) j=0;
        cout<<j+1<<endl;
    }
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push
#define pii pair<int,int>
#define vii vector<int>

int main() {
    int t; cin>>t;
    while(t--){
        int n, i, j, h=1, c=0, jj=0; cin>>n; int a[n]; for(i=0; i<n; i++) cin>>a[i];
        queue<int> q; q.pb(a[0]); q.pb(a[1]); map<int, int> ml, mp; ml[a[1]]=1; mp[a[1]]=a[0];
        for(i=2; i<n; i++){
            q.pb(a[i]);
            if(a[i]>a[i-1]){
                mp[a[i]]=mp[a[i-1]];
                ml[a[i]]=ml[mp[a[i]]]+1;
            }
            else{
                q.pop();
                mp[a[i]]=q.front();
                ml[a[i]]=ml[mp[a[i]]]+1;
            }
        }
        cout<<ml[a[n-1]]<<endl;
    }
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push
#define pii pair<int,int>
#define vii vector<int>

int main() {
    int t; cin>>t;
    while(t--){
        int n, i, j, h=1, c=0, jj=0; cin>>n; int a[n];
        queue<int> q; q.pb(a[0]); q.pb(a[1]);map<int,int> ml, mp;ml[a[1]]=1;mp[a[1]]=a[0];ml[a[0]]=0;
        for(i=2; i<n; i++){
            q.pb(a[i]);
            if(a[i]>a[i-1]){
                mp[a[i]]=mp[a[i-1]];
                ml[a[i]]=ml[mp[a[i]]]+1;
            }
            else{
                q.pop();
                mp[a[i]]=q.front();
                ml[a[i]]=ml[mp[a[i]]]+1;
            }
        }
        cout<<ml[a[n-1]]<<endl;
    }
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vii vector<int>

int main() {
    int t; cin>>t;
    while(t--){
        int n, i, j, h=0; cin>>n; int a[n];
        for(i=0; i<n; i++) cin>>a[i];
        j=a[n-1];
        for(i=n-2; i>0; i--){
            if(a[i]>a[i+1]){
                h++;
                j=a[i];
            }
        }
        cout<<h+1<<endl;
    }
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vii vector<int>

int main() {
    int t; cin>>t;
    while(t--){
        int n, i, j, h=0, c=0, jj=0; cin>>n; int a[n];
        for(i=0; i<n; i++) cin>>a[i];
        for(i=2; i<n; i++){
            if(a[i]<a[i-1]) h++;
            else {c=max(h, c); h=0; jj=max(jj, a[i]);}
        }
        if(h && jj>a[n-1]) h--;
        c=max(h, c);
        if(c==1000000) c=0;
        cout<<c+1<<endl;
    }
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vii vector<int>

int main() {
    int t; cin>>t;
    while(t--){
        int n, i, j, h=0, c=0; cin>>n; int a[n];
        for(i=0; i<n; i++) cin>>a[i];
        for(i=2; i<n; i++){
            if(a[i]<a[i-1]) h++;
            else {c=max(h, c); h=0;}
        }
        c=max(h, c);
        if(c==1000000) c=0;
        cout<<c+1<<endl;
    }
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vii vector<int>

int main() {
    int t; cin>>t;
    while(t--){
        int n, i, j=1000000, h=1; cin>>n; int a[n];
        for(i=0; i<n; i++) cin>>a[i];
        j=a[n-1];
        for(i=n-2; i>0; i--){
            if(a[i]<a[i+1]) h++;
            else break;
        }
        cout<<n-h<<endl;
    }
	return 0;
}


#include<bits/stdc++.h>
using namespace std;

int main() {
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        vector<int> arr(n);
        for(int i = 0; i < n; i++)
            cin >> arr[i];

        int lev = 0;
        int nodes_in_prev_lev = 1;
        for(int i = 1; i < n; i++){
            int count = 0;
            int nodes_in_this_lev;
            while(count < nodes_in_prev_lev){
                while(arr[i] < arr[i+1] && (i < n-1)){
                    nodes_in_this_lev++;
                    i++;
                }
                count++;
            }
            nodes_in_prev_lev = nodes_in_this_lev+1;
            lev++;
        }
        cout << lev << endl;
    }

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

int main() {
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        vector<int> arr(n);
        for(int i = 0; i < n; i++)
            cin >> arr[i];

        int lev = 0;
        for(int i = 0; i < n; i++){
            while(arr[i] < arr[i+1] && i < n-1) i++;
            lev++;
        }
        cout << lev << endl;
    }

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

int main() {
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        vector<int> arr(n);
        for(int i = 0; i < n; i++)
            cin >> arr[i];

        int lev = 0;
        int nodes_in_prev_lev = 1;
        for(int i = 1; i < n;){
            int nodes_in_this_lev=0;
            while(nodes_in_prev_lev-- && i<n){
                while(arr[i] < arr[i+1] && (i < n-1)){
                    nodes_in_this_lev++;
                    i++;
                }
                i++;
            }
            nodes_in_prev_lev = nodes_in_this_lev+1;
            lev++;
        }
        cout << lev << endl;
    }

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

int main() {
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        vector<int> arr(n);
        for(int i = 0; i < n; i++)
            cin >> arr[i];

        int lev = 0;
        int nodes_in_prev_lev = 1;
        for(int i = 1; i < n;){
            int nodes_in_this_lev=0;
            while(nodes_in_prev_lev-- && i<n){
                nodes_in_this_lev++;
                while(arr[i] < arr[i+1] && (i < n-1)){
                    nodes_in_this_lev++;
                    i++;
                }
                i++;
            }
            nodes_in_prev_lev = nodes_in_this_lev;
            lev++;
        }
        cout << lev << endl;
    }

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

int main() {
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        vector<int> arr(n);
        for(int i = 0; i < n; i++)
            cin >> arr[i];

        int lev = 0;
        int nodes_in_prev_lev = 1;
        for(int i = 1; i < n;){
            int nodes_in_this_lev=0;
            while(nodes_in_prev_lev--){
                while(arr[i] < arr[i+1] && (i < n-1)){
                    nodes_in_this_lev++;
                    i++;
                }
                i++;
            }
            nodes_in_prev_lev = nodes_in_this_lev+1;
            lev++;
        }
        cout << lev << endl;
    }

    return 0;
}


#include<bits/stdc++.h>
using namespace std;

int main() {
    int t;
    cin >> t;
    while(t--){
        int n;
        cin >> n;
        vector<int> arr(n);
        for(int i = 0; i < n; i++)
            cin >> arr[i];

        int lev = 0;
        for(int i = 1; i < n; i++){
            while(arr[i] < arr[i+1] && (i < n-1)) i++;
            lev++;
        }
        cout << lev << endl;
    }

    return 0;
}