#pragma once
#include <vector>
#include <algorithm>

class Set {
 private:
  std::vector<int64_t> set;
 public:
  explicit Set(const std::vector<int64_t>& s = { }) {
	  for (int64_t k : s) {
		  if (std::find(set.begin(), set.end(), k) == set.end()) {
			  set.push_back(k);
			  sort(set.begin(), set.end());
		  }
	  }
  }

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