#pragma once

#include <vector>
#include <algorithm>

class Set {
 private:
    std::vector<int64_t> set;
    
 public:
    explicit Set(const std::vector<int64_t> &s = {}) : set(s) {
    }

    void Add(int64_t num) {
        if (!(std::find(set.begin(), set.end(), num) != set.end())) {
            set.push_back(num);
            sort(set.begin(), set.end());
        }
    }

    void Remove(int64_t num) {
        auto it = std::find(set.begin(), set.end(), num);
        if (it != set.end())
            set.erase(it);
    }

    bool Contains(int64_t num) const {
        return std::find(set.begin(), set.end(), num) != set.end();
    }

    Set Union(const Set &s) const {
        Set setter;
        for (int64_t k : set)
            setter.Add(k);
        for (int64_t k : s.set)
            setter.Add(k);
        return setter;
    }

    Set SymmetricDifference(const Set &s) const {
        Set setter;
        for (int64_t k : s.set) {
            if (!(std::find(set.begin(), set.end(), k) != set.end())) {
                setter.Add(k);
            }
        }
        for (int64_t k : set) {
            if (!(std::find(s.set.begin(), s.set.end(), k) != s.set.end())) {
                setter.Add(k);
            }
        }
        return setter;
    }

    Set Difference(const Set &s) const {
        Set setter;
        for (int64_t k : set) {
            if (!(std::find(s.set.begin(), s.set.end(), k) != s.set.end())) {
                setter.Add(k);
            }
        }
        return setter;
    }

    Set Intersection(const Set &s) const {
        Set setter;
        for (int64_t k : s.set) {
            if ((std::find(set.begin(), set.end(), k) != set.end())) {
                setter.Add(k);
            }
        }
        return setter;
    }

    std::vector<int64_t> Data() const {
        return set;
    }
};