static Node addListsReverse(Node n1, Node n2)
 {
     int length1 = 0;
     int length2 = 0;
     Node r1 = n1;
     Node r2 = n2;
     while (r1 != null)
     {
         length1++;
         r1 = r1.next;
     }
     while (r2 != null)
     {
         length2++;
         r2 = r2.next;
     }
     n2 = pad(length1, length2, n1, n2);
     n1 = pad(length2, length1, n2, n1);
     NodeWrapper result = addReverseRecur(n1, n2);
     if (result.carry == 1)
     {
         Node nn = new Node(1);
         nn.next = result.n;
         return nn;
     }
     else
     {
         return result.n;
     }
 }
 static void delete(Node n)
 {
     if (n == null || n.next == null)
         return;
     n.data = n.next.data;
     n.next = n.next.next;
 }
        static Node addLists(Node n1, Node n2, bool carry)
        {
            if (n1 == null && n2 == null && !carry)
                return null;

            int result = 0;
            if (n1 != null)
                result += n1.data;
            if (n2 != null)
                result += n2.data;
            if (carry)
                result++;

            if (result >= 10)
            {
                carry = true;
                result -= 10;
            }
            else
                carry = false;

            Node n = new Node(result);

            n.next = addLists(n1 == null ? null : n1.next, n2 == null ? null : n2.next, carry);
            return n;
        }
 void appendToTail(int d)
 {
     Node end = new Node(d);
     Node n = this;
     while (n.next != null)
         n = n.next;
     n.next = end;
 }
 public static void printNodes(Node head)
 {
     while (head != null)
     {
         Console.Write(head.data);
         Console.Write(" -> ");
         head = head.next;
     }
     Console.Write("null\n");
 }
 public static Node createLinkedList(int[] nums)
 {
     Node n = new Node(nums[0]);
     Node head = n;
     for (int i = 1; i < nums.Length; i++)
     {
         Node next = new Node(nums[i]);
         n.next = next;
         n = next;
     }
     return head;
 }
 static void removeDuplicateNoStorage(Node n)
 {
     Node current = n;
     while (current != null)
     {
         Node runner = current;
         while (runner.next != null)
         {
             if (current.data == runner.next.data)
                 runner.next = runner.next.next;
             else
                 runner = runner.next;
         }
         current = current.next;
     }
 }
        static NodeWrapper addReverseRecur(Node n1, Node n2)
        {
            if (n1 == null && n2 == null)
                return new NodeWrapper(0, null);

            NodeWrapper wrapper = addReverseRecur(n1.next, n2.next);
            int result = wrapper.carry + n1.data + n2.data;
            int carry = 0;
            if (result >= 10)
            {
                result -= 10;
                carry = 1;
            }
            Node current = new Node(result);
            current.next = wrapper.n;
            return new NodeWrapper(carry, current);
        }
 static int kthToLast(int k, Node head)
 {
     Node current = head;
     Node runner = head;
     for (int i = 0; i < k; i++)
     {
         if (runner == null)
             return -1;
         runner = runner.next;
     }
     if (runner == null)
         return -1;
     while (runner.next != null)
     {
         runner = runner.next;
         current = current.next;
     }
     return current.data;
 }
        static void removeDuplicate(Node n)
        {
            HashSet<int> set = new HashSet<int>();
            Node next = n.next;
            if(next == null)
                return;
            set.Add(n.data);

            while (next != null)
            {
                if (set.Contains(next.data))
                {
                    n.next = next.next;
                }
                else
                {
                    set.Add(next.data);
                    n = n.next;
                }
                next = next.next;
            }
        }
        static Node getLoopBeginning(Node head)
        {
            Node fast = head;
            Node slow = head;

            while (fast != null && fast.next != null)
            {
                slow = slow.next;
                fast = fast.next.next;
                if (slow == fast)
                    break;
            }

            if (fast == null || fast.next == null)
                return null;

            slow = head;
            while (slow != fast)
            {
                slow = slow.next;
                fast = fast.next;
            }
            return fast;
        }
        static Boolean isPalindrome(Node n)
        {
            Node fastRunner = n;
            Node slowRunner = n;
            Stack<int> stack = new Stack<int>();
            while (fastRunner != null && fastRunner.next != null)
            {
                fastRunner = fastRunner.next.next;
                stack.Push(slowRunner.data);
                slowRunner = slowRunner.next;
            }
            if (fastRunner != null && fastRunner.next == null)//Odd number of nodes
                if (stack.Count > 0)//Check case of only one node
                    stack.Pop();

            while (stack.Count > 0)
            {
                int num = stack.Pop();
                 if (num != slowRunner.data)
                     return false;
                 slowRunner = slowRunner.next;
            }
            return true;
        }
 static Node pad(int r1, int r2, Node n1, Node n2)
 {
     if (r1 <= r2)
         return n2;
     int diff = r1 - r2;
     Node padding = new Node(0);
     Node paddingHead = padding;
     for (int i = 1; i < diff; i++)
     {
         padding.next = new Node(0);
         padding = padding.next;
     }
     padding.next = n2;
     return paddingHead;
 }
 public NodeWrapper(int carry, Node n)
 {
     this.carry = carry;
     this.n = n;
 }