Chef is an advocate for Go Green Initiative. Today he had n trees planted in a row outside his his restaurant. Today, the height of i-th tree is hi feet. The trees grow at a rate of mi feet per day.
Chef knows that trees will look beautiful if they form a zig-zag sequence. The trees will be said to be in Zig-zag sequence if the heights of tree first increases or decreases, then alternates between decreasing/increasing respectively. Formally, the trees will be said to in Zig-zag sequence if one of the following two conditions holds.

- h1 < h2 > h3 < h4 and so on..
- h1 >  h2 < h3 > h4 and so on..

Chef wants to know intervals of time when the heights of the trees will form a zig-zag sequence.

-----Input-----
The first line of the input contains an integer T denoting the number of test cases. The description of T test cases follows.
The first line of each test case contains a single integer n, denoting the number of trees.
The ith of following N lines contains two space separated integers hi and mi, denoting the initial height and the growth speed for ith tree.

-----Output-----
For each test case, output an integer Q - the amount of the periods of consecutive moments of time, when the trees for a zig-zag sequence.
On the following Q lines, output the intervals of time when the trees' heights form a zig-zag sequence. For each intervals, output its' smallest and the largest instants of time. If the range is infinite, output Inf as the right bound.
The test cases are designed in such a way that the total output won't exceed 2 MB.

-----Constraints-----

- 1 ≤ T ≤ 105
- 1 ≤ n ≤ 10
- Subtask 1 (23 points): 0 ≤ hi, mi ≤ 10
- Subtask 2 (77 points): 0 ≤ hi, mi ≤ 109
- 1 ≤ sum of n over a test cases in a single test file ≤ 5 × 105

-----Example-----
Input:3
3
0 1
2 2
0 3
2
2 1
1 2
3
1 1
2 2
3 3

Output:1
0 1
2
0 0
2 Inf
0

-----Explanation-----
Example case 1. In the first case 0 2 0 is already a zig-zag sequence, but on the 2nd second it will become 2 6 6 and will never turn back into zig-zag

Difficulty: interview

Starter code:

Solutions:
def get(l,n):
 l1,l2 = [],[]
 i = 1
 h1,m1 = l[0]
 while (i < len(l)):
  h2,m2 = l[i]
  if (h1>h2):
   if (m1 >= m2):
    l1 += [(0,10**20)]
    l2 += [(-1,-1)]
   else:
    d = (h1-h2)//(m2-m1)
    if (((h1-h2)%(m2-m1)) == 0):
     l1 += [(0,d-1)]
     l2 += [(d+1,10**20)]
    else:
     l1 += [(0,d)]
     l2 += [(d+1,10**20)]
  elif(h1==h2):
   if (m1 > m2):
    l1 += [(1,10**20)]
    l2 += [(-1,-1)]
   elif(m1==m2):
    l1 += [(-1,-1)]
    l2 += [(-1,-1)]
   else:
    l2 += [(1,10**20)]
    l1 += [(-1,-1)]
  else:
   if (m1 <= m2):
    l2 += [(0,10**20)]
    l1 += [(-1,-1)]
   else:
    d = (h2-h1)//(m1-m2)
    if ((h2-h1)%(m1-m2) == 0):
     l2 += [(0,d-1)]
     l1 += [(d+1,10**20)]
    else:
     l2 += [(0,d)]
     l1 += [(d+1,10**20)]
  i += 1
  h1,m1 = h2,m2
 return l1,l2
 
def intersect(k1,k2):
 k1,k2 = min(k1,k2),max(k1,k2)
 c1,c2 = k1
 c3,c4 = k2
 l = [c1,c2,c3,c4]
 l.sort()
 if (l[2]==c2):
  return (c3,min(c2,c4))
 elif (l[3]==c2):
  return k2
 else:
  return (-1,-1)
 
 
 
def union(k1,k2):
 k1,k2 = min(k1,k2),max(k1,k2)
 c1,c2 = k1
 c3,c4 = k2
 l = [c1,c2,c3,c4]
 l.sort()
 if (c2==l[3]):
  return ([c1,c2])
 elif(c2==l[2] or ((c3-c2) == 1)):
  return([c1,c4])
 else:
  return([c1,c2,c3,c4])
 
 
def aa(l1,l2,n):
 c1,c2 = 0,10**20
 i = 0
 n -= 1
 while (i < n):
  if (i%2 == 0):
   k1,k2 = l1[i]
  else:
   k1,k2 = l2[i]
  i += 1
  if ((k1,k2) == (-1,-1)):
   return (-1,-1)
  c1,c2 = intersect((c1,c2),(k1,k2))
  if ((c1,c2) == (-1,-1)):
   return (c1,c2)
 return (c1,c2)
 
 
test = int(input())
while (test != 0):
 test -= 1
 n = int(input())
 l = []
 i = 0
 while (i < n):
  c1,c2 = list(map(int,input().split()))
  l += [(c1,c2)]
  i += 1
 if (n == 1):
  print(1)
  print("0 Inf")
 else:
  l1,l2 = (get(l,n))
  k1,k2 = aa(l1,l2,n)
  if ((k1,k2) == (-1,-1)):
   k1,k2 = aa(l2,l1,n)
   if ((k1,k2) == (-1,-1)):
    print(0)
   else:
    print(1)
    if (k2 == 10**20):
     k2 = "Inf"
    print(str(k1) + " " +str(k2))
  else:
   k3,k4 = aa(l2,l1,n)
   if ((k3,k4) == (-1,-1)):
    print(1)
    if (k2 == 10**20):
     k2 = "Inf"
    print(str(k1) + " " +str(k2))
   else:
    p = union((k1,k2),(k3,k4))
    if (len(p)==2):
     c1,c2 = p
     if (c2==10**20):
      c2 = "Inf"
     print(1)
     print(str(c1) + " " +str(c2))
    else:
     c1,c2,c3,c4 = p
     if (c4 == 10**20):
      c4 = "Inf"
     print(2)
     print(str(c1) + " " +str(c2))
     print(str(c3) + " " +str(c4))


import math
def CHAHG1(xh,m):
 x = [x for x in xh]
 y = [y for y in m]
 
 up = []
 lw = []
 L = None
 R = None
 for i in range(0,len(x)-1):
  if(i%2==0):
   if((y[i]-y[i+1])==0):
    if(x[i] < x[i+1]):
     lw.append(0)
    else:
     return False
   else:
    if(y[i] < y[i+1]):
     l = (float)(x[i+1]-x[i])/(y[i]-y[i+1])
     l = int(math.floor(l))+1
     lw.append(max(0,l))
    else:
     r = (float)(x[i+1]-x[i])/(y[i]-y[i+1])
     r = int(math.ceil(r))-1
     if(r<0):
      return False
     up.append(r)
  else:
   if((y[i]-y[i+1])==0):
    if(x[i] > x[i+1]):
     lw.append(0)
    else:
     return False
   else:
    if(y[i] > y[i+1]):
     l = (float)(x[i+1]-x[i])/(y[i]-y[i+1])
     l = int(math.floor(l))+1
     lw.append(max(0,l))
    else:
     r = (float)(x[i+1]-x[i])/(y[i]-y[i+1])
     r = int(math.ceil(r))-1
     if(r<0):
      return False
     up.append(r)
 if(len(lw)>0):
  L = max(lw)
 else:
  L = 0
 if(len(up) > 0):
  R = min(up)
  if(L>R):
   return False
 else:
  R = "Inf"
 
 return L,R
 
def CHAHG2(xh,m):
 x = [x for x in xh]
 y = [y for y in m]
 up = []
 lw = []
 L = None
 R = None
 for i in range(0,len(x)-1):
  if(i%2==1):
   if((y[i]-y[i+1])==0):
    if(x[i] < x[i+1]):
     lw.append(0)
    else:
     return False
   else:
    if(y[i] < y[i+1]):
     l = (float)(x[i+1]-x[i])/(y[i]-y[i+1])
     l = int(math.floor(l))+1
     lw.append(max(0,l))
    else:
     r = (float)(x[i+1]-x[i])/(y[i]-y[i+1])
     r = int(math.ceil(r))-1
     if(r<0):
      return False
     up.append(r)
  else:
   if((y[i]-y[i+1])==0):
    if(x[i] > x[i+1]):
     lw.append(0)
    else:
     return False
   else:
    if(y[i] > y[i+1]):
     l = (float)(x[i+1]-x[i])/(y[i]-y[i+1])
     l = int(math.floor(l))+1
     lw.append(max(0,l))
    else:
     r = (float)(x[i+1]-x[i])/(y[i]-y[i+1])
     r = int(math.ceil(r))-1
     if(r<0):
      return False
     up.append(r)
 if(len(lw)>0):
  L = max(lw)
 else:
  L = 0
 if(len(up) > 0):
  R = min(up)
  if(L>R):
   return False
 else:
  R = "Inf"
 
 return L,R
 
T = int(input())
while T:
 T = T-1
 N = int(input())
 xh = []
 m = []
 for i in range(N):
  a,b = list(map(int,input().split()))
  xh.append(a)
  m.append(b)
 
 res = []
 p = CHAHG1(xh,m)
 q = CHAHG2(xh,m)
 if(p is not False):
  res.append(p)
 if(q is not False):
  res.append(q)
  
 res.sort()
 sz = len(res)
 
 if(N==1):
  print("1")
  print("0 Inf")
 else:
  if(sz==2 and (res[0][1]+1 == res[1][0])):
   print("1")
   print(res[0][0],res[1][1])
  else:
   print(sz)
   for L,R in res:
    print(L,R)
 


import math
def CHAHG1(xh,m):
 x = [x for x in xh]
 y = [y for y in m]

 up = []
 lw = []
 L = None
 R = None
 for i in range(0,len(x)-1):
  if(i%2==0):
   if((y[i]-y[i+1])==0):
    if(x[i] < x[i+1]):
     lw.append(0)
    else:
     return False
   else:
    if(y[i] < y[i+1]):
     l = (float)(x[i+1]-x[i])/(y[i]-y[i+1])
     l = int(math.floor(l))+1
     lw.append(max(0,l))
    else:
     r = (float)(x[i+1]-x[i])/(y[i]-y[i+1])
     r = int(math.ceil(r))-1
     if(r<0):
      return False
     up.append(r)
  else:
   if((y[i]-y[i+1])==0):
    if(x[i] > x[i+1]):
     lw.append(0)
    else:
     return False
   else:
    if(y[i] > y[i+1]):
     l = (float)(x[i+1]-x[i])/(y[i]-y[i+1])
     l = int(math.floor(l))+1
     lw.append(max(0,l))
    else:
     r = (float)(x[i+1]-x[i])/(y[i]-y[i+1])
     r = int(math.ceil(r))-1
     if(r<0):
      return False
     up.append(r)
 if(len(lw)>0):
  L = max(lw)
 else:
  L = 0
 if(len(up) > 0):
  R = min(up)
  if(L>R):
   return False
 else:
  R = "Inf"

 return L,R

def CHAHG2(xh,m):
 x = [x for x in xh]
 y = [y for y in m]
 up = []
 lw = []
 L = None
 R = None
 for i in range(0,len(x)-1):
  if(i%2==1):
   if((y[i]-y[i+1])==0):
    if(x[i] < x[i+1]):
     lw.append(0)
    else:
     return False
   else:
    if(y[i] < y[i+1]):
     l = (float)(x[i+1]-x[i])/(y[i]-y[i+1])
     l = int(math.floor(l))+1
     lw.append(max(0,l))
    else:
     r = (float)(x[i+1]-x[i])/(y[i]-y[i+1])
     r = int(math.ceil(r))-1
     if(r<0):
      return False
     up.append(r)
  else:
   if((y[i]-y[i+1])==0):
    if(x[i] > x[i+1]):
     lw.append(0)
    else:
     return False
   else:
    if(y[i] > y[i+1]):
     l = (float)(x[i+1]-x[i])/(y[i]-y[i+1])
     l = int(math.floor(l))+1
     lw.append(max(0,l))
    else:
     r = (float)(x[i+1]-x[i])/(y[i]-y[i+1])
     r = int(math.ceil(r))-1
     if(r<0):
      return False
     up.append(r)
 if(len(lw)>0):
  L = max(lw)
 else:
  L = 0
 if(len(up) > 0):
  R = min(up)
  if(L>R):
   return False
 else:
  R = "Inf"

 return L,R

T = int(input())
while T:
 T = T-1
 N = int(input())
 xh = []
 m = []
 for i in range(N):
  a,b = list(map(int,input().split()))
  xh.append(a)
  m.append(b)

 res = []
 p = CHAHG1(xh,m)
 q = CHAHG2(xh,m)
 if(p is not False):
  res.append(p)
 if(q is not False):
  res.append(q)
  
 res.sort()
 sz = len(res)

 if(N==1):
  print("1")
  print("0 Inf")
 else:
  if(sz==2 and res[0][1] >= res[1][0]):
   print("0")
  elif(sz==2 and (res[0][1]+1 == res[1][0])):
   print("1")
   print(res[0][0],res[1][1])
  else:
   print(sz)
   for L,R in res:
    print(L,R)


from random import *

def check(h):
 ans = True
 for i in range(n-1):
  if (i%2 == 0):
   if (h[i] < h[i+1]):
    ans = True
   else:
    ans = False
    break
  else:
   if (h[i] > h[i+1]):
    ans = True
   else:
    ans = False
    break
 if (ans == True):
  return 1
 
 ans = True
 for i in range(n-1):
  if (i%2 == 1):
   if (h[i] < h[i+1]):
    ans = True
   else:
    ans = False
    break
  else:
   if (h[i] > h[i+1]):
    ans = True
   else:
    ans = False
    break
 if (ans == True):
  return 1

 return 0
 
for t in range(int(input())):
 n = int(input())
 h = []
 r = []
 for i in range(n):
  #x, y = randint(1,10), randint(1,10)
  x, y = list(map(int, input().split()))
  h.append(x)
  r.append(y)

 ans = []
 curr = check(h)

 #print h
 #print r
 
 if (curr != 0):
  ans.append(0)
  
 #print 0, ":", "x", h, curr
 for i in range(1, 20):
  for j in range(n):
   h[j] += r[j]
  temp = check(h)
  #print i, ":", curr, h, temp
  if (temp != curr):
   if (temp == 0):
    ans.append(i-1)
   elif (temp == 1 and curr == 0):
    ans.append(i)
   elif (temp == 2 and curr == 0):
    ans.append(i)
   elif (temp == 1 and curr == 2):
    ans.append(i-1)
    ans.append(i)
   elif (temp == 2 and curr == 1):
    ans.append(i-1)
    ans.append(i)
  curr = temp
  if (len(ans)== 3):
   break
 if (len(ans)%2==1):
  ans.append('Inf')
  
 print(len(ans)/2)
 for i in range(0, len(ans), 2):
  print(ans[i], ans[i+1])
 


def is_zigzag(h):
 if (len(h) <= 1):
  return True
 sign = h[1] - h[0]
 if (len(h) == 2 and sign == 0):
  return False
 for i in range(2, len(h)):
  diff = h[i] - h[i - 1]
  if (diff * sign >= 0):
   return False
  sign = diff 
 return True

def is_possible(h, r):
 for i in range(1, len(h)):
  diff = h[i] - h[i - 1]
  if (diff < 0 and r[i] > r[i - 1]):
   return True
  elif (diff > 0 and r[i] < r[i - 1]):
   return True
  elif (diff == 0 and r[i] != r[i - 1]):
   return True
 return False

def add_day(h, r):
 for i in range(len(h)):
  h[i] += r[i]

INF = float('inf')
def find_intervals(heights, rates):
 intervals = []
 f = is_zigzag(heights)
 if (f):
  interval = [0, 'Inf']
  intervals.append(interval)
 day = 0
 while (is_possible(heights, rates)):
  day += 1
  add_day(heights, rates)
  if (is_zigzag(heights)):
   if (f == 1):
    continue
   else:
    intervals.append([day, 'Inf'])
    f = 1
  else:
   if (f == 1):
    intervals[-1][-1] = day - 1
    f = 0

 return intervals


t = int(input())
for i in range(t):
 n = int(input())
 heights = []
 rates = []
 for k in range(n):
  h, m = list(map(int, input().split()))
  heights.append(h)
  rates.append(m)
 intervals = find_intervals(heights, rates)
 print(len(intervals))
 for interval in intervals:
  print('{} {}'.format(interval[0], interval[1]))


from math import ceil
t=int(input())
rangex1=int(0)
rangex2=int(0)
rangey1=int(0)
rangey2=int(0)
while t>0:
 n = int(input())
 h = [int(0)]*11
 m = [int(0)]*11
 alt = int(-1)
 for i in range(0,n):
  a,b = input().split(" ")
  h[i]=int(a)
  m[i]=int(b)

 if n==1:
  print('1')
  print('0 Inf')
 else :
  state = int(1)
  count =int(0)
  index= int(0)
  curtime = int(0)
  while True:
   state = 1
   alt = -1
   for i in range(1,n):
    if i==1:
     if h[i]>h[i-1]: alt=1
     elif h[i]<h[i-1]: alt=0
     else:
      alt=2
      state=0
      break
    elif alt==1:
     if h[i]<h[i-1]: alt=0
     else :
      state=0
      break
    else :
     if h[i]>h[i-1] : alt=1
     else :
      state=0
      break

   if state ==1:
    count +=1
    if index==0: rangex1=int(curtime)
    else : rangex2=int(curtime) 

   mintime=int(0)
   found=int(0)
   tt=int(0)
   for i in range(1,n):
    if h[i-1]<h[i]:
     if m[i-1]>m[i]:
      tt = int(ceil(float(h[i]-h[i-1])/float(m[i-1]-m[i])))
      if found==0:
       mintime=tt
       found=1
      elif tt<mintime:
       mintime=tt
    elif h[i-1]>h[i]:
     if m[i]>m[i-1]:
      tt=int(ceil(float(h[i-1]-h[i])/float(m[i]-m[i-1])))
      if found==0:
       mintime=tt
       found=1
      elif tt<mintime:
       mintime=tt
    else:
     if m[i]!=m[i-1]:
      tt=1
      if found==0:
       mintime=tt
       found=1
      elif tt<mintime:
       mintime=tt

   #print found, mintime
   if found == 0:
    if state==1:
     if index==0:
      rangey1=int(-1)
      index+=1
     else :
      rangey2=int(-1)
      index+=1
    break
   else:
    if state==1:
     if index==0:
      rangey1=int(curtime+mintime-1)
      index+=1
     else:
      rangey2=int(curtime+mintime-1)
      index+=1
    
    curtime+=mintime
    for i in range(0,n):
     h[i]+=m[i]*mintime

  if count>1:
   if rangey1==rangex2-1:
    rangey1=rangey2
    count-=1

  print(count)
  if count>=1:
   if rangey1==-1:
    print('%d Inf' %(rangex1))
   else :
    print(rangex1, rangey1)
  if count>=2 :
   if rangey2==-1:
    print('%d Inf' %(rangex2))
   else :
    print(rangey1, rangey2)
 t-=1





import math
def floorm(a, b) :
 if a % b == 0 : return (a / b) - 1
 else : return a / b
def ceilp(a, b) :
 if a % b == 0 : return (a / b) + 1
 else : return (a + 1) / b + 1
def calc(h, m, f) :
 l, r = 0, 1234567890
 for i in range(len(h) - 1) :
  if i & 1 : u, v = i, i + 1
  else : u, v = i + 1, i
  if f : u, v = v, u
  H, M = h[u] - h[v], m[v] - m[u]#M * t < H
  if M > 0 : r = min(floorm(H, M), r)
  elif M < 0 : l = max(ceilp(H, M), l)
  elif H <= 0 : return -1, -1
  if l > r : return -1, -1
 return l, r
def printerval(l, r) :
 if r == 1234567890 : r = "Inf"
 print(l, r)

def doit() :
 n, h, m, a, t, al, ar = int(input()), [], [], [], [0], [], []
 for i in range(n) :
  h += [0]; m += [0]; a += [0]
 for i in range(n) :
  h[i], m[i] = list(map(int, input().split()))
 if n == 1 :
  print(1)
  print("0 Inf")
  return
 l1, r1 = calc(h, m, 1)
 l2, r2 = calc(h, m, 0)
 if l1 != -1 and l2 != -1 :
  if l1 > l2 : l1, l2, r1, r2 = l2, l1, r2, r1
  if r1 + 1 == l2 :
   print(1)
   printerval(l1, r2)
  else :
   print(2)
   printerval(l1, r1)
   printerval(l2, r2)
 elif l1 != -1 :
  print(1)
  printerval(l1, r1)
 elif l2 != -1 :
  print(1)
  printerval(l2, r2)
 else : print(0)

for cas in range(int(input())) : doit()

import math
def floorm(a, b) :
 if a % b == 0 : return (a / b) - 1
 else : return a / b
def ceilp(a, b) :
 if a % b == 0 : return (a / b) + 1
 else : return (a + 1) / b + 1
def calc(h, m, f) :
 l, r = 0, 1234567890
 for i in range(len(h) - 1) :
  if i & 1 : u, v = i, i + 1
  else : u, v = i + 1, i
  if f : u, v = v, u
  H, M = h[u] - h[v], m[v] - m[u]#M * t < H
  if M > 0 : r = min(floorm(H, M), r)
  elif M < 0 : l = max(ceilp(H, M), l)
  elif H <= 0 : return -1, -1
  if l > r : return -1, -1
 return l, r
def printerval(l, r) :
 if r == 1234567890 : r = "Inf"
 print(l, r)

def doit() :
 n, h, m, a, t, al, ar = int(input()), [], [], [], [0], [], []
 for i in range(n) :
  h += [0]; m += [0]; a += [0]
 for i in range(n) :
  h[i], m[i] = list(map(int, input().split()))
 if n == 1 :
  print(1)
  print("0 Inf")
  return
 l1, r1 = calc(h, m, 1)
 l2, r2 = calc(h, m, 0)
 if l1 != -1 and l2 != -1 :
  if l1 > l2 : l1, l2, r1, r2 = l2, l1, r2, r1
  if r1 + 1 == l2 :
   print(1)
   printerval(l1, r2)
  else :
   print(2)
   printerval(l1, r1)
   printerval(l2, r2)
 elif l1 != -1 :
  print(1)
  printerval(l1, r1)
 elif l2 != -1 :
  print(1)
  printerval(l2, r2)
 else : print(0)

for cas in range(int(input())) : doit()

import math
def calc(h, m, f) :
 l, r = 0, 1234567890
 for i in range(len(h) - 1) :
  if i & 1 : u, v = i, i + 1
  else : u, v = i + 1, i
  if f : u, v = v, u
  H, M = h[u] - h[v], m[v] - m[u]#M * t < H
  if M > 0 : r = min(int(math.floor(1.0 * H / M - 1e-12)), r)
  elif M < 0 : l = max(int(math.ceil(1.0 * H / M + 1e-12)), l)
  elif H <= 0 : return -1, -1
  if l > r : return -1, -1
 return l, r
def printerval(l, r) :
 if r == 1234567890 : r = "Inf"
 print(l, r)

def doit() :
 n, h, m, a, t, al, ar = int(input()), [], [], [], [0], [], []
 for i in range(n) :
  h += [0]; m += [0]; a += [0]
 for i in range(n) :
  h[i], m[i] = list(map(int, input().split()))
 if n == 1 :
  print(1)
  print("0 Inf")
  return
 l1, r1 = calc(h, m, 1)
 l2, r2 = calc(h, m, 0)
 if l1 != -1 and l2 != -1 :
  if l1 > l2 : l1, l2, r1, r2 = l2, l1, r2, r1
  if r1 + 1 == l2 :
   print(1)
   printerval(l1, r2)
  else :
   print(2)
   printerval(l1, r1)
   printerval(l2, r2)
 elif l1 != -1 :
  print(1)
  printerval(l1, r1)
 elif l2 != -1 :
  print(1)
  printerval(l2, r2)
 else : print(0)

for cas in range(int(input())) : doit()

def is_zig_zag(h):
 if len(h) < 2:
  return True
 if h[0] == h[1]:
  return False
 fs = (lambda x, y: x < y, lambda x, y: x > y)
 f = 0 if h[0] < h[1] else 1
 for i in range(1, len(h)-1):
  if not fs[(i+f)%2](h[i], h[i+1]):
   return False
 return True
def t_diff(h, m):
 max_t_diff = None
 for i in range(len(h)-1):
  h_diff, m_diff = h[i]-h[i+1], m[i]-m[i+1]
  if h_diff == m_diff or m_diff == 0:
   continue
  if h_diff == 0:
   return 1
  if (h_diff < 0) != (m_diff < 0):
   local_t_diff = max(1, abs(h_diff/m_diff))
   if max_t_diff is None:
    max_t_diff = local_t_diff
   else:
    max_t_diff = min(max_t_diff, local_t_diff)
 return max_t_diff
for _ in range(eval(input())):
 n = eval(input())
 h, m = list(map(list, list(zip(*[list(map(int, input().split())) for _ in range(n)]))))
 t = 0
 zig_zags = []
 zig_zag_start = None
 while True:
  if is_zig_zag(h):
   if zig_zag_start is None:
    zig_zag_start = t
  elif zig_zag_start is not None:
   zig_zags.append((zig_zag_start, t-1))
   zig_zag_start = None
  td = t_diff(h, m)
  if td is None:
   if zig_zag_start is not None:
    zig_zags.append((zig_zag_start, 'Inf'))
    zig_zag_start = None
   break
  h = list(map(lambda x, y: x+td*y, h, m))
  t += td
 print(len(zig_zags))
 for s, e in zig_zags:
  print(s, e)

def is_zig_zag(h):
 if len(h) < 2:
  return True
 if h[0] == h[1]:
  return False
 fs = (lambda x, y: x < y, lambda x, y: x > y)
 f = 0 if h[0] < h[1] else 1
 for i in range(1, len(h)-1):
  if not fs[(i+f)%2](h[i], h[i+1]):
   return False
 return True
def t_diff(h, m):
 max_t_diff = None
 for i in range(len(h)-1):
  h_diff, m_diff = h[i]-h[i+1], m[i]-m[i+1]
  if h_diff == m_diff or m_diff == 0:
   continue
  if h_diff == 0:
   return 1
  if (h_diff < 0) != (m_diff < 0):
   local_t_diff = max(1, abs(h_diff/m_diff))
   if max_t_diff is None:
    max_t_diff = local_t_diff
   else:
    max_t_diff = min(max_t_diff, local_t_diff)
 return max_t_diff
def no_more_changes(h, m):
 for i in range(len(h)-1):
  h_diff, m_diff = h[i]-h[i+1], m[i]-m[i+1]
  if h_diff == m_diff or m_diff == 0:
   continue
  if h_diff == 0 or (h_diff < 0) != (m_diff < 0):
   return False
 return True
for _ in range(eval(input())):
 n = eval(input())
 h, m = list(map(list, list(zip(*[list(map(int, input().split())) for _ in range(n)]))))
 t = 0
 zig_zags = []
 zig_zag_start = None
 while True:
  if is_zig_zag(h):
   if zig_zag_start is None:
    zig_zag_start = t
  elif zig_zag_start is not None:
   zig_zags.append((zig_zag_start, t-1))
   zig_zag_start = None
  td = t_diff(h, m)
  if td is None:
   if zig_zag_start is not None:
    zig_zags.append((zig_zag_start, 'Inf'))
    zig_zag_start = None
   break
  h = list(map(lambda x, y: x+td*y, h, m))
  t += td
 print(len(zig_zags))
 for s, e in zig_zags:
  print(s, e)

def is_zig_zag(h):
 if len(h) < 2:
  return True
 if h[0] == h[1]:
  return False
 fs = (lambda x, y: x < y, lambda x, y: x > y)
 f = 0 if h[0] < h[1] else 1
 for i in range(1, len(h)-1):
  if not fs[(i+f)%2](h[i], h[i+1]):
   return False
 return True
def no_more_changes(h, m):
 for i in range(len(h)-1):
  h_diff, m_diff = h[i]-h[i+1], m[i]-m[i+1]
  if h_diff == m_diff or m_diff == 0:
   continue
  if h_diff == 0 or (h_diff < 0) != (m_diff < 0):
   return False
 return True
for _ in range(eval(input())):
 n = eval(input())
 h, m = list(map(list, list(zip(*[list(map(int, input().split())) for _ in range(n)]))))
 t = 0
 zig_zags = []
 zig_zag_start = None
 while True:
  if is_zig_zag(h):
   if zig_zag_start is None:
    zig_zag_start = t
  elif zig_zag_start is not None:
   zig_zags.append((zig_zag_start, t-1))
   zig_zag_start = None
  if no_more_changes(h, m):
   if zig_zag_start is not None:
    zig_zags.append((zig_zag_start, 'Inf'))
    zig_zag_start = None
   break
  h = list(map(lambda x, y: x+y, h, m))
  t += 1
 print(len(zig_zags))
 for s, e in zig_zags:
  print(s, e)