#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

typedef struct {
    long long value;   // element value
    int stream;        // which stream it belongs to
    int index;         // position inside the stream
    long long ready;   // earliest time this stream can be used again
} Node;

// Min-heap by (value, ready time)
typedef struct {
    Node *arr;
    int size;
    int capacity;
} MinHeap;

void swap(Node *a, Node *b) {
    Node temp = *a;
    *a = *b;
    *b = temp;
}

MinHeap* createHeap(int capacity) {
    MinHeap heap = (MinHeap)malloc(sizeof(MinHeap));
    heap->arr = (Node*)malloc(capacity * sizeof(Node));
    heap->size = 0;
    heap->capacity = capacity;
    return heap;
}

void heapify(MinHeap *heap, int i) {
    int smallest = i;
    int left = 2*i + 1;
    int right = 2*i + 2;

    if (left < heap->size && heap->arr[left].value < heap->arr[smallest].value)
        smallest = left;
    if (right < heap->size && heap->arr[right].value < heap->arr[smallest].value)
        smallest = right;

    if (smallest != i) {
        swap(&heap->arr[i], &heap->arr[smallest]);
        heapify(heap, smallest);
    }
}

Node extractMin(MinHeap *heap) {
    Node root = heap->arr[0];
    heap->arr[0] = heap->arr[heap->size - 1];
    heap->size--;
    heapify(heap, 0);
    return root;
}

void insertHeap(MinHeap *heap, Node item) {
    int i = heap->size++;
    heap->arr[i] = item;
    while (i != 0 && heap->arr[(i-1)/2].value > heap->arr[i].value) {
        swap(&heap->arr[i], &heap->arr[(i-1)/2]);
        i = (i-1)/2;
    }
}

int main() {
    int K, D;
    if (scanf("%d %d", &K, &D) != 2) return 0;

    int sizes = (int)malloc(K * sizeof(int));
    long long *streams = (long long)malloc(K * sizeof(long long));

    // Read streams
    for (int i = 0; i < K; i++) {
        scanf("%d", &sizes[i]);
        streams[i] = (long long*)malloc(sizes[i] * sizeof(long long));
        for (int j = 0; j < sizes[i]; j++) {
            scanf("%lld", &streams[i][j]);
            if (streams[i][j] < 0) {
                printf("Invalid input\n");
                return 0;
            }
        }
    }

    MinHeap *heap = createHeap(100000);
    long long ready = (long long)calloc(K, sizeof(long long));

    // Initialize heap with first element of each stream
    for (int i = 0; i < K; i++) {
        if (sizes[i] > 0) {
            Node node = { streams[i][0], i, 0, 0 };
            insertHeap(heap, node);
        }
    }

    long long currentTime = 0;

    while (heap->size > 0) {
        Node minNode = extractMin(heap);

        // Ensure stream is ready
        if (currentTime < ready[minNode.stream])
            currentTime = ready[minNode.stream];

        printf("%lld ", minNode.value);
        currentTime++;

        // Update ready time for this stream
        ready[minNode.stream] = currentTime + D;

        // Push next element from this stream if available
        if (minNode.index + 1 < sizes[minNode.stream]) {
            Node next = { streams[minNode.stream][minNode.index + 1],
                          minNode.stream,
                          minNode.index + 1,
                          ready[minNode.stream] };
            insertHeap(heap, next);
        }
    }

    printf("\n");
    return 0;
}