Recently, Olya received a magical square with the size of $2^n\times 2^n$.

It seems to her sister that one square is boring. Therefore, she asked Olya to perform exactly $k$ splitting operations.

A Splitting operation is an operation during which Olya takes a square with side $a$ and cuts it into 4 equal squares with side $\dfrac{a}{2}$. If the side of the square is equal to $1$, then it is impossible to apply a splitting operation to it (see examples for better understanding).

Olya is happy to fulfill her sister's request, but she also wants the condition of Olya's happiness to be satisfied after all operations.

The condition of Olya's happiness will be satisfied if the following statement is fulfilled:

Let the length of the side of the lower left square be equal to $a$, then the length of the side of the right upper square should also be equal to $a$. There should also be a path between them that consists only of squares with the side of length $a$. All consecutive squares on a path should have a common side.

Obviously, as long as we have one square, these conditions are met. So Olya is ready to fulfill her sister's request only under the condition that she is satisfied too. Tell her: is it possible to perform exactly $k$ splitting operations in a certain order so that the condition of Olya's happiness is satisfied? If it is possible, tell also the size of the side of squares of which the path from the lower left square to the upper right one will consist.


-----Input-----

The first line contains one integer $t$ ($1 \le t \le 10^3$) — the number of tests.

Each of the following $t$ lines contains two integers $n_i$ and $k_i$ ($1 \le n_i \le 10^9, 1 \le k_i \le 10^{18}$) — the description of the $i$-th test, which means that initially Olya's square has size of $2^{n_i}\times 2^{n_i}$ and Olya's sister asks her to do exactly $k_i$ splitting operations.


-----Output-----

Print $t$ lines, where in the $i$-th line you should output "YES" if it is possible to perform $k_i$ splitting operations in the $i$-th test in such a way that the condition of Olya's happiness is satisfied or print "NO" otherwise. If you printed "YES", then also print the $log_2$ of the length of the side of the squares through space, along which you can build a path from the lower left square to the upper right one.

You can output each letter in any case (lower or upper).

If there are multiple answers, print any.


-----Example-----
Input
3
1 1
2 2
2 12

Output
YES 0
YES 1
NO



-----Note-----

In each of the illustrations, the pictures are shown in order in which Olya applied the operations. The recently-created squares are highlighted with red.

In the first test, Olya can apply splitting operations in the following order: [Image]  Olya applies one operation on the only existing square. 

The condition of Olya's happiness will be met, since there is a path of squares of the same size from the lower left square to the upper right one: [Image] 

The length of the sides of the squares on the path is $1$. $log_2(1) = 0$.

In the second test, Olya can apply splitting operations in the following order: [Image]  Olya applies the first operation on the only existing square. She applies the second one on the right bottom square. 

The condition of Olya's happiness will be met, since there is a path of squares of the same size from the lower left square to the upper right one: [Image] 

The length of the sides of the squares on the path is $2$. $log_2(2) = 1$.

In the third test, it takes $5$ operations for Olya to make the square look like this: [Image] 

Since it requires her to perform $7$ splitting operations, and it is impossible to perform them on squares with side equal to $1$, then Olya cannot do anything more and the answer is "NO".

Source: codeforces | Difficulty: HARD
Tags: Mathematics

Implementation

Constructive algorithms


Solutions:
import collections, atexit, math, sys, bisect
sys.setrecursionlimit(1000000)

def getIntList():
	return list(map(int, input().split()))
try:
	import numpy

	def dprint(*args, **kwargs):
		print(*args, file=sys.stderr)
	dprint('debug mode')
except Exception:

	def dprint(*args, **kwargs):
		pass
inId = 0
outId = 0
if inId > 0:
	dprint('use input', inId)
	sys.stdin = open('input' + str(inId) + '.txt', 'r')
if outId > 0:
	dprint('use output', outId)
	sys.stdout = open('stdout' + str(outId) + '.txt', 'w')
	atexit.register(lambda : sys.stdout.close())
(T,) = getIntList()
MAXN = 10 ** 18 + 10

def getUpper(N):
	z = 1
	r = 0
	for i in range(N):
		r += z
		z *= 4
		if r > MAXN:
			break
	return r
for _ in range(T):
	(N, K) = getIntList()
	tk = K
	z = 1
	for i in range(N):
		tk -= z
		z *= 4
		if tk < 0:
			break
	if tk > 0:
		print('NO')
		continue
	nowcut = 0
	nt = 1
	nowupper = 0
	ok = False
	for i in range(N):
		nt *= 2
		nowcut += nt - 1
		if nowcut > K:
			break
		t = nt * 2 - 3
		tu = t * getUpper(N - 1 - i)
		nowupper += tu
		dprint('bound', nowcut, nowcut + nowupper)
		if nowcut <= K <= nowcut + nowupper:
			ok = True
			break
	if ok:
		print('YES', N - 1 - i)
	else:
		print('NO')


from math import ceil

def solve(n, k):
	if k == 1:
		return n - 1
	if k == 2:
		if n > 1:
			return n - 1
		else:
			return -1
	if k == 3:
		if n > 2:
			return n - 1
		else:
			return -1
	if k in {4, 5}:
		if n > 1:
			return n - 2
		else:
			return -1
	if 2 * n + 1 <= len(bin(3 * k)[2:]):
		return -1
	else:
		return n - ceil((len(bin(3 * k)[2:]) - 1) / 2)
for i in range(int(input())):
	(n, k) = map(int, input().split())
	a = solve(n, k)
	if a == -1:
		print('NO')
	else:
		print('YES', a)


t = int(input())
for ca in range(t):
	asd = input().split()
	n = int(asd[0])
	k = int(asd[1])
	if n >= 40:
		print('YES ' + str(n - 1))
	else:
		ans = -1
		for m in range(1, n + 1):
			asd = (4 ** m - 1) // 3
			asd2 = (2 ** m - 1) ** 2
			asd2 *= (4 ** (n - m) - 1) // 3
			asd += asd2
			if asd >= k and m * m <= k:
				ans = n - m
				break
		if ans == -1:
			print('NO')
		else:
			print('YES ' + str(ans))


import math
f = [0] * 100
for i in range(100):
	f[i] = (4 ** i - 1) // 3

def solve(N, K):
	if N < 100 and f[N] < K:
		print('NO')
		return
	for i in range(99):
		if f[i] <= K < f[i + 1]:
			x = K - f[i]
			a = N - i
			if x == 0:
				print('YES {}'.format(a))
				return
			edge = 2 ** (i + 1) - 1
			others = (2 ** i - 1) ** 2
			if edge == x:
				print('YES {}'.format(a - 1))
				return
			ans = a
			if edge < x:
				x -= edge
				ans = a - 1
			for j in range(a + 1):
				if others * f[j] >= x:
					print('YES {}'.format(ans))
					return
			print('NO')
			return
	print('NO')
T = int(input())
for ti in range(T):
	(N, K) = map(int, input().split())
	solve(N, K)


t = int(input())
while t > 0:
	(n, k) = input().split()
	(n, k) = (int(n), int(k))
	if n >= 32:
		print('YES', n - 1)
		t -= 1
		continue
	possibleSize = -1
	sz = 1
	while sz <= n:
		req_cuts = 2 ** (sz + 1) - 2 - sz
		tot_cuts = (4 ** sz - 1) // 3 + (2 ** sz - 1) ** 2 * ((4 ** (n - sz) - 1) // 3)
		if req_cuts > k:
			break
		if tot_cuts >= k:
			possibleSize = sz
			break
		sz += 1
	if possibleSize != -1:
		print('YES', n - possibleSize)
	else:
		print('NO')
	t -= 1


def mypw2(deg):
	if deg >= 1500:
		return 2 ** 150
	return 2 ** deg

def sol():
	(n, k) = map(int, input().split())
	if k == 0:
		print('YES', n)
		return
	for side in range(1, n + 1):
		MIN = mypw2(side + 1) - side - 2
		MAX = mypw2(2 * n) - mypw2(2 * n - side + 1) + mypw2(side + 1) + mypw2(2 * n - 2 * side) - 2
		MAX //= 3
		if MIN <= k <= MAX:
			print('YES', n - side)
			return
	print('NO')

def main():
	t = int(input())
	for i in range(t):
		sol()
main()


def A(n):
	return (4 ** n - 1) // 3
L = 31
T = int(input())
for _ in range(T):
	(n, k) = [int(_) for _ in input().split()]
	if n > L:
		print('YES', n - 1)
		continue
	if k > A(n):
		print('NO')
		continue
	E = 1
	M = 0
	R = 0
	while n >= 0:
		M += E
		I = 2 * E - 1
		E = 2 * E + 1
		n -= 1
		R += I * A(n)
		if M <= k and k <= M + R:
			break
	if n >= 0:
		print('YES', n)
	else:
		print('NO')


def tonum(count):
	return (count - 1) // 3

def check(n, k, logdivl):
	divl = 2 ** logdivl
	min_k = 2 ** (logdivl + 1) - 2 - logdivl
	max_k = tonum(divl * divl + (divl * divl - (2 * divl - 1)) * ((2 ** (n - logdivl)) ** 2 - 1))
	return min_k <= k <= max_k

def main(n, k):
	if k == 1:
		return n - 1
	if n > 100:
		return n - 1
	if ((2 ** (n - 1)) ** 2 - 1) // 3 + 1 >= k:
		return n - 1
	for logdivl in range(1, n + 1):
		if check(n, k, logdivl):
			return n - logdivl
	return None
t = int(input())
for i in range(t):
	(n, k) = list(map(int, input().split()))
	ans = main(n, k)
	if ans is not None:
		print('YES {}'.format(ans))
	else:
		print('NO')


for _ in range(int(input())):
	(n, k) = [int(x) for x in input().split()]
	if n == 2 and k == 3 or (n <= 30 and k > (4 ** n - 1) // 3):
		print('NO')
	else:
		cn = n - 1
		ck = k - 1
		l = 1
		while cn * ck != 0 and ck >= 4 * l - 1:
			ck -= 4 * l - 1
			cn -= 1
			l *= 2
		print('YES', cn)


import sys
t = int(input())
for _ in range(0, t):
	ri = input().split(' ')
	n = int(ri[0])
	k = int(ri[1])
	if k == 0:
		print('YES ' + str(n))
		continue
	is_ok = False
	for i in range(1, min(64, n + 1)):
		l = 2 ** (i + 1) - i - 2
		r = 0
		if n > 100:
			r = k
		else:
			r = (4 ** n - 1) // 3 - (2 ** (i + 1) - 1) * (4 ** (n - i) - 1) // 3
		if l <= k and k <= r:
			print('YES ' + str(n - i))
			is_ok = True
			break
	if not is_ok:
		print('NO')


from sys import stdin, stdout
readline = stdin.readline
write = stdout.write
squareMoves = []

def precompute():
	top = 10 ** 18
	prev = 0
	while prev <= 30 * top:
		squareMoves.append(prev)
		prev = 1 + 4 * prev

def getAns(k, n):
	low = 0
	high = 0
	a = 1
	b = 1
	i = 1
	while i <= n:
		low += a
		high += a + b * squareMoves[n - i]
		if high >= k:
			if low > k:
				return -1
			return i
		a = 2 * a + 1
		b = 2 * a - 1
		i += 1
	return -1
precompute()
t = int(readline().strip())
for i in range(t):
	[n, k] = list(map(int, readline().strip().split(' ')))
	tmpN = min(n, len(squareMoves))
	ans = getAns(k, tmpN)
	if ans == -1:
		write('NO\n')
	else:
		write('YES ' + str(n - ans) + '\n')


import math
t = int(input())

def eval_(n, k):
	level = 0.5 * math.log2(3 * k + 1)
	if n > 30:
		cond = level - n > 0
	else:
		cond = 3 * k + 1 > 4 ** n
	if cond:
		return 'NO'
	elif n == 2 and k == 3:
		return 'NO'
	else:
		level = math.floor(level)
		if n > 5:
			temp = 1 + 0.5 * math.log2(3 * (k - 1) + 1)
			if n > temp:
				return 'YES ' + str(n - 1)
			else:
				return 'YES  0'
		else:
			delta = 2 ** (n - level) * (2 ** level - 1) * (4 ** (n - level) - 1) // 3
			start = (4 ** level - 1) // 3
			if k <= start + delta:
				return 'YES ' + str(n - level)
			else:
				return 'YES ' + str(n - level - 1)
for i in range(t):
	(n, k) = [int(i) for i in input().split()]
	print(eval_(n, k))


def solve(n, k):
	if n >= 60:
		return 'YES ' + str(n - 1)
	mxxx = (4 ** n - 1) // 3
	if k > mxxx:
		return 'NO'
	(mn, mx) = (0, 0)
	for i in range(n):
		mn += 2 ** (i + 1) - 1
		mx += 4 ** i
		if mn <= k and mx >= k:
			return 'YES ' + str(n - i - 1)
	if k >= 22 and k <= 25:
		return 'YES ' + str(n - 3)
	if k == 2:
		if n >= 2:
			return 'YES ' + str(n - 1)
		return 'NO'
	if k == 3:
		if n <= 2:
			return 'NO'
		return 'YES ' + str(n - 1)
	if k >= 6 and k <= 10:
		return 'YES ' + str(n - 2)
t = int(input())
for i in range(t):
	(n, k) = map(int, input().split())
	print(solve(n, k))


test = int(input())
while test:
	test = test - 1
	(n, k) = input().split()
	n = int(n)
	k = int(k)
	if n == 2 and k == 3:
		print('NO')
		continue
	if n >= 32:
		print('YES', n - 1)
		continue
	val = []
	val.append(0)
	for i in range(1, n + 1):
		val.append(4 * val[i - 1] + 1)
	if val[n] < k:
		print('NO')
		continue
	s = 0
	t = 2
	rem = 0
	flag = 0
	while s + t - 1 <= k and n > 0:
		s = s + t - 1
		t *= 2
		n = n - 1
	print('YES', n)


t = int(input())
for i in range(t):
	(n, k) = map(int, input().split())
	if n > 32:
		print('YES', n - 1)
	else:
		max_splits = (4 ** n - 1) // 3
		if k > max_splits or (n, k) == (2, 3):
			print('NO')
		else:
			done = False
			for i in range(n):
				if k < 2 ** (i + 2) - i - 3:
					print('YES', n - i)
					done = True
					break
			if not done:
				print('YES', 0)


t = int(input())

def sol(n, k):
	p = 1
	acc = 0
	while n > 0 and k >= p:
		k -= p
		n -= 1
		if n >= 40:
			return n
		acc += (2 * p - 1) * (4 ** n - 1) // 3
		if k <= acc:
			return n
		p = 2 * p + 1
	return -1
for _ in range(t):
	(n, k) = (int(v) for v in input().split())
	ans = sol(n, k)
	if ans == -1:
		print('NO')
	else:
		print('YES', ans)


for _ in range(int(input())):
	(n, k) = map(int, input().split())
	if n > 31:
		print('YES', n - 1)
		continue
	elif k > (4 ** n - 1) // 3:
		print('NO')
		continue
	l = (4 ** n - 1) // 3
	i = 1
	j = 0
	k1 = k
	while i <= n:
		k -= 2 ** i - 1
		j = i
		if k < 0:
			j = j - 1
			k += 2 ** i - 1
			break
		i += 1
	k2 = k1 - k
	k3 = (2 ** (j + 1) - 1) * ((4 ** (n - j) - 1) // 3)
	if l - k2 - k3 >= k:
		print('YES', n - i + 1)
	else:
		print('NO')


t = int(input())
for iter in range(t):
	(n, k) = map(int, input().split())
	if n >= 50:
		if k == 0:
			print('YES ' + str(n))
		else:
			print('YES ' + str(n - 1))
	else:
		a = [0] * (n + 1)
		b = [0] * (n + 1)
		c = [0] * (n + 1)
		a[0] = 0
		b[n] = 1
		c[n] = 0
		for i in range(1, n + 1):
			a[i] = 4 * a[i - 1] + 1
		for i in range(n - 1, -1, -1):
			b[i] = b[i + 1] * 2 + 1
		for i in range(n - 1, -1, -1):
			c[i] = c[i + 1] + b[i + 1]
		res = -1
		for d in range(n + 1):
			if c[d] <= k and k <= a[n] - a[d] * b[d]:
				res = d
		if res == -1:
			print('NO')
		else:
			print('YES ' + str(res))


MAX = 1000
f = [0]
for i in range(1, MAX):
	f.append(f[i - 1] + (1 << 2 * i - 2))
g = [0]
for i in range(1, MAX):
	g.append(g[i - 1] + (1 << i) - 1)
t = int(input())
for _ in range(t):
	(n, k) = map(int, input().split(' '))
	ans = False
	for i in range(1, n + 1):
		if k >= g[i]:
			if n >= MAX:
				print('YES %d' % (n - i))
				ans = True
			elif k <= f[n] - ((1 << i + 1) - 1) * f[n - i]:
				print('YES %d' % (n - i))
				ans = True
		if ans == True:
			break
	if ans == False:
		print('NO')


f = [0 for _ in range(40)]
for i in range(1, 32):
	f[i] = 1 + 4 * f[i - 1]
t = int(input())
for _ in range(t):
	(n, k) = map(int, input().split())
	if n >= 32:
		print('YES %d' % (n - 1))
		continue
	if f[n] < k:
		print('NO')
		continue
	k -= 1
	extra = 1
	way = 3
	size = n - 1
	done = False
	total = f[size]
	ans = True
	while k > total and size > 0:
		if k < way:
			ans = False
			break
		k -= way
		size -= 1
		extra = way * 2 - 1
		way = way * 2 + 1
		total += extra * f[size]
	if ans:
		print('YES %d' % size)
	else:
		print('NO')


from sys import stdin, stdout
import cProfile, math
from collections import Counter
from bisect import bisect_left, bisect, bisect_right
import itertools
from copy import deepcopy
from fractions import Fraction
import sys, threading
sys.setrecursionlimit(10 ** 6)
threading.stack_size(2 ** 27)
printHeap = str()
memory_constrained = False
P = 10 ** 9 + 7
import sys
sys.setrecursionlimit(10000000)

class Operation:

	def __init__(self, name, function, function_on_equal, neutral_value=0):
		self.name = name
		self.f = function
		self.f_on_equal = function_on_equal

def add_multiple(x, count):
	return x * count

def min_multiple(x, count):
	return x

def max_multiple(x, count):
	return x
sum_operation = Operation('sum', sum, add_multiple, 0)
min_operation = Operation('min', min, min_multiple, 1000000000.0)
max_operation = Operation('max', max, max_multiple, -1000000000.0)

class SegmentTree:

	def __init__(self, array, operations=[sum_operation, min_operation, max_operation]):
		self.array = array
		if type(operations) != list:
			raise TypeError('operations must be a list')
		self.operations = {}
		for op in operations:
			self.operations[op.name] = op
		self.root = SegmentTreeNode(0, len(array) - 1, self)

	def query(self, start, end, operation_name):
		if self.operations.get(operation_name) == None:
			raise Exception('This operation is not available')
		return self.root._query(start, end, self.operations[operation_name])

	def summary(self):
		return self.root.values

	def update(self, position, value):
		self.root._update(position, value)

	def update_range(self, start, end, value):
		self.root._update_range(start, end, value)

	def __repr__(self):
		return self.root.__repr__()

class SegmentTreeNode:

	def __init__(self, start, end, segment_tree):
		self.range = (start, end)
		self.parent_tree = segment_tree
		self.range_value = None
		self.values = {}
		self.left = None
		self.right = None
		if start == end:
			self._sync()
			return
		self.left = SegmentTreeNode(start, start + (end - start) // 2, segment_tree)
		self.right = SegmentTreeNode(start + (end - start) // 2 + 1, end, segment_tree)
		self._sync()

	def _query(self, start, end, operation):
		if end < self.range[0] or start > self.range[1]:
			return None
		if start <= self.range[0] and self.range[1] <= end:
			return self.values[operation.name]
		self._push()
		left_res = self.left._query(start, end, operation) if self.left else None
		right_res = self.right._query(start, end, operation) if self.right else None
		if left_res is None:
			return right_res
		if right_res is None:
			return left_res
		return operation.f([left_res, right_res])

	def _update(self, position, value):
		if position < self.range[0] or position > self.range[1]:
			return
		if position == self.range[0] and self.range[1] == position:
			self.parent_tree.array[position] = value
			self._sync()
			return
		self._push()
		self.left._update(position, value)
		self.right._update(position, value)
		self._sync()

	def _update_range(self, start, end, value):
		if end < self.range[0] or start > self.range[1]:
			return
		if start <= self.range[0] and self.range[1] <= end:
			self.range_value = value
			self._sync()
			return
		self._push()
		self.left._update_range(start, end, value)
		self.right._update_range(start, end, value)
		self._sync()

	def _sync(self):
		if self.range[0] == self.range[1]:
			for op in self.parent_tree.operations.values():
				current_value = self.parent_tree.array[self.range[0]]
				if self.range_value is not None:
					current_value = self.range_value
				self.values[op.name] = op.f([current_value])
		else:
			for op in self.parent_tree.operations.values():
				result = op.f([self.left.values[op.name], self.right.values[op.name]])
				if self.range_value is not None:
					bound_length = self.range[1] - self.range[0] + 1
					result = op.f_on_equal(self.range_value, bound_length)
				self.values[op.name] = result

	def _push(self):
		if self.range_value is None:
			return
		if self.left:
			self.left.range_value = self.range_value
			self.right.range_value = self.range_value
			self.left._sync()
			self.right._sync()
			self.range_value = None

	def __repr__(self):
		ans = '({}, {}): {}\n'.format(self.range[0], self.range[1], self.values)
		if self.left:
			ans += self.left.__repr__()
		if self.right:
			ans += self.right.__repr__()
		return ans

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

def primeFactors(n):
	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 isprime(n):
	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 test_print(*args):
	if testingMode:
		print(args)

def display_list(list1, sep=' '):
	stdout.write(sep.join(map(str, list1)) + '\n')

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
TestCases = True
testingMode = False
optimiseForReccursion = False

def main():
	(n, k) = get_tuple()
	x = 0
	i = 0
	xs = []
	if k == 0:
		print('YES ' + str(n))
		return
	if n == 1:
		print('YES 0') if k == 1 else print('NO')
		return
	while x <= k and i < n:
		x += 4 ** i
		xs.append(x)
		i += 1
	if x < k:
		print('NO')
		return
	elif k == 3:
		print('YES ' + str(n - 1)) if n > 2 else print('NO')
	else:
		for (i, ele) in enumerate(xs):
			if i == len(xs) - 1:
				ind = len(xs) - 1
			elif ele <= k and xs[i + 1] > k:
				ind = i + 1
				break
		if xs[ind - 1] + (2 * (2 ** ind - 2) + 3) <= k and n > 1:
			ind += 1
		print('YES ' + str(n - ind))
if TestCases:
	for _ in range(get_int()):
		cProfile.run('main()') if testingMode else main()
else:
	(cProfile.run('main()') if testingMode else main()) if not optimiseForReccursion else threading.Thread(target=main).start()


T = int(input())
while T != 0:
	T -= 1
	(N, K) = list(map(int, input().split()))
	cur_usage = 0
	reslog = 0
	cnts = dict()
	while True:
		reslog += 1
		cur_usage += (1 << reslog) - 1
		if reslog != N:
			cnts[reslog] = ((1 << reslog) - 2 << 1) + 1
		if cur_usage + (1 << reslog + 1) - 1 > K or reslog == N:
			break
	K -= cur_usage
	while K > 0:
		if len(cnts) == 0:
			break
		for key in cnts:
			K -= cnts[key]
			if key + 1 >= N:
				del cnts[key]
				break
			if key + 1 not in cnts:
				cnts[key + 1] = 0
			cnts[key + 1] += cnts[key] * 4
			del cnts[key]
			break
	if K <= 0:
		print('YES %d' % (N - reslog))
	else:
		print('NO')


t = int(input())
for i in range(0, t):
	(n, k) = [int(x) for x in input().split()]
	if n >= 32:
		print('YES %d' % (n - 1))
	else:
		low = 0
		co = -1
		md = [0]
		for j in range(1, n):
			md.append(md[-1] * 4 + 1)
		kk = 0
		found = 0
		for cut in range(1, n + 1):
			low += (1 << cut) - 1
			co = 2 * co + 3
			kk += co * md[n - cut]
			if k >= low and k <= low + kk:
				print('YES %d' % (n - cut))
				found = 1
				break
		if found == 0:
			print('NO')


import math
t = int(input())
res = []
while t:
	t -= 1
	(n, k) = map(int, input().split())
	limit = -1
	if n <= 60:
		limit = 0
		pow4 = 1
		for _ in range(n):
			limit += pow4
			pow4 *= 4
	if limit < k and limit != -1 or (n == 2 and k == 3):
		res.append('NO')
	else:
		div = 1
		k -= 1
		size = 1
		while div < n and k >= 4 * size - 1:
			k -= 4 * size - 1
			size *= 2
			div += 1
		res.append('YES ' + str(n - div))
print('\n'.join(res))


m = 10 ** 18

def run():
	(n, k) = [int(x) for x in input().split()]
	(currn, currs) = (1, n)
	rem = 0
	while True:
		if k == 0:
			print(f'YES {currs}')
			return
		if k < currn or currs == 0:
			print('NO')
			return
		currs -= 1
		k -= currn
		if currs >= 40:
			rem = m
		else:
			rem = min(m, rem + cc[currs] * ((currn - 1) * 2 + 1))
		currn = (currn - 1) * 2 + 3
		if k <= rem:
			print(f'YES {currs}')
			return
cc = [0, 1]
for i in range(2, 50):
	cc.append(min(m, 1 + 4 * cc[-1]))
for i in range(int(input())):
	run()


import sys
import random
from itertools import permutations, combinations
from math import sqrt, fabs, ceil
from collections import namedtuple
in_file_path = 'input.txt'
output_file_path = 'output.txt'
SUBMIT = True

def read_num(fin, num_type=int):
	tmp_list = [num_type(x) for x in fin.readline().strip().split()]
	if len(tmp_list) == 1:
		return tmp_list[0]
	else:
		return tuple(tmp_list)

def solve(fin):
	T = read_num(fin)
	for _ in range(0, T):
		(n, k) = read_num(fin)
		if n > 34 or k == 1:
			print('YES', n - 1)
		else:
			f = [0]
			for _ in range(0, n):
				f.append(f[-1] * 4 + 1)
			min_step = 1
			max_step = 1 + f[n - 1]
			out_range = 3
			flag = True
			for i in range(0, n):
				if min_step <= k <= max_step:
					print('YES', n - i - 1)
					flag = False
					break
				max_step += out_range
				min_step += out_range
				out_range = out_range * 2 + 1
				if n - 2 - i >= 0:
					max_step += (out_range - 2) * f[n - 2 - i]
			if flag:
				print('NO')
if SUBMIT:
	solve(sys.stdin)
else:
	solve(open(in_file_path, 'r'))


def f_pow(a, n):
	if n < 0:
		return 0
	if n == 0:
		return 1
	if n % 2 == 0:
		return f_pow(a * a, n // 2)
	else:
		return a * f_pow(a, n - 1)

def get_c(n):
	if n > 68:
		return int(1e+40)
	return (f_pow(4, n) - 4) // 12

def get_cc(n):
	if n > 51:
		return int(1e+30)
	return (f_pow(4, n) - 4) // 12

def ans(n, k):
	side = n - 1
	way = 4
	cnt_all = get_c(n + 1)
	c = 2
	op = 1
	while True:
		if k < op or side < 0:
			break
		way_blocks = way - 1
		if get_cc(side - 1) > k:
			return side
		per_block = get_cc(side + 1)
		kk = k - op
		if cnt_all - way_blocks * per_block - op >= kk:
			return side
		side -= 1
		op += (1 << c) - 1
		c += 1
		way *= 2
	return -1

def read():
	return [int(i) for i in input().split()]
t = int(input())
for i in range(t):
	(n, k) = read()
	a = ans(n, k)
	if a == -1:
		print('NO')
	else:
		print('YES {}'.format(a))


def getsum(n):
	return ((1 << 2 * n) - 1) // 3

def b(n, k):
	l = n - 1
	r = max(0, l - 41)
	while True:
		mid = (l + r) // 2
		count = getsum(n - mid)
		if count <= k:
			l = mid
		else:
			r = mid
		if l - r <= 1:
			break
		del count
	g = getsum(n - r)
	if g < k:
		del g
		return None
	elif g == k:
		del g
		return r
	return l
t = int(input())
for i in range(t):
	(n, k) = map(int, input().split())
	min_side = b(n, k)
	if min_side is None:
		print('NO')
		continue
	k -= getsum(n - min_side)
	if n == 2 and min_side == 1 and (k == 2):
		print('NO')
		continue
	num_squares = (1 << n - min_side) * 2 - 1
	if k >= num_squares:
		print('YES ' + str(min_side - 1))
	else:
		print('YES ' + str(min_side))


pw = [1, 4]
for i in range(2, 32):
	pw.append(pw[i - 1] * 4)
t = int(input())
for cas in range(t):
	(n, k) = map(int, input().split())
	last = 1
	path = 1
	ans = n
	i = 0
	while True:
		if (pw[i + 1] - 1) // 3 > k:
			ans -= i
			last = k - (pw[i] - 1) // 3
			break
		i = i + 1
		path *= 2
	sp = path * 2 - 1
	if ans < 0 or (ans == 0 and last > 0):
		print('No')
		continue
	sq = path * path - sp
	if ans == 1 and last > sq and (last < sp):
		print('No')
		continue
	elif ans == 1 and last >= sp:
		ans = ans - 1
	print('Yes', ans)


def ii():
	return int(input())

def mi():
	return list(map(int, input().split()))

def li():
	return list(mi())
for t in range(ii()):
	(n, k) = mi()
	if n == 1:
		ans = 'YES 0' if k == 1 else 'NO'
	elif n == 2:
		if k <= 2:
			ans = 'YES 1'
		elif k == 3 or k > 5:
			ans = 'NO'
		else:
			ans = 'YES 0'
	elif n <= 32 and k > (4 ** n - 1) // 3:
		ans = 'NO'
	else:
		(c, x) = (0, n)
		p2 = 2
		while x > 0:
			if c + p2 - 1 > k:
				break
			c += p2 - 1
			x -= 1
			p2 *= 2
		ans = 'YES %d' % (x,)
	print(ans)


test = int(input())
while test:
	test = test - 1
	(n, k) = input().split()
	n = int(n)
	k = int(k)
	s = 0
	curr = 1
	ct = 0
	while s < k:
		s = s + curr
		curr = 4 * curr
		ct = ct + 1
	if n >= 35:
		print('YES', n - 1)
		continue
	val = []
	val.append(0)
	for i in range(1, n):
		val.append(1 + 4 * val[i - 1])
	s = 0
	t = 2
	rem = 0
	while n > 0:
		s = s + t - 1
		t *= 2
		p = 3
		rem = rem + (t - 3) * val[n - 1]
		rem = int(rem)
		if rem + s >= k and s <= k:
			print('YES', n - 1)
			n = -2
			break
		n = n - 1
	if n != -2:
		print('NO')


from sys import stdin, stdout
import math
import heapq
from itertools import accumulate
Q = int(input())
four = []
for i in range(62):
	four.append(4 ** i)
for i in range(Q):
	(N, K) = [int(x) for x in stdin.readline().split()]
	tmp_N = N
	if N >= 60:
		N = 60
	dk = (4 ** N - 1) // 3
	if K > dk:
		print('NO')
		continue
	seq = []
	block = []
	s = 0
	for i in range(N):
		s += 2 ** (i + 1) - 1
		block.append(2 ** (i + 1) - 1)
		seq.append(s)
	if K >= seq[-1]:
		print('YES', 0)
		continue
	for i in range(N - 1):
		if K >= seq[i] and K < seq[i + 1]:
			d = K - seq[i]
			happy = tmp_N - i - 1
			round = i + 1
			break
	block = block[::-1]
	res = 0
	for i in range(round):
		A = (4 ** (i + 1) - 1) // 3
		B = block[i] - 2
		res += A * B
	if d <= res:
		print('YES', happy)
	else:
		print('NO')


for _ in range(int(input())):

	def get(n):
		return (4 ** n - 1) // 3
	(n, k) = map(int, input().split())
	if n < 32 and 4 ** n < 1 * 3 * k:
		print('NO')
		continue
	now = 1
	p = 2
	ans = n
	sq = 0
	buff = 0
	d = 4
	while k >= now:
		k -= now
		p *= 2
		now = p - 1
		ans -= 1
		sq = sq * 4 + d - 3
		d *= 2
		if n < 60:
			buff += sq * (4 ** ans - 1) // 3
		else:
			buff = 10 ** 19
		if ans == 0:
			break
	if buff < k:
		print('NO')
	else:
		print('YES', max(ans, 0))


q = int(input())
for i in range(q):
	(n, k) = map(int, input().split())
	if n > 31:
		print('YES', n - 1)
		continue
	a = [0]
	for i in range(1, n + 1):
		a.append(a[i - 1] * 4 + 1)
	if a[n] < k:
		print('NO')
		continue
	if n == 2 and k == 3:
		print('NO')
		continue
	p = 0
	q = 2
	while p + q - 1 <= k and n > 0:
		p += q - 1
		q *= 2
		n -= 1
	print('YES', n)


def main():
	t = int(input())
	for i in range(t):
		(n, k) = input().split(' ')
		n = int(n)
		k = int(k)
		if n > 35:
			m = n - 1
			print('YES ' + m.__str__())
			continue
		if k > (4 ** n - 1) // 3:
			print('NO')
			continue
		ans = None
		for a in range(n):
			can = (2 ** (n - a + 1) - 1) * (4 ** a - 1) // 3
			total = (4 ** n - 1) // 3
			min = 2 ** (n - a + 1) - 2 - n + a
			if k <= total - can and k >= min:
				ans = a
				break
		if ans is not None:
			print('YES ' + ans.__str__())
		else:
			print('NO')
main()


import sys
import math
input = sys.stdin.readline
testcase = int(input())
T = [list(map(int, input().split())) for i in range(testcase)]

def bi(n, k):
	MIN = 0
	MAX = n
	while MAX > MIN + 1:
		bn = (MIN + MAX) // 2
		if math.log2(k + 2 + bn) < bn + 1:
			MAX = bn
		elif math.log2(k + 2 + bn) == bn + 1:
			return bn
		else:
			MIN = bn
	if MAX + 1 <= math.log2(k + 2 + MAX):
		return MAX
	return MIN
for (n, k) in T:
	if n == 1:
		if k == 1:
			print('YES', 0)
		else:
			print('NO')
		continue
	if n == 2:
		if 1 <= k <= 2:
			print('YES', 1)
		elif k == 3:
			print('NO')
		elif 4 <= k <= 5:
			print('YES', 0)
		else:
			print('NO')
		continue
	if n <= 30 and k > (pow(4, n) - 1) // 3:
		print('NO')
		continue
	ANS = bi(n, k)
	print('YES', n - ANS)


for i in range(int(input())):
	(n, k) = [int(i) for i in input().split()]
	if n > 31:
		print('YES ' + str(n - 1))
	else:
		rez = -1
		for i in range(1, n + 1):
			x = (4 ** i - 2 ** (i + 1) + 1) * ((4 ** (n - i) - 1) // 3) + (4 ** i - 1) // 3
			y = (4 ** i - 1) // 3 - (4 ** (i - 1) - 1) // 3
			if y <= k <= x:
				rez = n - i
				break
		print('YES ' + str(rez) if rez != -1 else 'NO')


a = [0 for i in range(100)]
b = [0 for i in range(100)]
for i in range(1, 100):
	a[i] = a[i - 1] * 2 + 1
	b[i] = b[i - 1] + a[i]

def calc(x):
	return (4 ** x - 1) // 3
for i in range(int(input())):
	(n, k) = map(int, input().split())
	if n > 35:
		print('YES ' + str(n - 1))
	elif 1 + calc(n - 1) >= k:
		print('YES ' + str(n - 1))
	elif calc(n) < k:
		print('NO')
	else:
		for i in range(1, n + 1):
			if b[i] <= k and k <= calc(n) - (2 ** (i + 1) - 1) * calc(n - i):
				print('YES ' + str(n - i))
				break
		else:
			print('NO')


from math import *
from random import *
t = int(input())
for l in range(t):
	(n, k) = map(int, input().split())
	fast = 0
	norm = 0
	slow = 0
	length = 1
	power = 1
	slow_flag = False
	for i in range(n, -1, -1):
		if fast <= k and (k <= slow or slow_flag == True):
			print('YES', i)
			break
		if fast > k:
			print('NO')
			break
		fast += length
		norm += power
		length = 2 * length + 1
		power *= 4
		if n > 35:
			slow_flag = True
		if slow_flag == False:
			slow = norm + (power - length) * 4 ** (i - 2)
		if i == 1 or i == 0:
			slow = norm
		if slow > k:
			slow_flag = True
	else:
		print('NO')


for t in range(int(input())):
	(n, k) = map(int, input().split())
	lev = 1
	b = False
	if n >= 60:
		all_moves = 0
		b = True
	else:
		all_moves = (4 ** n - 1) // 3
	cnt = 1
	step = 0
	prev_need = 0
	while True:
		need = 2 * cnt - 1
		if k >= need and step < n:
			k -= need
			all_moves -= need
			cnt *= 2
			step += 1
			prev_need = need
		else:
			if b:
				print('YES', n - step)
				break
			if all_moves < k:
				print('NO')
				break
			all_moves -= 4 ** (n - step) // 3 * need
			if all_moves >= k or b:
				print('YES', n - step)
				break
			else:
				print('NO')
				break


def solve(n, k, v):
	if n >= 50:
		print('YES ' + str(n - 1))
		return
	critical = 1
	excess = 0
	while n > 0:
		if excess >= k:
			print('YES ' + str(n))
			return
		if critical > k:
			print('NO')
			return
		k -= critical
		n -= 1
		excess += (critical * 2 - 1) * v[n]
		critical = critical * 2 + 1
	if excess >= k:
		print('YES ' + str(n))
		return
	print('NO')
v = [0, 1]
for i in range(50):
	a = 1 + 4 * v[-1]
	v.append(a)
t = int(input())
for tcase in range(t):
	inputs = [int(x) for x in input().split()]
	n = inputs[0]
	k = inputs[1]
	solve(n, k, v)


max_ = 10 ** 18
arr = [0, 1]
arr2 = [0, 3]
while arr[-1] < max_:
	arr.append(arr[-1] * 4)
	arr2.append(arr2[-1] * 2 + 1)
for i in range(1, len(arr)):
	arr[i] += arr[i - 1]

def solve(n, k):
	if n == 2 and k == 3:
		return 'NO'
	if n == 2 and k == 4:
		return 'YES 0'
	if n + 1 <= len(arr) and k > arr[n]:
		return 'NO'
	i = 0
	while k >= arr[i + 1]:
		i += 1
	if k - arr[i] > arr2[i]:
		i += 1
	return 'YES ' + str(n - i)
for _ in range(int(input())):
	(n, k) = map(int, input().split())
	print(solve(n, k))


t = int(input())
for _ in range(t):
	(n, k) = list(map(int, input().split()))
	if n >= 32:
		print('YES ' + str(n - 1))
	else:
		ans = -1
		for i in range(1, n + 1):
			p = 4 ** i - 2 ** (i + 1) + 1
			p *= (4 ** (n - i) - 1) // 3
			g = (4 ** i - 1) // 3
			p += (4 ** i - 1) // 3
			g = (4 ** i - 1) // 3 - (4 ** (i - 1) - 1) // 3
			if g <= k and p >= k:
				ans = n - i
				break
		if ans != -1:
			print('YES ' + str(ans))
		else:
			print('NO')


t = int(input())

def get_max(n):
	ans = 0
	while n:
		ans = 4 * ans + 1
		n = n - 1
		if ans > 10 ** 19:
			break
	return ans
for _ in range(t):
	(n, k) = list(map(int, input().split()))
	if n == 1:
		if k == 1:
			print('YES 0')
		else:
			print('NO')
	elif n == 2:
		if k <= 2:
			print('YES 1')
		elif k != 3 and k <= 5:
			print('YES 0')
		else:
			print('NO')
	else:
		siz = n - 1
		l = 1
		cnt = 3
		while siz:
			if l <= k < l + cnt:
				print('YES {}'.format(siz))
				break
			l = l + cnt
			cnt = 2 * cnt + 1
			siz = siz - 1
		else:
			if k <= get_max(n):
				print('YES 0')
			else:
				print('NO')


NANS = (False, None)

def is_valid(n, k):
	if n > 31:
		return True
	return k * 3 <= 2 ** (2 * n) - 1

def solve_mini(n, k):
	if not is_valid(n, k):
		return NANS
	if n == 1:
		if k == 1:
			return (True, 0)
		else:
			return (False, None)
	if n == 2:
		if k in [1, 2]:
			return (True, 1)
		if k in [4, 5]:
			return (True, 0)
	return (False, None)

def solve(n, k):
	if n < 3:
		(ans, log) = solve_mini(n, k)
		return (ans, log)
	if not is_valid(n, k):
		return NANS
	w = 1
	while k >= w and n >= 1:
		k -= w
		n -= 1
		w = w + w + 1
	return (True, n)
t = int(input())
for i in range(t):
	(n, k) = map(int, input().split())
	(ans, log) = solve(n, k)
	if ans:
		print('YES', log)
	else:
		print('NO')


from sys import stdin
memo = {}

def max_splits(n):
	if n == 0:
		return 0
	if n == 1:
		return 1
	if n in memo:
		return memo[n]
	result = 4 * max_splits(n - 1) + 1
	memo[n] = result
	return result
t = int(stdin.readline())
for i in range(t):
	(n, k) = [int(s) for s in stdin.readline().strip().split()]
	min_splits = 1
	path_count = 3
	if n > 75:
		print('YES', n - 1)
		continue
	square_size = n - 1
	max_buffer = max_splits(square_size)
	while min_splits + path_count <= k and square_size > 0:
		min_splits += path_count
		max_buffer += (4 * path_count - (2 * path_count + 1)) * max_splits(square_size - 1)
		path_count = 2 * path_count + 1
		square_size -= 1
	if min_splits <= k <= min_splits + max_buffer:
		print('YES', square_size)
	else:
		print('NO')


def pow(x, p):
	ret = 1
	for i in range(p):
		ret = ret * x
	return ret

def rate(p):
	ret = 0
	now = 1
	for i in range(p):
		ret = ret + now
		now = now * 4
	return ret

def solve():
	(n, k) = map(int, input().split())
	if n > 35:
		print('YES %d' % (n - 1))
		return
	mSplit = 1
	cnt1 = 0
	cnt3 = 1
	for i in range(1, n + 1):
		now = pow(4, i) - pow(2, i + 1) + 1
		now = now * rate(n - i) + rate(i)
		if k <= now:
			print('YES %d' % (n - i))
			return
		mSplit = mSplit + cnt1 + cnt3 * 3
		cnt1 = cnt1 + cnt3
		cnt3 = cnt3 + cnt3
		if mSplit > k:
			break
	print('NO')

def main():
	T = int(input())
	for i in range(T):
		solve()
main()


case = int(input())
for i in range(case):
	f = [0] * 32
	g = [0] * 32
	success = False
	(n, k) = map(int, input().split())
	ans = n
	for i in range(1, n):
		f[i] = f[i - 1] * 4 + 1
		if f[i] >= k:
			success = True
			break
	for i in range(1, n + 1):
		if k < (1 << i) - 1:
			break
		k = k - (1 << i) + 1
		ans = ans - 1
	for i in range(n - 1, ans - 1, -1):
		if i >= 32 or (i and f[i] == 0):
			success = True
			break
		g[i] = 1 if i == n - 1 else g[i + 1] * 2 + 3
		k = k - f[i] * g[i]
		if k <= 0:
			success = True
			break
	print('YES %d' % ans if success else 'NO')


t = int(input())
for _ in range(t):
	(n, k) = map(int, input().split())
	if n == 2 and k == 3:
		print('NO')
		continue
	if n <= 100:
		curr = 0
		for j in range(n):
			curr += pow(4, j)
		if curr < k:
			print('NO')
			continue
	curr = 0
	ans = 0
	while curr < k and ans < n:
		ans += 1
		curr += pow(2, ans) - 1
	if curr > k:
		ans -= 1
	print('YES', n - ans)


lst = list()
lst.append(0)
lst.append(1)
now = 1
while now <= 1e+25:
	now = now * 4 + 1
	lst.append(now)
t = int(input())
for i in range(t):
	s = input().split()
	n = int(s[0])
	k = int(s[1])
	if n >= 34:
		print('YES ' + str(n - 1))
		continue
	sek = 0
	ambil = 1
	nyak = 0
	cnt = 0
	sudah = False
	while sek < n:
		cnt = cnt + (1 << sek + 1) - 1
		if cnt > k:
			print('NO')
			sudah = True
			break
		next_ambil = (ambil + 1) * 2 - 1
		sisa = 4 * ambil - next_ambil
		ambil = next_ambil
		sek += 1
		nyak = nyak + sisa * lst[n - sek]
		if nyak + cnt >= k:
			print('YES ' + str(n - sek))
			sudah = True
			break
	if sudah == False:
		print('NO')