#pragma once

#include <vector>

class Set {
 private:
    std::vector<int64_t> set;

 public:
        explicit Set(const std::vector<int64_t> &vec) {
            this->set = vec;
        }
        Set() {}

        void Add(int64_t number) {
            bool present = false;
            for (int64_t i : set) {
                if (i == number) {
                    present = true;
                    break;
                }
            }
            if (!present) {
                this->set.push_back(number);
            }
        }

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

        bool Contains(int64_t number) const {
            for (int64_t i : this->set) {
                if (i == number) {
                    return true;
                }
            }
            return false;
        }

        Set Union(const Set& other) {
            for (int64_t i : other.set) {
                this->Add(i);
            }
            return *this;
        }


        Set Intersection(const Set& other) const {
            Set *intersection = new Set();
            for (int64_t i : this->set) {
                if (other.Contains(i)) {
                    intersection->Add(i);
                }
            }
            return *intersection;
        }

        Set Difference(const Set& other) const {
            Set *difference = new Set();
            for (int64_t i : this->set) {
                if (!other.Contains(i)) {
                    difference->Add(i);
                }
            }
            return *difference;
        }

        Set SymmetricDifference(const Set& other) const {
            Set *simdiff = new Set();
            for (int64_t i : this->set) {
                if (!other.Contains(i)) {
                    simdiff->Add(i);
                }
            }
            for (int64_t i : other.set) {
                if (!this->Contains(i)) {
                    simdiff->Add(i);
                }
            }
            return *simdiff;
        }
};