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

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

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;
    }
};