#include #include struct Node { struct Node *l, *r; unsigned val; int track; int lcnt, rcnt; } node_pool[ 200000 ], *root, *sort[ 200000 ]; struct Car { unsigned val; struct Car *next; } car_pool[ 200000 ]; struct Track { struct Car *head, *tail; } tracks[ 200001 ]; int buffer[ 200000 ], bufsize; int balancePos; void fillNode( struct Node *node ) { if( node ) { fillNode( node->l ); sort[ balancePos ++ ] = node; fillNode( node->r ); } } struct Node *getMid( int l, int r ) { if( l == r ) return NULL; { int index = ( l + r ) / 2; struct Node *act = sort[ index ]; act->l = getMid( l, index ); act->r = getMid( index + 1, r ); act->lcnt = ( index - l ); act->rcnt = ( r - index - 1 ); return act; } } struct Node *balance( struct Node *n ) { balancePos = 0; fillNode( n ); return getMid( 0, balancePos ); } void nodeInsert( struct Node *n ) { struct Node **x; int d = 0; struct Node *disb = NULL, *parent = NULL; n->lcnt = n->rcnt = 1; x = &root; while( *x ) { if( n->val < (*x)->val ) { if( ( (*x)->lcnt ++ > (*x)->rcnt * 2 ) && ( (*x)->lcnt > 1 ) ) { disb = d ? disb : parent; d = 1; } parent = *x; x = &(*x)->l; } else { if( ( (*x)->rcnt ++ > (*x)->lcnt * 2 ) && ( (*x)->rcnt > 1 ) ) { disb = d ? disb : parent; d = 1; } parent = *x; x = &(*x)->r; } } /*if( d ) { if( disb ) { disb->l = balance( disb->l ); disb->r = balance( disb->r ); } else root = balance( root ); }*/ *x = n; } struct Node *getLowest() { struct Node *act = root; struct Node *parent = NULL; struct Node *disbalance = NULL; if( !act ) return NULL; while( act->l ) { if( ( 2 * act->lcnt -- < act->rcnt ) && ( !disbalance ) ) disbalance = parent; parent = act; act = parent->l; } if( parent ) parent->l = act->r; else root = root->r; /*if( disbalance ) disbalance->l = balance( disbalance->l );*/ return act; } void doInput( int N, int M ) { int i; int car_alloc = 0, node_alloc = 0, track_pos = 0; root = NULL; bufsize = 0; for( i = 0; i < N; ++ i ) { int best = 0; struct Node *act = root; unsigned car; scanf( "%u", &car ); while( act ) { if( act->val <= car ) { best = act->track; act = act->r; } else { act = act->l; } } if( best ) { struct Car *c = car_pool + ( car_alloc ++ ); c->next = NULL; c->val = car; tracks[ best ].tail->next = c; tracks[ best ].tail = c; buffer[ bufsize ++ ] = best; } else { struct Car *c = car_pool + ( car_alloc ++ ); struct Node *n = node_pool + ( node_alloc ++ ); if( track_pos == M ) { int j; printf( "Transportation failed\n" ); for( j = 0; j < N - i - 1; ++ j ) scanf( "%u", &car ); return; } best = ( ++ track_pos ); c->next = NULL; c->val = car; tracks[ best ].head = c; tracks[ best ].tail = c; n->val = car; n->track = best; n->l = n->r = NULL; nodeInsert( n ); buffer[ bufsize ++ ] = best; } } for( i = 0; i < bufsize; ++i ) printf( "%u%c", buffer[ i ], ( i == bufsize - 1 ) ? '\n' : ' ' ); root = NULL; node_alloc = 0; for( i = 1; i <= track_pos; ++i ) { struct Node *n = node_pool + ( node_alloc ++ ); n->val = tracks[ i ].head->val; n->track = i; n->l = n->r = NULL; nodeInsert( n ); } { struct Node *act; while( ( act = getLowest() ) ) { printf( "%i%c", act->track, ( root || tracks[ act->track ].head->next ) ? ' ' : '\n' ); if( tracks[ act->track ].head->next ) { tracks[ act->track ].head = tracks[ act->track ].head->next; act->val = tracks[ act->track ].head->val; act->l = act->r = 0; nodeInsert( act ); } } } } int main( int argc, char **argv ) { for( ;; ) { int M, N; scanf( "%i%i", &N, &M ); if( !M && !N ) return 0; doInput( N, M ); } return 0; }