#include <iostream>
#include <sstream>
#include <algorithm>
#include <cstdlib>
#include <cassert>
#include <random>
#include <thread>
#include <deque>
#include <mutex>
#include <condition_variable>
using namespace std;

int main() {
    vector<string> vec;

    mutex mtx;
    condition_variable got_something;

    thread t {
        [&]() {
            while (1) {
                unique_lock lck(mtx);  // lck's contructor will lock mtx

                while (vec.empty()) {
                    got_something.wait(lck);  // wait will release lck
                }
                // lck is reacquired when wait() returns

                for (const auto& x : vec) {
                    // exit thread on poison value
                    if (x == ""s) {
                        return;
                    }
                    cout << x << ' ';
                }
                cout << '\n';
                vec.clear();

                // lck's destructor will unlock mtx
            }
        }
    };

    string str, line;
    while (getline(cin, line)) {
        istringstream iss(line);

        unique_lock lck(mtx);  // lck's contructor will lock mtx

        while (iss >> str) { vec.push_back(str); }

        got_something.notify_one();  // unblock one waiting thread

        // lck's destructor will unlock mtx
    }

    {
        unique_lock lck(mtx);
        vec.push_back(""s);  // poison value to tell the thread to exit
        got_something.notify_one();
    }
    t.join();
}
