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

using std::vector;

class Set {
 public:
vector<int64_t> v;

Set() = default;

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

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

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

Set Union(const Set& v) const {
vector<int64_t> un_v1 = this->Data();
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 {
vector<int64_t> un_v1 = this->Data();
vector<int64_t> un_v2 = v.Data();
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 {
vector<int64_t> un_v1 = this->Data();
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(remove(un_v1.begin(),
un_v1.end(), un_v2[i]), un_v1.end());
}
return un_v1;
}

Set SymmetricDifference(const Set& v) const {
vector<int64_t> un_v1 = this->Data();
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(remove(un_v1.begin(),
un_v1.end(), un_v2[i]), un_v1.end());
}
return un_v1;
}
};