
#include <iostream> 
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <fstream>
#include <strstream>
#include <sstream>
#include <utility>
#include <map>
#include <list>
#include <set>
#include <vector>
#include <iomanip>
#include <algorithm>
#include <iterator>
using namespace std;

int threshold = 3;
std::map <int, set<int>> Ls;
std::size_t Msize = 0, temp = 0;
std::size_t MCsize=0, temp2 = 0;
 
template <typename Iterator>
inline bool next_combination(const Iterator first, Iterator k, const Iterator last)
{
/* Credits: Thomas Draper */
if ((first == last) || (first == k) || (last == k))
return false;
Iterator itr1 = first;
Iterator itr2 = last;
++itr1;
if (last == itr1)
return false;
itr1 = last;
--itr1;
itr1 = k;
--itr2;
while (first != itr1)
{
if (*--itr1 < *itr2)
{
Iterator j = k;
while (!(*itr1 < *j)) ++j;
std::iter_swap(itr1, j);
++itr1;
++j;
itr2 = k;
std::rotate(itr1, j, last);
while (last != j)
{
++j;
++itr2;
}
std::rotate(k, itr2, last);
return true;
}
}
std::rotate(first, k, last);
return false;
}
 
 
 int main()
{
	 std::vector<std::vector<int>> data =
{
{1, 2, 3, 4, 5},
{1, 3, 4, 5},
{1, 2, 3, 5},
{1, 3}
};

/*
in my program, I calculte Msize as:
Msize = std::distance(std::istream_iterator<std::string>(Sline1),
			std::istream_iterator<std::string>());

		if (temp > Msize)
			Msize = temp;
		else
			temp = Msize;
*/
Msize =5; 
	int j = 0;
	std::size_t k = 0;
	std::map<std::set<int>, int> counts;

	for (std::size_t Lsize = 1; Lsize <= Msize; ++Lsize)
	{
		for (unsigned i = 0; i < data.size(); ++i)
		{
			//std::size_t k = std::min(Lsize, data[i].size());
			if (Lsize >  data[i].size())
				continue;
			else
				 k = Lsize;

			do
			{
				std::set<int> n_k(data[i].begin(), data[i].begin() + k);

				if (Ls.size() != 0)
				{
					std::map <int, set<int>> ::iterator ls2 = Ls.begin();

					while (ls2 != Ls.end())
					{
						if (std::includes(n_k.begin(), n_k.end(), ls2->second.begin(), ls2->second.end()))
						{
							++j;
							Ls[j].insert(n_k.begin(), n_k.end());
							goto ncom;
						}
						else
						++ls2;
					}
				}
					++counts[n_k];
				ncom:
					cout << ""; // If I don't put this statement  I will get error: missing {
			} while (next_combination(data[i].begin(), data[i].begin() + k, data[i].end()));

		}


		MCsize = counts.size();
		if (temp2 == MCsize) // check if counts don't have more supset > threshold, then no needs to generate  more superset
			goto stop;
		else
			temp2 = MCsize;

		std::map<std::set<int>, int> ::iterator current = counts.begin();
		
		while (current != counts.end())
		{
			if (current->second < threshold)
			{
				Ls[j].insert(current->first.begin(), current->first.end());
				current = counts.erase(current);
				++j;
			}
			else
				++current;
		}

		}


	stop:
	for (const auto& p : counts)
	{
		std::cout << "{";
		for (auto e : p.first) {
			std::cout << e << " ";
		}
		std::cout << "} = " << p.second << std::endl;
	}

		
	data.clear();

	



	
	return 0;
}



