import java.util.*;

//We need to handle this challenge from the perspective of understanding the shapes in the top right (positive x axis and y axis)
//I have a feeling that once this is established.
//I can then use  principles of test cases 1-7 in which I had completed the exact overlaps... In this area, I focussed on the
//implications of having coordinates in the positive x and negative x axis. I would need to apply the following logic
//if ((rect2BottomLeft[1]<0 && rect2TopRight[1]>0)) into my main analysis undertaken in the positive axis.
//Since the principles should still hold

//When it reaches test case 22 and 23, there are new challenges that have arisen


public class Solution 
{
    public static int overlappingArea(int[] rect1BottomLeft, int[] rect1TopRight, int[] rect2BottomLeft, int[] rect2TopRight) 
    {
        int width=0;
        int height=0;
        int [] store = new int[4];
        int count=0;
        
        //used for test case 11
        if (rect1BottomLeft[0]>=rect2TopRight[0]
           || (rect2BottomLeft[0]>=rect1TopRight[0])
            || (rect1BottomLeft[1]>=rect2TopRight[1])
           || (rect2BottomLeft[1]>=rect1TopRight[1]))
           {
               System.out.println("NO OVERLAP FOUND");
               System.exit(0);
           }
           
           //now need to focus on exact overlap
           
           System.out.println("rect1Topright: " + rect1TopRight[1]);
           System.out.println("rect2TopRight: " + rect2TopRight[1]);
           System.out.println("rect1BottomLeft: " + rect1BottomLeft[1]);
           System.out.println("rect2BottomLeft: " + rect2BottomLeft[1]);
           
           
           if (rect1TopRight[1]==rect2TopRight[1]
              &&rect1BottomLeft[1]==rect2BottomLeft[1])
              {
                  System.out.println("EXACT overlap");
                  
                  if ((rect2BottomLeft[1]<0 && rect2TopRight[1]>0))
                  
                  {
                      width = Math.abs(0-rect2BottomLeft[0]) + Math.abs(0-rect2TopRight[0]);
                  height = Math.abs(0-rect2BottomLeft[1]) + Math.abs(0-rect2TopRight[1]);
                      
                  }
                  
                  else
                  {
                  
                  width = Math.abs(0-rect2BottomLeft[0]) - Math.abs(0-rect2TopRight[0]);
                  System.out.println(width);
                  height = Math.abs(0-rect2BottomLeft[1]) - Math.abs(0-rect2TopRight[1]);
                  System.out.println(height);
                  
                  }
                  return (Math.abs(width) * Math.abs(height));
              }
             
              
              //if all in the positive axis
             if (rect1BottomLeft[1]>=0 && rect2BottomLeft[1]>0  
             && rect1TopRight[1]>=0 && rect2TopRight[1]>=0)
                {
                    
                    //whether the shapes are physically overlapped
                    //looks at x axis
                    
                    //x axis smalller
                    if(rect1BottomLeft[0]<rect2BottomLeft[0])
                    {
                        //looks at y axis,  y axis smaller
                        if (rect1TopRight[1]<rect2TopRight[1])
                        {
                            
                            
    //We need something to treat different if X axis is smaller rect1BottomLeft[0]
    //(which blue is smaller than red rect1BottomLeft[0])...And also Y axis is smaller 
    //rect1TopRight[1](which it is, blue smaller than red rect1TopRight[2])..
    //This observation would be suitable for Test Case 8.
    //But for Test Case 22 and 23, we can also see that blue rectangle has gone through both sides of the red.....
    //To translate this into coding, we need to check if the blue rectangle has a top right (x axis) which is greater than red rectangle x axis...
    //IF this is the case, then we are interested in using the width = width of the red rectangle.
    //And we will need height to be the same as blue rectangle...
    
    if (rect1TopRight[0]>rect2TopRight[0])
    {
        width = Math.abs(0-rect2BottomLeft[0]) - Math.abs(0-rect2TopRight[0]);
        height = Math.abs(0-rect1BottomLeft[1]) - Math.abs(0-rect1TopRight[1]);
        
        System.out.println("HERE9");
        System.out.println(width);
        System.out.println(height);
        
        return (Math.abs(width) * Math.abs(height));
    }
    
    else
    {
            System.out.println("HERE1");
            width = Math.abs(0-rect2BottomLeft[0]) - Math.abs(0-rect1TopRight[0]);
            System.out.println(width);
            height = Math.abs(0-rect2BottomLeft[1]) - Math.abs(0-rect1TopRight[1]);
            System.out.println(height);
                            
            return (Math.abs(width) * Math.abs(height));
    }
                        }
                    }
                    
                    //Same code as above, but flipped  (test case 9)
                    if(rect2BottomLeft[0]<rect1BottomLeft[0])
                    {
                        if (rect2TopRight[1]<rect1TopRight[1])
                        {
                            
                            //We need something to treat different if X axis is smaller rect1BottomLeft[0]
    //(which blue is smaller than red rect1BottomLeft[0])...And also Y axis is smaller 
    //rect1TopRight[1](which it is, blue smaller than red rect1TopRight[2])..
    //This observation would be suitable for Test Case 8.
    //But for Test Case 22 and 23, we can also see that blue rectangle has gone through both sides of the red.....
    //To translate this into coding, we need to check if the blue rectangle has a top right (x axis) which is greater than red rectangle x axis...
    //IF this is the case, then we are interested in using the width = width of the red rectangle.
    //And we will need height to be the same as blue rectangle...
    
    if (rect2TopRight[0]>rect1TopRight[0])
    {
        width = Math.abs(0-rect1BottomLeft[0]) - Math.abs(0-rect1TopRight[0]);
        height = Math.abs(0-rect2BottomLeft[1]) - Math.abs(0-rect2TopRight[1]);
        
        System.out.println("HERE9");
        System.out.println(width);
        System.out.println(height);
        
        return (Math.abs(width) * Math.abs(height));
    }
                            
                            
                            
                            
                            
                            
                            
                            else
                            {
                            System.out.println("HERE2");
                            width = Math.abs(0-rect1BottomLeft[0]) - Math.abs(0-rect2TopRight[0]);
                            System.out.println(width);
                            height = Math.abs(0-rect1BottomLeft[1]) - Math.abs(0-rect2TopRight[1]);
                            System.out.println(height);
                            
                            return (Math.abs(width) * Math.abs(height));
                            }
                        }
                    }
                    
                    
                    //whether shape is inside shape 
                    //to make it compliant with test case 14 and test case 15, I included less than and equal to as part of equality check 
                    
                     if(rect1BottomLeft[0]>=rect2BottomLeft[0]  ||  rect2BottomLeft[0]>=rect1BottomLeft[0])
                     {
                        //test case 10
                        if (rect1TopRight[1]<=rect2TopRight[1])
                        {
                            //needed this as part of test cases 14 and 15
                            //to exactly identify which is inside the other one 
                            
                            //with test case 24 and test case 25 it is performning assumption that shape is inside shape
                            //we can understand from the perspective of the X coordinates, it fits inside
                            //But we have not contemplated the Y coordinate
                            
                            
                            if (rect1BottomLeft[1] >= rect2BottomLeft[1])
                            {
                            if(rect1BottomLeft[0]>=rect2BottomLeft[0])
                            {
                            
                            System.out.println("MUST1");
                            width = Math.abs(0-rect1BottomLeft[0]) - Math.abs(0-rect1TopRight[0]);
                            System.out.println(width);
                            height = Math.abs(0-rect1BottomLeft[1]) - Math.abs(0-rect1TopRight[1]);
                            System.out.println(height);
                            
                            store[count]=(Math.abs(width) * Math.abs(height));
                            count++;
                            //return (Math.abs(width) * Math.abs(height));
                            
                            }
                            
                            
                            else
                            {
                            
                            System.out.println("MUST2");
                            width = Math.abs(0-rect2BottomLeft[0]) - Math.abs(0-rect2TopRight[0]);
                            System.out.println(width);
                            height = Math.abs(0-rect2BottomLeft[1]) - Math.abs(0-rect2TopRight[1]);
                            System.out.println(height);
                            store[count]=(Math.abs(width) * Math.abs(height));
                            count++;
                            }
                            
                        }
                        
                        //this is taking into consideration of the Y co-ordinates and making a better decision in test case 24 and 25
                        
                        else
                        {
                            width = Math.abs(0-rect1BottomLeft[0]) - Math.abs(0-rect2TopRight[0]);
                            System.out.println(width);
                            height = Math.abs(0-rect2BottomLeft[1]) - Math.abs(0-rect1TopRight[1]);
                            System.out.println(height);
                            System.out.println("MUST7");
                            return (Math.abs(width) * Math.abs(height));
                        }
                        
                        
                     }
                        
                        //test case 11
                        //swap of shapes
                        if (rect2TopRight[1]<=rect1TopRight[1])
                        {
                            //needed this as part of test cases 14 and 15
                            //to exactly identify which is inside the other one 
                            
                            //needed this as part of test cases 14 and 15
                            //to exactly identify which is inside the other one 
                            
                            //with test case 24 and test case 25 it is performning assumption that shape is inside shape
                            //we can understand from the perspective of the X coordinates, it fits inside
                            //But we have not contemplated the Y coordinate
                            
                            
                            if (rect2BottomLeft[1] >= rect1BottomLeft[1])
                            {
                            
                            
                            if (rect2BottomLeft[0]>=rect1BottomLeft[0])
                            {
                            System.out.println("MUST3");
                            width = Math.abs(0-rect2BottomLeft[0]) - Math.abs(0-rect2TopRight[0]);
                            System.out.println(width);
                            height = Math.abs(0-rect2BottomLeft[1]) - Math.abs(0-rect2TopRight[1]);
                            System.out.println(height);
                            //return (Math.abs(width) * Math.abs(height));
                            store[count]=(Math.abs(width) * Math.abs(height));
                            count++;
                            }
                            
                            else
                            {
                                System.out.println("MUST4");
                            width = Math.abs(0-rect1BottomLeft[0]) - Math.abs(0-rect1TopRight[0]);
                            System.out.println(width);
                            height = Math.abs(0-rect1BottomLeft[1]) - Math.abs(0-rect1TopRight[1]);
                            System.out.println(height);
                             store[count]=(Math.abs(width) * Math.abs(height));
                            
                            }
                        }
                        
                        //this is taking into consideration of the Y co-ordinates and making a better decision in test case 24 and 25
                        
                        else
                        {
                             
                            
                           width = Math.abs(0-rect2BottomLeft[0]) - Math.abs(0-rect1TopRight[0]);
                            System.out.println(width);
                            height = Math.abs(0-rect1BottomLeft[1]) - Math.abs(0-rect2TopRight[1]);
                            System.out.println(height);
                            System.out.println("MUST8");
                            return (Math.abs(width) * Math.abs(height));
                        }
                            
                        }
                    }
                }
        
        //return (Math.abs(width) * Math.abs(height));
        return GetHighestArea(store);
    }
    
    public static int GetHighestArea(int []store)
    {
        int min = store[0];
        for (int i: store)
        {
            if (i<min && i!=0)
            {
                min = i;
            }
        }
        return min;
    }

    public static void main (String[] args)
    {
        
           //TEST CASE 1 - NO OVERLAP
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{-6, 5},  new int[]{-5, 5},new int[]{-8, 2}, new int[]{-4, 3}));
        //                                                           //rect1bottomLeft     //rect1TopRight   //rect2BottomLeft    //rect2TopRight
        
         //TEST CASE 2 - EXACT OVERLAP
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{3, 3},  new int[]{6, 6},new int[]{3, 3}, new int[]{6, 6}));
        //                                                           //rect1bottomLeft     //rect1TopRight   //rect2BottomLeft    //rect2TopRight
        
         //TEST CASE 3 - EXACT OVERLAP
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{-9, 0},  new int[]{-6, 3},new int[]{-9, 0}, new int[]{-6, 3}));
        //                                                           //rect1bottomLeft     //rect1TopRight   //rect2BottomLeft    //rect2TopRight
        
          //TEST CASE 4 - EXACT OVERLAP
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{0, -2},  new int[]{3, 1},new int[]{0, -2}, new int[]{3, 1}));
        //                                                           //rect1bottomLeft     //rect1TopRight   //rect2BottomLeft    //rect2TopRight
        
      
          //TEST CASE 5 - EXACT OVERLAP
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{-1, -1},  new int[]{2, 2},new int[]{-1, -1}, new int[]{2, 2}));
        //                                                           //rect1bottomLeft     //rect1TopRight   //rect2BottomLeft    //rect2TopRight
        
      
       //TEST CASE 6 - EXACT OVERLAP
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{-6, -5},  new int[]{-3, -2},new int[]{-6, -5}, new int[]{-3, -2}));
        //                                                           //rect1bottomLeft     //rect1TopRight   //rect2BottomLeft    //rect2TopRight
        
      //TEST CASE 7 - EXACT OVERLAP
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{4, -5},  new int[]{7, -2},new int[]{4, -5}, new int[]{7, -2}));
        //                                                           //rect1bottomLeft     //rect1TopRight   //rect2BottomLeft    //rect2TopRight
        
        
       //TEST CASE 8 - EXACT OVERLAP
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{3, 1},  new int[]{6, 4},new int[]{4, 2}, new int[]{7, 5}));
        //                                                           //rect1bottomLeft     //rect1TopRight   //rect2BottomLeft    //rect2TopRight
        
      
       //TEST CASE 9 - EXACT OVERLAP (flip of test case 8)
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{4, 2}, new int[]{7, 5},new int[]{3, 1},  new int[]{6, 4}));
        //                                                           //rect1bottomLeft     //rect1TopRight   //rect2BottomLeft    //rect2TopRight
        
        //TEST CASE 10 
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{4, 2}, new int[]{7, 5},new int[]{4, 2},  new int[]{9, 6}));
        //                                                           //rect1bottomLeft     //rect1TopRight   //rect2BottomLeft    //rect2TopRight
        
      
      //TEST CASE 11   same as above flipped
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{4, 2},  new int[]{9, 6},new int[]{4, 2}, new int[]{7, 5}));
        //
        
         //TEST CASE 12   this will follow same principle as test case 10
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{3, 1},  new int[]{9, 6},new int[]{4, 2}, new int[]{7, 5}));
        //     
        
        //TEST CASE 13   same as above, but flipped
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{4, 2}, new int[]{7, 5},new int[]{3, 1},  new int[]{9, 6}));
        //     
        
          //TEST CASE 14   same as above, but flipped
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{3, 1}, new int[]{9, 6},new int[]{6, 3},  new int[]{9, 6}));
        //    
        
            //TEST CASE 15   same as above, but flipped
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{6, 3},  new int[]{9, 6},new int[]{3, 1}, new int[]{9, 6}));
        //     
        
        
         //TEST CASE 16
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{6, 3},  new int[]{9, 4},new int[]{6, 3}, new int[]{9, 6}));
        //    
        
         //TEST CASE 17, same as above but flipped
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{6, 3}, new int[]{9, 6},new int[]{6, 3},  new int[]{9, 4}));
        //    
        
         //TEST CASE 18, same as above but flipped
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{6, 3}, new int[]{9, 6},new int[]{6, 5},  new int[]{9, 6}));
        //    
        
         //TEST CASE 19, same as above but flipped
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{6, 5},  new int[]{9, 6},new int[]{6, 3}, new int[]{9, 6}));
        //   
        
        
        //TEST CASE 20
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{6, 3},  new int[]{9, 6},new int[]{8, 3}, new int[]{9, 6}));
        // 
        
         //TEST CASE 21, same as above but flipped
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{8, 3}, new int[]{9, 6}),new int[]{6, 3},  new int[]{9, 6});
          // 
        
        
        
        
      //TEST CASE 22
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{5, 2}, new int[]{6, 6},new int[]{4, 3},  new int[]{7, 5}));
          // 
          
          //TEST CASE 23 - flip of the above
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{4, 3},  new int[]{7, 5},new int[]{5, 2}, new int[]{6, 6}));
          // 
          
             //TEST CASE 24
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{4, 1},  new int[]{8, 3},new int[]{4, 2}, new int[]{8, 4}));
          // 
          
               //TEST CASE 25  - flip of the above
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{4, 2}, new int[]{8, 4},new int[]{4, 1},  new int[]{8, 3}));
          //
          
           //TEST CASE 26
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{2, 1}, new int[]{4, 4},new int[]{4, 2},  new int[]{8, 4}));
          //
          
           //TEST CASE 27 - flip of the above
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{4, 2}, new int[]{8, 4},new int[]{4, 1},  new int[]{8, 3}));
          //
          
          //TEST CASE 28
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{2, 2}, new int[]{4, 5},new int[]{4, 2},  new int[]{8, 4}));
          //
          
           //TEST CASE 29 - flip of the above
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{4, 2},  new int[]{8, 4},new int[]{2, 2}, new int[]{4, 5}));
          //
          
          //TEST CASE 30
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{2, 1},  new int[]{4, 5},new int[]{4, 2}, new int[]{8, 4}));
          //
          
          //TEST CASE 31 - flip of the above
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{4, 2}, new int[]{8, 4},new int[]{2, 1},  new int[]{4, 5}));
          //
          
          //TEST CASE 32
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{2, 1}, new int[]{4, 5},new int[]{3, 3},  new int[]{7, 6}));
          //
          
          //TEST CASE 33 - flip of the above
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{3, 3},  new int[]{7, 6},new int[]{2, 1}, new int[]{4, 5}));
          //
               
          //TEST CASE 34
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{-8, 1},  new int[]{-6, 5},new int[]{-7, 3}, new int[]{-3, 6}));
          //
          
           //TEST CASE 35 - flip of the above
          //System.out.println("The overlapping area is: " + overlappingArea(new int[]{-7, 3}, new int[]{-3, 6},new int[]{-8, 1},  new int[]{-6, 5}));
          //
          
           //TEST CASE 36
          System.out.println("The overlapping area is: " + overlappingArea(new int[]{-6, -2}, new int[]{-4, 2},new int[]{-5, 0},  new int[]{-1, 3}));
          //
          
          
          
  
        
    }
}