#include <cstring>
#include <iostream>
#include <fstream>
#include <sstream>
#include <unordered_set>

#define UNSYNC
//#define UNTIE

int main(int argc,char *argv[])
{
    std::ifstream in("list.txt", std::ios::binary);
    std::ofstream out("nodup.txt", std::ios::binary);

    //std::cin.rdbuf(in.rdbuf());
    //std::cout.rdbuf(out.rdbuf());

#ifdef UNTIE
    {
        static std::ostringstream dummy;
        std::cin.tie(&dummy); // there ain't no untie() !?
    }
#endif

#ifdef UNSYNC
    std::ios_base::sync_with_stdio(false);
#endif

    struct Key
    {
        size_t operator()(char const *p) const
        {
            unsigned long hash = 5381;
            while (int c = *p++)
                hash = ((hash << 5) + hash) + c;
            // see http://www.cse.yorku.ca/~oz/hash.html
            return hash;
        }
    };

    struct Equal
    {
        bool operator()(char const *p,char const *q) const
        {
            return 0 == strcmp(p,q);
        }
    };

    std::unordered_set<char const*,Key,Equal> S;

    char buffer[0x10000]; // extent if needed or make it dynamic if you like

    while (in.getline(buffer,sizeof(buffer)))
    {
        S.clear();
        size_t n = 0;
        auto p = buffer;
        auto q = p;
        while (*q != '\0')
        {
            if (*q == ';')
            {
                *q++ = '\0';
                if (n<3 || S.insert(p).second)
#ifdef FSTREAM
                    fputs(p,stdout);
#else
                out << p;
#endif

#if defined FSTREAM
                fputc(';',stdout);
#elif defined PUTCHAR
                out.put(';');
#else
                out << ';';
#endif
                p = q;
                ++n;
            }
            else ++q;
        }
        if (n<3 || S.insert(p).second)
#ifdef FSTREAM
            fputs(p,stdout);
#else
        out << p;
#endif

#if defined FSTREAM
        fputc('\n',stdout);
#elif defined PUTCHAR
        out.put('\n');
#else
        out << '\n';
#endif
    }
    if (!in.eof())
    {
        std::cerr << "line probably too long (please extend buffer size)\n";
        exit(1);
    }
    return 0;
}
