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