#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef unsigned int    U16;
typedef          char   C08;

#define NUM_STR_MAX       11                                     // Contain '\0'
#define OPE_STR_MAX       (NUM_STR_MAX + 7)
#define OPE_COUNT_MAX 2000000
#define INPUT_NUM_MIN 0
#define INPUT_NUM_MAX 2000000000
#define QUEUE_TOP_IDX 0

static void Insert_Num_Void(U16 *U16_Queue_p, U16 *U16_MaxNumIdx, U16 *U16_QueueEndIdx, U16 U16_InputNum);              // Function of insert the num to queue
static void Extract_Num_Void(U16 *U16_Queue_p, U16 *U16_MaxNumIdx, U16 *U16_QueueEndIdx);       // Function of extract the maximum num of queue


/***********************************************************************************
 ++module <main>
 ++outline
        main function
 ++arguments
        <>                      <>                                      []
 ++supp
         <return>
           nothing
 ++end_module
************************************************************************************/
int main(void)
{
        // Valiable declaration
        C08 C08_OpeStr[OPE_STR_MAX]   = {'\0'}; // Operation string ("insert XX", "extract", "end")
        C08 C08_InputNum[NUM_STR_MAX] = {'\0'}; // Input num(C08)
        U16 U16_InputNum    = 0;                                // Input num(U16)
        U16 *U16_Queue_p;                                               // Queue
        U16 U16_MaxNumIdx   = QUEUE_TOP_IDX;    // Max num index of queue
        U16 U16_QueueEndIdx = QUEUE_TOP_IDX;    // Index of queue end
        C08 *C08_IsOpeStrMatch_p;                               // Check the Operation
        U16 U16_i = 0;                                                  // Loop valiable
        
        // Get malloc
        U16_Queue_p = (U16 *)malloc(sizeof(U16) * OPE_COUNT_MAX);
        if(NULL == U16_Queue_p)
        {
                return 1;
        }
        
        // Initialize the queue
        for(U16_i = 0; U16_i < OPE_COUNT_MAX; U16_i++)
        {
                U16_Queue_p[U16_i] = 0;
        }
        // memset(&U16_Queue_p, OPE_COUNT_MAX, 0);
        U16_i = 0;
        
        // Input the operation
        while(U16_i < OPE_COUNT_MAX)
        {
                fgets(C08_OpeStr, OPE_STR_MAX, stdin);
                
                if( NULL != ( C08_IsOpeStrMatch_p = strstr(C08_OpeStr, "insert") ) )                    // Insert the num
                {
                        // Get the number from "C08_OpeStr"
                        strncpy(C08_InputNum, C08_OpeStr + (OPE_STR_MAX - NUM_STR_MAX), NUM_STR_MAX);
                        U16_InputNum = atoi(C08_InputNum);
                        
                        // If the input num is out of the range, do nothing
                        if(INPUT_NUM_MAX < U16_InputNum)
                        {
                                
                        }
                        else
                        {
                                // Insert the num
                                Insert_Num_Void(&U16_Queue_p[QUEUE_TOP_IDX], &U16_MaxNumIdx, &U16_QueueEndIdx, U16_InputNum);
                        }
                }
                else if( NULL != ( C08_IsOpeStrMatch_p = strstr(C08_OpeStr, "extract") ) )              // Extract the num
                {
                        // If the queue is empty, do nothing
                        if(QUEUE_TOP_IDX == U16_QueueEndIdx)
                        {
                                
                        }
                        else
                        {
                                // Extract the num
                                Extract_Num_Void(&U16_Queue_p[QUEUE_TOP_IDX], &U16_MaxNumIdx, &U16_QueueEndIdx);
                        }
                }
                else if( NULL != ( C08_IsOpeStrMatch_p = strstr(C08_OpeStr, "end") ) )                  // End
                {
                        break;
                }
                else
                {
                        // Do nothing
                }
                
                // Reset the operation string
                memset(&C08_OpeStr[0], '\0', sizeof(C08_OpeStr));
                U16_i++;
        }
        
        // Release the queue
        free(U16_Queue_p);
        
        return 0;
}

/***********************************************************************************
 ++module <Insert_Num_Void>
 ++outline
        Insert the num to queue
 ++arguments
        <U16>   <U16_Queue_p>           [Queue]
        <U16>   <U16_MaxNumIdx>         [Index of maximim num]
        <U16>   <U16_QueueEndIdx>       [Index of queue end]
        <U16>   <U16_InputNum>          [Input num]
 ++supp
         <return>
           nothing
 ++end_module
************************************************************************************/
static void Insert_Num_Void(U16 *U16_Queue_p, U16 *U16_MaxNumIdx, U16 *U16_QueueEndIdx, U16 U16_InputNum)
{
        U16_Queue_p[*U16_QueueEndIdx] = U16_InputNum;                   // Insert the num
        
        // Update the max num
        if(U16_InputNum > U16_Queue_p[*U16_MaxNumIdx])
        {
                *U16_MaxNumIdx = *U16_QueueEndIdx;
        }
        
        // Update the end index
        (*U16_QueueEndIdx)++;
//        *U16_QueueEndIdx += sizeof(U16);
        
        return;
}


/***********************************************************************************
 ++module <Extract_Num_Void>
 ++outline
        Extract the maximum num of queue
 ++arguments
        <U16>   <U16_Queue_p>           [Queue pointer]
        <U16>   <U16_MaxNumIdx>         [Index of maximim num]
        <U16>   <U16_QueueEndIdx>       [Index of queue end]
 ++supp
         <return>
           nothing
 ++end_module
************************************************************************************/
static void Extract_Num_Void(U16 *U16_Queue_p, U16 *U16_MaxNumIdx, U16 *U16_QueueEndIdx)
{
        U16 U16_i;
        
        printf("%d\n", U16_Queue_p[*U16_MaxNumIdx]);                           // Disp the max num
        
        // Update the queue
        U16_i = (*U16_MaxNumIdx) + 1;
//        U16_i = (*U16_MaxNumIdx) + sizeof(U16);
        while(1)
        {
                U16_Queue_p[U16_i - 1] = U16_Queue_p[U16_i];
//                U16_Queue_p[U16_i - sizeof(U16)] = U16_Queue_p[U16_i];
                
                if(U16_i == *U16_QueueEndIdx)
                {
                        // Update queue end
                        U16_Queue_p[U16_i] = 0;
                        (*U16_QueueEndIdx)--;
//                        *U16_QueueEndIdx -= sizeof(U16);
                        break;
                }
                U16_i++;
        }
        
        // Update the maximim num
        *U16_MaxNumIdx = QUEUE_TOP_IDX;
        U16_i          = (*U16_MaxNumIdx) + 1;
//        U16_i          = (*U16_MaxNumIdx) + sizeof(U16);
        
        while(1)
        {
                if(U16_Queue_p[U16_i] > U16_Queue_p[*U16_MaxNumIdx])
                {
                        *U16_MaxNumIdx = U16_i;
                }
                
                // If "U16_i" is "U16_QueueEndIdx", break
                // If "U16_i" is not "U16_QueueEndIdx", update "U16_i"
                if(U16_i == *U16_QueueEndIdx)
                {
                        break;
                }
                else
                {
                        U16_i++;
//                        U16_i += sizeof(U16);
                }
        }
        
        return;
}


/*
insert 8
insert 2
extract
insert 10
extract
insert 11
extract
extract
end
*/
