import java.util.*;
public class Solution 
{
    public static void main (String[] args)
    {
        List<List<Object>> intervals = new ArrayList<>();
            
        List<Object> entries = new ArrayList<>();
        
               //I will create all my test cases again and keep it simple.
        //and build my code outwards...
        // I need to first have a road map of what the purpose is....
        //Also need to create meaningful variable names so that a non-technical person
        //can understand the semantics
        //Having read online, the interval is defined as the entire contents [X,X]
        
        //These are commercial and non-commercial uses.
        //I understand there is lots references to sorting the intervals first in ascending order by start time.
        //This would largely vary on the application use.
        //For applications such as an array with items based chronologically, performing similar action would defy purpose altogether...
        //I am still largely keen to tackle merging intervals for financial analysis.
        //But I strongly need to understand the real life requirements otherwise will end up looping like previously...
        //Financial Analysis: Merging time periods for stock price analysis.
        
        //These are all uses identified online:
        //Calendar Management: Automatically merging overlapping events in your calendar app.
        //Resource Allocation: Optimizing the use of shared resources like conference rooms.
        //Network Intervals: Merging time slots for network usage to avoid congestion.
        //Job Scheduling: Merging job intervals in operating systems to improve efficiency.
        //Data Compression: Merging ranges in data sets to reduce storage space.
        //Traffic Management: Merging traffic intervals to optimize flow on busy roads.
        //Event Planning: Merging overlapping event schedules for better organization.
        //Game Development: Merging time intervals for character animations.
        //Healthcare: Merging patient appointment slots to maximize doctor availability.
        
        
        //TEST CASE 1:
        //entries.add("[1, 3]");
        //EXPLAINING IMPACT ON VARIABLES: I am doing this so in future, if the code is used
        //for any of the purposes above, there is full clarity.
        //To support this process, I have included an output of all variables at each point when it writes
        //into the innerList.... This is ONLY way to define requirements clearly....
        
        //SCENARIO 1
        //It will identify numberObjects==1 and populate startIntervalFirstRange(1), endIntervalFirstRange(2)
        //and also interval [1,3].   And add [1,3] into the innerList.
        //It will populate the lastItemInnerList variable since numberObjects==1
        
        //SCENARIO 3
        //At this point, the counter is 1, so it has performed same calculation to obtain startIntervalFirstRange
        //and endIntervalFirstRange using substring from range(this is the object s taken from the objects contained in the intervals).
        //No writes into the innerList
        //NOTE: startInterval and endInterval are not configured.. This will be explained later...
        
        //And finally it writes the innerList into OuterList
        
        //TEST CASE 2:
        //entries.add("[1, 3]");
        //entries.add("[4, 5]");
        //EXPLAINING IMPACT ON VARIABLES: I am doing this so in future, if the code is used
        //SCENARIO 3
        //At this point counter is 1, so it will populate startIntervalFirstRange and startIntervalSecondRange.
        //No writes to the innerList...
        //SCENARIO 4
        //It is here since counter==2.  Since nothing has been written innerList, another set variables store
        //startIntervalSecondRange=4,  endIntervalSecondRange=5
        //other variables already configured are:    startIntervalFirstRange=1   endIntervalFirstRange=3
        
        //                                             3                                       4 
        //it performs check as follows:   endIntervalFirstRange)>=Integer.valueOf(startIntervalSecondRange)
        //It can be seen there is no merge applicable,
        //so it simply places  [1,3] and  [4,5] into the innerList
        //it configures lastItemInnerList to be [4,5]
        
        //Note: there are no constraints on numberObjects with exception of 1 since it has to be handled differently.
        //and ALWAYS stored into innerList
        
        //it configures the newInterval to be [4,5] on the basis of incoming objects...
        //                             4                                   5             
        //newInterval = "["+startIntervalSecondRange+","+ " " + endIntervalSecondRange+"]";
        //NOTE: startInterval and endInterval are not configured.. This will be explained later...
        
        //And finally it writes the innerList into OuterList
         
         
        //TEST CASE 3 
        entries.add("[1, 3]");
        entries.add("[4, 5]");
        entries.add("[5, 6]");
        //SCENARIO 3
        //At this point counter is 1, so it will populate startIntervalFirstRange and startIntervalSecondRange.
        //No writes to the innerList...
        //SCENARIO 4
        //counter ==2... Store  startIntervalSecondRange=4, endIntervalSecondRange=5
        //                                3                     4     (NO MERGE) 
        //perform comparision  endIntervalSecondRange>=startIntervalSecondRange
        //Store  [1,3], [4,5] into innerList
        //populate lastItemInnerList
        // populate newInterval  [4,5].
        //This is also same as lastItemInnerList
        //Again NOTE: No intervention with startInterval or endInterval
        //I have created new variable newInterval since we do not know what the lifecycle of
        //startIntervalSecondRange[4] and endIntervalSecondRange[5] will be 
        
        //SCENARIO 2
        //This is first point where counter>2.  It is currently processing object  [5,6]
        //I have introduced new variable here since it is very confusing working with
        //startIntervalFirstRange/endIntervalFirstRange and startIntervalSecondRange/endIntervalSecondRange
        //We know newInterval is [4,5]
        //I created another new variable endNewInterval to extract 5 from [4,5]
        
        
        //it obtains startIntervalFirstRange and endIntervalFirstRange from the incoming object.
        //It performs a compare against
       //                              5                                         5    
       //if (Integer.valueOf(startIntervalFirstRange)>Integer.valueOf(endNewInterval))
       //we know this is not the case, so it performs a merge  [4,5], [5,6]  into [4,6]
       //We know the current innerList is   [1,3],[4,5]  since it processed this when counter ==2
       //So we need to remove [4,5] and replace it with merged interval [4,6]
        
        
        
        
        
        
        intervals.add(entries);
            
        System.out.println("Final outer list: " + mergeIntervals(intervals));
    }
    
    public static List<List<Object>> mergeIntervals(List<List<Object>> intervals) 
    {
        List<List<Object>> outerList = new ArrayList<>();

        List<Object> innerList = new ArrayList<>();

        int counter=0;
        
        String newInterval="";
        
        int numberObjects=0;
        String range;
        Object lastItemInnerList="";
        String lastItemInnerListString = "";
                
        String startIntervalFirstRange="";
        String endIntervalFirstRange="";
        
        String startIntervalSecondRange="";
        String endIntervalSecondRange="";
        String startInterval="";
        String endInterval="";
        
        Iterator<List<Object>> it = intervals.iterator();

        for (List <Object> tt: intervals)
        {  
              for (Object s:tt)
            {
                numberObjects++;
            }
            
            for (Object s:tt)
            {
                counter++;
                System.out.println("\nTHIS IS OBJECT: " + s +  " Counter: " + counter);
                    
                range = String.valueOf(s);
                
                if (numberObjects==1)
                {
                    startIntervalFirstRange = range.substring(1, range.indexOf(","));
                    
                    endIntervalFirstRange = range.substring(range.indexOf(" ")+1,range.indexOf("]"));
                    
                    newInterval = "["+startIntervalFirstRange+","+ " " + endIntervalFirstRange+"]";
                    innerList.add(newInterval);
                    System.out.println("1Added into innerlist: " + innerList);
                    
                    lastItemInnerList = innerList.get(innerList.size()-1);
                    lastItemInnerListString = String.valueOf(lastItemInnerList);
                    
                    System.out.println("*******SCENARIO 1****************************************");        
System.out.println ("Last item innerlist: " + lastItemInnerList);        
System.out.println("start interval: " + startInterval);
System.out.println("end interval: " + endInterval);
System.out.println("new interval: " + newInterval);
System.out.println("start interval second range: " + startIntervalSecondRange);
System.out.println("end interval second range: " + endIntervalSecondRange);
System.out.println("start interval first range: " + startIntervalFirstRange);
System.out.println("end interval first range: " + endIntervalFirstRange);
System.out.println("***********************************************");  
                    
                    
                }
                
                if (counter>2)
                {
                     
                    
                    String endNewInterval = newInterval.substring(newInterval.indexOf(" ")+1, newInterval.indexOf("]"));
                    
                    startIntervalFirstRange = range.substring(1, range.indexOf(","));
                    
                    endIntervalFirstRange = range.substring(range.indexOf(" ")+1,range.indexOf("]"));
                    
                    if (Integer.valueOf(startIntervalFirstRange)>Integer.valueOf(endNewInterval))
                    {
                        newInterval = "["+startIntervalFirstRange+","+ " " + endIntervalFirstRange+"]";
                        innerList.add(newInterval);
                        System.out.println("2Added into Inner List: " + newInterval);
                    }
                    
                    else
                    {
                        lastItemInnerList = innerList.get(innerList.size()-1);
                        lastItemInnerListString = String.valueOf(lastItemInnerList);
                        System.out.println("Last item inner list: " + lastItemInnerList);
                        
                        //startInterval = lastItemInnerListString.substring(1,lastItemInnerListString.indexOf(","));
                        //endInterval =  lastItemInnerListString.substring(lastItemInnerListString.indexOf(" ")+1,lastItemInnerListString.indexOf("]"));
                        
                        System.out.println("Removed last item from innerList: " + innerList.get(innerList.size()-1));
                        System.out.println(startIntervalFirstRange);
                        System.out.println(startIntervalSecondRange);
                        System.out.println(startIntervalSecondRange);
                        System.out.println(endIntervalSecondRange);
                        
                        innerList.remove(innerList.size()-1);
                        
                        newInterval = "["+startIntervalSecondRange+","+ " " + endIntervalFirstRange+"]";
                        innerList.add(newInterval);
                        System.out.println("3Added into Inner List: " + newInterval);
                        System.out.println("This is innerlist: " + innerList);
                    }
                    
                    System.out.println("*******SCENARIO 2****************************************");        
System.out.println ("Last item innerlist: " + lastItemInnerList);        
System.out.println("start interval: " + startInterval);
System.out.println("end interval: " + endInterval);
System.out.println("new interval: " + newInterval);
System.out.println("start interval second range: " + startIntervalSecondRange);
System.out.println("end interval second range: " + endIntervalSecondRange);
System.out.println("start interval first range: " + startIntervalFirstRange);
System.out.println("end interval first range: " + endIntervalFirstRange);
System.out.println("***********************************************");  
                }
                
                if (counter<=2)
                {
                    if (counter==1)
                    {
                        startIntervalFirstRange = range.substring(1, range.indexOf(","));
                        endIntervalFirstRange = range.substring(range.indexOf(" ")+1,range.indexOf("]"));
                        
                       
                        System.out.println("*******SCENARIO 3****************************************");       
System.out.println ("Last item innerlist: " + lastItemInnerList);        
System.out.println("start interval: " + startInterval);
System.out.println("end interval: " + endInterval);
System.out.println("new interval: " + newInterval);
System.out.println("start interval second range: " + startIntervalSecondRange);
System.out.println("end interval second range: " + endIntervalSecondRange);
System.out.println("start interval first range: " + startIntervalFirstRange);
System.out.println("end interval first range: " + endIntervalFirstRange);
System.out.println("***********************************************");  
                        
                    }
                
                    if (counter==2)
                    {
                        startIntervalSecondRange = range.substring(1, range.indexOf(","));
                        
                        endIntervalSecondRange = range.substring(range.indexOf(" ")+1,range.indexOf("]"));
                        
                        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);
                        }
                        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+"]";
                            
                            lastItemInnerList = innerList.get(innerList.size()-1);
                            lastItemInnerListString = String.valueOf(lastItemInnerList);
                        }
                        
                        System.out.println("*******SCENARIO 4****************************************");      
System.out.println ("Last item innerlist: " + lastItemInnerList);        
System.out.println("start interval: " + startInterval);
System.out.println("end interval: " + endInterval);
System.out.println("new interval: " + newInterval);
System.out.println("start interval second range: " + startIntervalSecondRange);
System.out.println("end interval second range: " + endIntervalSecondRange);
System.out.println("start interval first range: " + startIntervalFirstRange);
System.out.println("end interval first range: " + endIntervalFirstRange);
System.out.println("***********************************************");  
                        
                    }
                }
            }  //for objects inner loop
        }   //for objects outer loop
        
        outerList.add(innerList);
        

startIntervalFirstRange="";
endIntervalFirstRange="";
startIntervalSecondRange="";
endIntervalSecondRange="";        
        
        return outerList;
    }
}