#pragma once
#include <iostream>
#include <vector>

class Set {
 public:
    std::vector<int64_t> v;

    explicit Set(const std::vector<int64_t>& v) {
        for (unsigned int i = 0; i < v.size(); i++)
            Add(v[i]);
    }

    Set() {
    }

    bool Contains(int64_t val) const {
        for (unsigned int i = 0; i < this->v.size(); i++)
            if (this->v[i] == val)
                return true;
        return false;
    }

    void Add(int64_t val) {
        if (Contains(val))
            return;
        this->v.push_back(val);
    }

    void Remove(int64_t val) {
        for (unsigned int i = 0; i < this->v.size(); i++) {
            if (this->v[i] == val)
                this->v.erase(this->v.begin() + i);
        }
    }

    std::vector<int64_t> Data() const {
        return this->v;
    }

    Set Union(const Set& v) const {
        std::vector<int64_t> un_v1 = this->Data();
        std::vector<int64_t> un_v2 = v.Data();
        for (unsigned int i = 0; i < un_v2.size(); i++) {
            if (!Contains(un_v2[i]))
                un_v1.push_back(un_v2[i]);
        }
        return un_v1;
    }

    Set Intersection(const Set& v) const {
        std::vector<int64_t> un_v1 = this->Data();
        std::vector<int64_t> un_v2 = v.Data();
        std::vector<int64_t> un_v3;
        for (unsigned int i = 0; i < un_v2.size(); i++) {
            if (Contains(un_v2[i]))
                un_v3.push_back(un_v2[i]);
        }
        return un_v3;
    }

    Set Difference(const Set& v) const {
        std::vector<int64_t> un_v1 = this->Data();
        std::vector<int64_t> un_v2 = v.Data();
        for (unsigned int i = 0; i < un_v2.size(); i++) {
            if (Contains(un_v2[i]))
                un_v1.erase(std::remove(un_v1.begin(),
                    un_v1.end(), un_v2[i]), un_v1.end());
        }
        return un_v1;
    }

    Set SymmetricDifference(const Set& v) const {
        std::vector<int64_t> un_v1 = this->Data();
        std::vector<int64_t> un_v2 = v.Data();
        for (unsigned int i = 0; i < un_v2.size(); i++) {
            if (!Contains(un_v2[i]))
                un_v1.push_back(un_v2[i]);
            else
                un_v1.erase(std::remove(un_v1.begin(),
                    un_v1.end(), un_v2[i]), un_v1.end());
        }
        return un_v1;
    }
};