import random
import queue

# ............................................................................
#                                 N O D E
# ............................................................................

class Node:
    def __init__(self, label, key):
        self.left = None
        self.right = None
        self.label = label
        self.key = key
        # not mandatory, used just for display
        self.xcoord = -1
        self.tag = ' ' # one character

    def print(self):
        print( "[" + str(self.key) + "]", end = "" )


# ............................................................................
#                         B I N A R Y   T R E E
# ............................................................................

class BinaryTree:
    def __init__(self  ):
        self.root = None
    # ------------------------------------------------------------------------
    # ...................................................
    #  Basic processing examples:
    #  InOrder, PreOrder, PostOrder
    # ...................................................
    def processInOrder(self, node):
        if (node == None): return
        self.processInOrder(node.left)
        print(node.key, end = " ")
        self.processInOrder(node.right)

    def processPreOrder(self, node):
        if (node == None): return
        print(node.key, end = " ")
        self.processPreOrder(node.left)
        self.processPreOrder(node.right)

    def processPostOrder(self, node):
        if (node == None): return
        self.processPostOrder(node.left)
        self.processPostOrder(node.right)
        print(node.key, end = " ")

    # ------------------------------------------------------------------------
    # ...................................................
    #  Simple random binary tree generator
    # ...................................................
    def  rndTreex(self, node, depth):
        if (depth <= 0 or random.randrange(10) > 7) :
            return None
        newnode = Node(10+random.randrange(90))
        newnode.left = Node.rndTree(depth-1)
        newnode.right = Node.rndTree(depth-1)
        return newnode

    def rndTree(self, node, depth):
        node.key = 10+random.randrange(90)
        if depth <= 0:  return node

        if random.randrange(0, 10) < 6:
            childNode = Node ( 0 )  # any key will do
            node.left = self.rndTree( childNode, depth-1 )

        if random.randrange(0, 10) < 6:
            childNode = Node ( 0 )  # any key will do
            node.right = self.rndTree( childNode, depth-1 )
        return node

    # ------------------------------------------------------------------------
    # ...................................................
    #  Create a tree from all nodes  specifications
    # ...................................................
    def buildFromTable(self, table, localRootLabel ):
        if localRootLabel == -1: return None
        newNode = Node( table[localRootLabel][0], table[localRootLabel][1] )
        newNode.left = self.buildFromTable(table, table[localRootLabel][2] )
        newNode.right = self.buildFromTable(table, table[localRootLabel][3] )
        return newNode

    # Build the tree according to the input specifications stored in a table
    # the items in table row correspond to a node label, node key
    # and the label of the left and right child. Non-existing child is coded by -1.
    # The table is preceded by a row with tree size and the root label.
    # Example:  A tree with three nodes, labeled from left to right 0, 1, 2
    #     ____20____
    #     10      30
    # 3 1
    # 0 10 -1 -1
    # 1 20 0 2
    # 2 30 -1 -1
    def readFromInput(self):
        Nnodes, rootLabel = map(int, input().split())
        table = [];
        # first, load all specifications into the table
        for id in range(Nnodes):
            label, key, leftLabel, rightLabel = map(int, input().split() )
            table.append( [label, key, leftLabel, rightLabel] )
        # now build the entire tree
        self.root =  self.buildFromTable( table, rootLabel )
        # print for debug, if you want to
        # self.processInOrder(self.root)

    # ------------------------------------------------------------------------
    # ...................................................
    #  Display the tree  (a bit technical)
    # ...................................................
    def countNodes(self, node):
        if node == None: return 0
        return 1 + self.countNodes( node.left ) + self.countNodes( node.right )

    # calculates x coord = node order of in Inorder traversal
    def setXcoord(self, node, x_coord):
        if node == None: return x_coord
        node.xcoord = self.setXcoord(node.left, x_coord) + 1
        #print(node.key, node.setXcoord)
        return self.setXcoord(node.right, node.xcoord)

    def display(self):
        self.setXcoord(self.root, 0)
        qu = queue.Queue()
        prevDepth = -1
        prevEndX = -1
        # in the queue store pairs(node, its depth)
        qu.put( (self. root, 0) )
        while not qu.empty():
            node, nodeDepth = qu.get()

            LbranchSize = RbranchSize = 0
            if node.left != None:
                LbranchSize = (node.xcoord - node.left.xcoord)
                qu.put( (node.left, nodeDepth+1) )
            if node.right != None:
                RbranchSize = (node.right.xcoord - node.xcoord)
                qu.put( (node.right, nodeDepth+1) )

            LspacesSize = (node.xcoord - LbranchSize) - 1  # if first on a line
            if prevDepth == nodeDepth:                  # not first on line
                LspacesSize -= prevEndX

            # print the node, branches, leading spaces
            if prevDepth < nodeDepth and prevDepth > -1 : print() # next depth occupies new line
            nodelen = 2
            print( " "*nodelen*LspacesSize, end = '' )
            print( "_"*nodelen*LbranchSize, end = ''  )
            #print( "." + ("%2d"%node.key) + node.tag+".", end = '' )
            #print( node.tag + ("%2d"%node.key), end = ''  )
            print( "" + ("%2d"%node.key), end = ''  )
            print( "_"*nodelen*RbranchSize, end = ''  )

            # used in the next run of the loop:
            prevEndX = node.xcoord + RbranchSize
            prevDepth = nodeDepth
        # end of queue processing

        N = self.countNodes( self.root )
        print("\n"+ '-'*N*nodelen) # finish the last line of the tree


    # ------------------------------------------------------------------------
    # More tree processing examples
    # ------------------------------------------------------------------------

    # Weight of the subtree is the sum of all its keys
    # Determines the number of nodes in the heaviest subtree
    # If more then one subtree is the heaviest it determines
    # the one with minimum number of nodes
    def maxWeigthSubtree(self):
        inRootWeight, inRootSize, maxWeightNodeLabel, maxWeight, maxWeightSize \
            = self.maxWSubtree(self.root)
        print(  maxWeightNodeLabel, maxWeight, maxWeightSize )

    def maxWSubtree( self, node ):
        if node == None: return 0, 0, -1, 0, 0
        weightL, sizeL, maxLabelL, maxWeightL, maxWeightSizeL = self.maxWSubtree(node.left)
        weightR, sizeR, maxLabelR, maxWeightR, maxWeightSizeR = self.maxWSubtree(node.right)
        weightHere = weightL + weightR + node.key
        sizeHere = sizeL + sizeR + 1
        # if this node is better then L and R children
        if weightHere > max (maxWeightL, maxWeightR):
            return weightHere, sizeHere, node.label, weightHere, sizeHere
        # if this node is the same as or worse than one of the L and R children
        if maxWeightL > maxWeightR:
            return maxWeightL, maxWeightSizeL, maxLabelL, maxWeightL, maxWeightSizeL
        if maxWeightL < maxWeightR:
            return maxWeightR, maxWeightSizeR, maxLabelR, maxWeightR, maxWeightSizeR
        # if both L and R have the same weight choose the one with smaller size
        if maxWeightSizeL < maxWeightSizeR:
            return maxWeightL, maxWeightSizeL, maxLabelL, maxWeightL, maxWeightSizeL
        else:  return maxWeightR, maxWeightSizeR, maxLabelR, maxWeightR, maxWeightSizeR

    # ------------------------------------------------------------------------
    # More tree processing examples to be completed
    # ------------------------------------------------------------------------

    # [1] Determine the sum of keys (=weight) in all leaves with positive keys
    def totalWeightOfPositLeaves(self):
        totalWeight = self.totalWOfPositLeaves( self.root )
        print( totalWeight )

    def totalWOfPositLeaves(self, node ):
        if node == None: return 0
        leftW = self.totalWOfPositLeaves( node.left )
        rightW = self.totalWOfPositLeaves( node.right )
        # ... suggest how to fill in the missing code here
        # ...
        # ...
        return ...

    # [2] Determine the maximum size of the subtree which contains only positive keys
    def maxSizeOfPositiveSubtree(self):
        maxSize = self.maxSizeOfPosSubtree( self.root )
        print( maxSize )

    def maxSizeOfPosSubtree(self, node ):
        if node == None:
            return 0, 0, True
        sizeL, maxPositSizeL, allPositiveL = self.maxSizeOfPosSubtree( node.left )
        sizeR, maxPositSizeR, allPositiveR = self.maxSizeOfPosSubtree( node.left )
        # ... suggest how to fill in the missing code here
        # ...
        # ...
        return ...


    # [3] Build a complete balanced tree with the given depth
    # (the total number of nodes in this tree is 2^(depth+1) - 1
    # The value of the node key is equal to twice the value of the parent key
    def buildCompleteTree(self, depth, rootKey ):
        self.root = self.buildComplete( depth, rootKey )

    def buildComplete(self, depth, key ):
        if depth < 0: return None
        # ... suggest how to fill in the missing code here
        # ...
        # ...
        return ...


    # [4] Count the number of nodes with one child in the whole tree
    def countAllNodesWith1child(self):
        all1nodes = self.countNodesWith1Child( self.root )
        print(all1nodes)

    def countNodesWith1Child(self, node):
        if node == None: return 0
        nodes1ChildL =  self.countNodesWith1Child(node.left)
        nodes1ChildR =  self.countNodesWith1Child(node.left)
        # ... suggest how to fill in the missing code here
		# ...
		# ...
        return ...

# ............................................................................
#       M A I N    P R O G R A M
# ............................................................................

T = BinaryTree( )
T.readFromInput()
#T.rndTree( T.root, 5 )
print()
T.display()
T.totalWeightOfPositLeaves()

'''
Input Example
5 2
0 40 -1 -1
1 50 -1 -1
2 15 3 4
3 77 0 1
4 78 -1 -1
'''

