import java.util.*;
public class Solution {
    
    public static void main (String[] args)
    {
            //Test case 1 
            List<List<Object>> intervals = new ArrayList<>();
            
            List<Object> entries = new ArrayList<>();
            
            //TEST CASE 1 - No issues     PASS
            //entries.add("[1, 3]");
            
            //TEST CASE 2 - No issues     PASS
            //entries.add("[1, 3]");
            //entries.add("[4, 7]");
            
            //TEST CASE 3 - No issues     PASS
            //entries.add("[1, 3]");
            //entries.add("[2, 7]");
            
            //TEST CASE 4 - No issues     PASS
            //entries.add("[1, 3]");
            //entries.add("[4, 7]");
            //entries.add("[8, 9]");
            
            //TEST CASE 5 - No issues     PASS
            //entries.add("[1, 3]");
            //entries.add("[2, 7]");
            //entries.add("[8, 9]");
            
            // I CAN SEE, AS THE OBJECTS HIT 4, SIMILAR TO MY OTHER CODE, THE RESULTS WERE SKEWED....
            
             //TEST CASE 6 - No issues     PASS
            //entries.add("[1, 3]");
            //entries.add("[4, 7]");
            //entries.add("[8, 10]");
            //entries.add("[11, 25]");
            
            /*
            //TEST CASE 7 - No issues     PASS
            entries.add("[1, 3]");
            entries.add("[4, 7]");
            entries.add("[8, 10]");
            entries.add("[11, 25]");
            entries.add("[27, 33]");
            entries.add("[35, 38]");
            entries.add("[42, 47]");
            */
            
            //TEST CASE 8 -                 PASS
            //entries.add("[1, 3]");
            //entries.add("[2, 7]");
            //entries.add("[6, 10]");
            
            /*
             //TEST CASE 9 -                 PASS
            entries.add("[1, 3]");
            entries.add("[2, 7]");
            entries.add("[6, 10]");
            entries.add("[9, 25]");
            entries.add("[24, 33]");
            entries.add("[30, 38]");
            entries.add("[34, 44]");
            */
            
            /*
            //TEST CASE 10                  PASS 
            entries.add("[1, 3]");
            entries.add("[4, 7]");
            entries.add("[6, 9]");
            entries.add("[8, 25]");
            */
            
            /*
            //TEST CASE 11                PASS
            entries.add("[1, 3]");
            entries.add("[2, 7]");
            entries.add("[8, 9]");
            entries.add("[19, 45]");
            entries.add("[40, 52]");
            entries.add("[58, 61]");
            */
            
            /*
            //TEST CASE 12 - Invalid data   (same interval first two objects) - - seems satisfactory output
            entries.add("[1, 3]");
            entries.add("[3, 9]");
            entries.add("[8, 9]");
            */
            
            //TEST CASE 13 - Invalid data   (same interval first two objects) - seems satisfactory output
            //entries.add("[1, 3]");
            //entries.add("[3, 9]");
            //entries.add("[8, 12]");
            //entries.add("[12, 15]");
            
            /*
            //TEST CASE 14 - Invalid data   (same interval first two objects) - seems semantically correct
            entries.add("[1, 3]");
            entries.add("[4, 9]");
            entries.add("[8, 4]");
            entries.add("[9, 2]");
            */
            
            
            //TEST CASE 15 - undocumented  (same ranges) - seems satisfactory output
            entries.add("[1, 3]");
            entries.add("[1, 3]");
            
            
            
            intervals.add(entries);
            
            System.out.println("Final outer list: " + mergeIntervals(intervals));
            
            //mergeIntervals(new ArrayList<>(Arrays.asList(["[1,4]", "[4,5]"])));
    }
    
    public static List<List<Object>> mergeIntervals(List<List<Object>> intervals) 
    {
        List<List<Object>> outerList = new ArrayList<>();

        List<Object> innerList = new ArrayList<>();  //this is the list inside list to satisfy return type

        int counter=0;
        
        String newInterval="";
        
        int numberObjects=0;
        String range;
                
        String startIntervalFirstRange="";
        String endIntervalFirstRange="";
        
        String startIntervalSecondRange="";
        String endIntervalSecondRange="";
        
        //first need to understand that return type is List < List<Integer> >
        //I am not sure if System.out.println() will print this since I am typically not used to having a collection within a collection..
        //Since we are returning variable of this datatype, I presume the test environment will take care of this scenario..
        // It will only become an issue once I configure the driver class with main method

        //Also require an iterator through the list

        Iterator<List<Object>> it = intervals.iterator();

        //since the data inside mergeIntervals is a List, I think the hasNext() might not be applicable
        //since this would refer to a String....
        
        //need to iterate through the List items differently
        
        System.out.println("REACH HERE");
        
        for (List <Object> tt: intervals)
        {  
              for (Object s:tt)
            {
                numberObjects++;
            }
            
            for (Object s:tt)  //process each Object in the intervals   {X,Y}, {X,Z}......
            {
                counter++;
                System.out.println("\nTHIS IS OBJECT: " + s +  " Counter: " + counter);
                    
                range = String.valueOf(s);
                
                //we know only one range and it has to be outputted
                //basic scenario
                if (numberObjects==1)
                {
                    startIntervalFirstRange = range.substring(1, range.indexOf(","));
                    System.out.println(startIntervalFirstRange);
                    endIntervalFirstRange = range.substring(range.indexOf(" ")+1,range.indexOf("]"));
                    System.out.println(endIntervalFirstRange);
                    
                    newInterval = "["+startIntervalFirstRange+","+ " " + endIntervalFirstRange+"]";
                    innerList.add(newInterval);
                    System.out.println("1Added into innerlist: " + innerList);
                }
                
                if (counter>2)
                {
                    //in here for remaining.
                    //we can pull the Object into any pair of set of variables
                    //{startIntervalFirstRange, endIntervalFirstRange}
                    //{startIntervalSecondRange, endIntervalSecondRange}
                
                    //perform same comparison again against the newInterval (X, Y)
                    
                    String endNewInterval = newInterval.substring(newInterval.indexOf(" ")+1, newInterval.indexOf("]"));
                    System.out.println("END OF NEW INTERVAL: " + endNewInterval);
                    
                    startIntervalFirstRange = range.substring(1, range.indexOf(","));
                    System.out.println(startIntervalFirstRange);
                    endIntervalFirstRange = range.substring(range.indexOf(" ")+1,range.indexOf("]"));
                    System.out.println(endIntervalFirstRange);
                    
                    
                    //there will be no overlap
                    //this is straight forward....
                    System.out.println("START FIRST INTERVAL: " + startIntervalFirstRange);
                    if (Integer.valueOf(startIntervalFirstRange)>Integer.valueOf(endNewInterval))
                    {
                        newInterval = "["+startIntervalFirstRange+","+ " " + endIntervalFirstRange+"]";
                        innerList.add(newInterval);
                        System.out.println("2Added into Inner List: " + newInterval);
                    }
                    //overlap
                    //NOTE: We are not considering any cases where the end interval is identical to start of next range...
                    //Data would be exempt from this. Hence else statement
                    
                    else
                    {
                        //remove last item in inner
                        //this is where it gets tricky... What is the startNumber of the range
                        
                        //So far we know counter is 3.
                        //so lets assume we were presented with
                        //{1,3},{2,6},{5,4}
                        
                        //The innerList would currently be  {1,6},  
                        //in a view to merge {5,4}
                        
                        //before removing lastItem from innerlist, need to get start for the last range in there...
                        
                        Object lastItemInnerList = innerList.get(innerList.size()-1);
                        System.out.println("Last item inner list: " + lastItemInnerList);
                        
                        String startInterval = String.valueOf(lastItemInnerList).substring(1,String.valueOf(lastItemInnerList).indexOf(","));
                        System.out.println("STARTINTERVAL: " + startInterval);
                        
                        //remove last item
                        System.out.println("Removed last item from innerList: " + innerList.get(innerList.size()-1));
                        
                        innerList.remove(innerList.size()-1);
                        
                        //we are using endIntervalFirstRange since this was our choice of storage location!
                        newInterval = "["+startInterval+","+ " " + endIntervalFirstRange+"]";
                        innerList.add(newInterval);
                        System.out.println("3Added into Inner List: " + newInterval);
                        System.out.println("This is innerlist: " + innerList);
                    }
                }
                
                if (counter<=2)
                {
                    if (counter==1)
                    {
                        startIntervalFirstRange = range.substring(1, range.indexOf(","));
                        System.out.println(startIntervalFirstRange);
                        endIntervalFirstRange = range.substring(range.indexOf(" ")+1,range.indexOf("]"));
                        System.out.println(endIntervalFirstRange);
                    }
                
                    if (counter==2)
                    {
                        startIntervalSecondRange = range.substring(1, range.indexOf(","));
                        System.out.println(startIntervalSecondRange);
                        endIntervalSecondRange = range.substring(range.indexOf(" ")+1,range.indexOf("]"));
                        System.out.println(endIntervalSecondRange);
                    
                        if (Integer.valueOf(endIntervalFirstRange)>=Integer.valueOf(startIntervalSecondRange))
                        {
                            newInterval = "["+startIntervalFirstRange+","+ " " + endIntervalSecondRange+"]";
                            innerList.add(newInterval);
                            System.out.println("4Added into Inner List: " + newInterval);
                            System.out.println("4*****THE INNERLIST: " + innerList);
                    
                            //no need to worry about values in any of the variables so they can be emptied:
                    
                            startIntervalFirstRange="";
                            endIntervalFirstRange="";
                            startIntervalSecondRange="";
                            endIntervalSecondRange="";
                        }
                        else
                        {
                            innerList.add("["+startIntervalFirstRange+","+ " " + endIntervalFirstRange+"]");
                            System.out.println("5Added into Inner List: " + "["+startIntervalFirstRange+","+ " " + endIntervalFirstRange+"]");
                    
                            innerList.add("["+startIntervalSecondRange+","+ " " + endIntervalSecondRange+"]");
                            System.out.println("6Added into Inner List: " + "["+startIntervalSecondRange+","+ " " + endIntervalSecondRange+"]");
                    
                            System.out.println("*****THE INNERLIST: " + innerList);
                            newInterval = "["+startIntervalSecondRange+","+ " " + endIntervalSecondRange+"]";
                        }
                    }
                }
            }
        }
        
        //the final step would be to add the innerList into the outerList
        outerList.add(innerList);
        
        return outerList;
    }
}