def circular_ll(l):
    """
    Given a circular linked list, this would return the beginning of the circular loop
    Returns False if the list is linear. This is a toughie!
    Observations:
    1. We will use two pointers, one moving twice as fast as the other. Then if the two
       meet again, we have a loop.
    2. If they both started from the same place, they will meet at the start. (fast ptr
       would have made two laps by the time the slow ptr made just one!)
    3. If They didn't start at the same place, but say the fast ptr started k steps ahead,
       then they will meet k steps before the start of the loop.
    So we just have to run these two pointers, the place where they meet will be k steps 
    before the start of the loop. Also, this k is the head start that fast ptr got before the small
    ptr entered the loop, so head is k steps away from the start of the loop.
    Reset slow ptr back to head, and leave the fast ptr at the meeting place. Since both these starting
    points are k steps away from the loop start, by running both the pointers AT THE SAME PACE, we 
    are guaranteed that they will meet again at the loop start.
    """
    fast = l.head
    slow = l.head
    # Run one to make them meet
    while fast and fast.next:
        fast = fast.next.next
        slow = slow.next
        if fast.data == slow.data:
            break

    # Handle the case of no circularity
    if not fast.next:
        return False
    # Setting slow back to head
    slow = l.head
    while slow.data != fast.data:
        slow = slow.next
        fast = fast.next

    return fast.data