#include "bits/stdc++.h"

#define REP(i,x,y) for(int i=(x);i<(y);i++)
#define RREP(i,x,y) for(int i=(y)-1;i>=(x);i--)
#define all(x) (x).begin(),(x).end()
#define int long long

using namespace std;

// conversion
inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}

#ifdef LOCAL
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define dump(x)  cerr << #x << " = " << (x) << endl
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl
#else
#define eprintf(...) 42
#define dump(x) 42
#define debug(x) 42
#endif

typedef long long ll;

const ll MOD = 1e9 + 7;

struct Queue {
    Queue() {}
    Queue(int N) : s(vector<int>(N)), last(0) {}
    vector<int> s;
    int last;
};

void simulate(const int N, ll currentIndex, const ll limit, vector<int>& A, Queue& queue) {
    unordered_map<int, int> positions; // <number, position>
    unordered_map<int, int> numbers; // <position, number>

    while (currentIndex < limit) {
        const int a = A[currentIndex % N];
//        cout << "a:" << a << ", queue.last:" << queue.last << '\n';
        if (positions.find(a) != positions.end() && numbers[positions[a]] == a && positions[a] < queue.last) {
            queue.last = positions[a];
        } else {
            queue.s[queue.last] = a;
            positions[a] = queue.last;
            numbers[queue.last] = a;
            queue.last++;
        }
        currentIndex++;
//        REP(i,0,queue.last) {
//            cout << queue.s[i] << " ";
//        }
//        cout << "\n";
    }
}

vector<int> generateDistanceListToNextIndex(int N, vector<int>& A) {
    vector<int> list(N, 0);
    unordered_map<int, int> previousIndex; // <number, index>

    REP(i,0,2*N) {
//        debug(i);
        const int currentNumber = A[i%N];
        if (previousIndex.find(currentNumber) != previousIndex.end() && list[previousIndex[currentNumber] % N] == 0) {
            list[previousIndex[currentNumber] % N] = i - previousIndex[currentNumber];
//            debug(previousIndex[currentNumber]);
            assert(list[previousIndex[currentNumber] % N]>0);
        }
        previousIndex[currentNumber] = i;
    }

    REP(i,0,N) {
        if (list[i] == 0) list[i] = N;
    }

    return list;
}

void solve(int N, ll K, vector<int>& A) {
    Queue queue(N);

    ll currentIndex = 0;
    const ll limit = N * K;

    if (K > 1) {
        const auto distanceListToNextIndex = generateDistanceListToNextIndex(N, A);

        ll cycle = 0;
        vector<ll> visitedWhen(N, -1);

        const ll preLimit = N * (K-1);
        int count = 0;
        while (currentIndex < preLimit) {
            if (visitedWhen[currentIndex % N] != -1) {
                cycle = currentIndex - visitedWhen[currentIndex % N];
                break;
            }
            visitedWhen[currentIndex % N] = currentIndex;
            currentIndex += distanceListToNextIndex[currentIndex % N] + 1;
            count++;
//            assert(currentIndex >= 0);
        }

        if (cycle != 0 && currentIndex < preLimit) {
            currentIndex += (N * K - currentIndex) / cycle * cycle;
        }

        while (currentIndex < preLimit) {
            currentIndex += distanceListToNextIndex[currentIndex % N] + 1;
            count++;
        }
    }

//    assert(limit - currentIndex <= 2 * N);

    simulate(N, currentIndex, limit, A, queue);

    stringstream ss;
    REP(i,0,queue.last-1) {
        ss << queue.s[i] << " ";
    }
    if (queue.last != 0) ss << queue.s[queue.last-1];
    cout << ss.str() << '\n';
    return;
}

signed main() {
    ll N, K;
    cin >> N >> K;

    vector<int> A(N);
    REP(i,0,N) cin >> A[i];

    solve(N, K, A);

    return 0;
}


Measured memory_bytes: 19856