#include <iostream>
#include <vector>
#include <string>
using namespace std;
 
bool UpdateCombination (std::vector<int> &comboindices, int count, int n)
{
    for (int i = 1; i <= n; ++i)
	{
		if (comboindices[n - i] < count - i)
		{
			++comboindices[n - i];
			for (int j = n - i + 1; j < n; ++j)
			{
				comboindices[j] = comboindices[j-1] + 1;
			}
			return false;
		}
	}
	return true;
}

void ResetCombination (std::vector<int> &comboindices, int n)
{
	comboindices.resize(n);
	for (int i = 0; i < n; ++i)
	{
		comboindices[i] = i;
	}
}

void PrintArrays (const std::vector<std::vector<std::string>> items, int count)
{
    std::vector<std::vector<int>> indices;
    int n = items.size();
    indices.resize(items.size());

	for(auto i = indices.begin (); i != indices.end (); ++i)
	{
		ResetCombination((*i),count);
	}
        
    while (true) //Iterate until we've used all of the last array of items
    {
			for (int i = 0; i < n; ++i)
			{
				cout << "{";
				for (auto j = indices[i].begin (); j != indices[i].end (); ++j)
				{
					int ji = (*j);
					cout << (items[i])[ji] << " ";
				}
				cout << "} ";

			}
			cout << endl;
                
            //Update to the next indice
            for (int i = n - 1; i >= 0; --i)
            {
					bool done = UpdateCombination (indices[i],items[i].size(),count);
                    if (!done)
                    {
                            break;
                    }
                    else if (done && i == 0)
                    {
                        return; //Escape.
                    }
					else
					{
						ResetCombination(indices[i],count);
					}
            }
    }
        
}
 //{A,B,C,D},{A,B},{A,B},{A,B,C,D,E,F},{A,B}


int main() {
        
    vector<vector<string>> lists;
    lists.resize(5);
    lists[0].push_back("A");
	lists[0].push_back("B");
	lists[0].push_back("C");
	lists[0].push_back("D");

    lists[1].push_back("A");
    lists[1].push_back("B");

    lists[2].push_back("A");
    lists[2].push_back("B");

    lists[3].push_back("A");
    lists[3].push_back("B");
	lists[3].push_back("C");
    lists[3].push_back("D");
	lists[3].push_back("E");
	lists[3].push_back("F");

    lists[4].push_back("A");
	lists[4].push_back("B");
    
    
    
    PrintArrays(lists,2);
    return 0;
}