class Index:
	def __init__(self, i, j, k, lifetime):
		self.i = i
		self.j = j
		self.k = k
		self.lifetime = lifetime

	def visit(self):
		print("[{}, {}, {}]".format(self.i, self.j, self.k))

	# +I -> -j
	# -J -> -i
	# -I -> +j
	# +J -> +i
	# +K -> +I, -J, -I, +J

def StepMainPlusI(mainPlusI, minusJ, lifetime):
	result = []
	for m in mainPlusI:
		if lifetime > 0:
			minusJ.append(Index(m.i, m.j-1, m.k, lifetime))
		m.lifetime -= 1
		m.i += 1
		if m.lifetime > 0:
			result.append(m)
	return result

def StepMainMinusJ(mainMinusJ, minusI, lifetime):
	result = []
	for m in mainMinusJ:
		if lifetime > 0:
			minusI.append(Index(m.i-1, m.j, m.k, lifetime))
		m.lifetime -= 1
		m.j -= 1
		if m.lifetime > 0:
			result.append(m)
	return result

def StepMainMinusI(mainMinusI, plusJ, lifetime):
	result = []
	for m in mainMinusI:
		if lifetime > 0:
			plusJ.append(Index(m.i, m.j+1, m.k, lifetime))
		m.lifetime -= 1
		m.i -= 1
		if m.lifetime > 0:
			result.append(m)
	return result

def StepMainPlusJ(mainPlusJ, plusI, lifetime):
	result = []
	for m in mainPlusJ:
		if lifetime > 0:
			plusI.append(Index(m.i+1, m.j, m.k, lifetime))
		m.lifetime -= 1
		m.j += 1
		if m.lifetime > 0:
			result.append(m)
	return result

def StepMainPlusK(mainPlusK, mainPlusI, mainMinusI, mainPlusJ, mainMinusJ, lifetimeA, lifetimeB):
	result = []
	for m in mainPlusK:
		if lifetimeA > 0:
			mainPlusI.append(Index(+1, 0, m.k, lifetimeA))
			mainPlusJ.append(Index(0, +1, m.k, lifetimeA))
		if lifetimeB > 0:
			mainMinusI.append(Index(-1, 0, m.k, lifetimeB))
			mainMinusJ.append(Index(0, -1, m.k, lifetimeB))
		m.lifetime -= 1
		m.k += 1
		if m.lifetime > 0:
			result.append(m)
	return result

def StepMainMinusK(mainMinusK, mainPlusI, mainMinusI, mainPlusJ, mainMinusJ, lifetimeA, lifetimeB):
	result = []
	for m in mainMinusK:
		if lifetimeA > 0:
			mainPlusI.append(Index(+1, 0, m.k, lifetimeA))
			mainPlusJ.append(Index(0, +1, m.k, lifetimeA))
		if lifetimeB > 0:
			mainMinusI.append(Index(-1, 0, m.k, lifetimeB))
			mainMinusJ.append(Index(0, -1, m.k, lifetimeB))
		m.lifetime -= 1
		m.k -= 1
		if m.lifetime > 0:
			result.append(m)
	return result

def StepPlusI(plusI):
	result = []
	for m in plusI:
		m.i += 1
		m.lifetime -= 1
		if m.lifetime > 0:
			result.append(m)
	return result

def StepMinusI(minusI):
	result = []
	for m in minusI:
		m.i -= 1
		m.lifetime -= 1
		if m.lifetime > 0:
			result.append(m)
	return result

def StepPlusJ(plusJ):
	result = []
	for m in plusJ:
		m.j += 1
		m.lifetime -= 1
		if m.lifetime > 0:
			result.append(m)
	return result

def StepMinusJ(minusJ):
	result = []
	for m in minusJ:
		m.j -= 1
		m.lifetime -= 1
		if m.lifetime > 0:
			result.append(m)
	return result

def Traverse(N):
	halfA = halfB = (N-1)/2
	if N % 2 == 0:
		halfA = N/2
		halfB = N/2-1

	# visit center
	Index(0,0,0,0).visit()

	# Side growing nodes
	PlusI  = []
	MinusI = []
	PlusJ  = []
	MinusJ = []

	# Main growing nodes
	MainPlusI  = []
	MainMinusI = []
	MainPlusJ  = []
	MainMinusJ = []
	MainPlusK  = []
	MainMinusK = []

	if halfA > 0:
		MainPlusI.append(  Index(+1, 0, 0, halfA) )
		MainPlusJ.append(  Index(0, +1, 0, halfA) )
		MainPlusK.append(  Index(0, 0, +1, halfA) )

	if halfB > 0:
		MainMinusI.append( Index(-1, 0, 0, halfB) )
		MainMinusJ.append( Index(0, -1, 0, halfB) )
		MainMinusK.append( Index(0, 0, -1, halfB) )

	visited = True
	while visited:
		visited = False

		# visit all main nodes
		for m in MainPlusI:
			m.visit()
			visited = True
		for m in MainMinusI:
			m.visit()
			visited = True
		for m in MainPlusJ:
			m.visit()
			visited = True
		for m in MainMinusJ:
			m.visit()
			visited = True
		for m in MainPlusK:
			m.visit()
			visited = True
		for m in MainMinusK:
			m.visit()
			visited = True

		# visit all side nodes
		for m in PlusI:
			m.visit()
			visited = True
		for m in MinusI:
			m.visit()
			visited = True
		for m in PlusJ:
			m.visit()
			visited = True
		for m in MinusJ:
			m.visit()
			visited = True

		PlusI = StepPlusI(PlusI)
		MinusI = StepMinusI(MinusI)
		PlusJ = StepPlusJ(PlusJ)
		MinusJ = StepMinusJ(MinusJ)

		MainPlusI = StepMainPlusI(MainPlusI, MinusJ, halfB)
		MainMinusJ = StepMainMinusJ(MainMinusJ, MinusI, halfB)
		MainMinusI = StepMainMinusI(MainMinusI, PlusJ, halfA)
		MainPlusJ = StepMainPlusJ(MainPlusJ, PlusI, halfA)

		MainPlusK = StepMainPlusK(MainPlusK, MainPlusI, MainMinusI, MainPlusJ, MainMinusJ, halfA, halfB)
		MainMinusK = StepMainMinusK(MainMinusK, MainPlusI, MainMinusI, MainPlusJ, MainMinusJ, halfA, halfB)


Traverse(5)

