int maxProduct(vector<string>& words) {
        CreateBitmask();

        int Ans = 0;

        vector<int> vec;
        for(int i = 0; i < words.size(); ++i)
        {
            int x = 0;
            for(int j = 0; j < words[i].length(); ++j)
            {
                int alpha = words[i][j] - 'a';
                x |= arr[alpha];
            }
            vec.push_back(x);
        }

        for(int i = 0; i < vec.size(); ++i)
        {
            for(int j = i + 1; j < vec.size(); ++j)
            {
                if((vec[i] & vec[j]) == 0)
                {
                    int Union = words[i].length() * words[j].length();
                    if(Union > Ans)
                        Ans = Union;
                }
            }
        }

        return Ans;
    }
/*   CheckMaxEventSet

     Search the eventset with the maximum events added.
     Uses a bitmask to generate all the possible combinations.
*/
void CheckMaxEventSet (int ncounters, unsigned *counters)
{
	int i;
	int j;
	int k;
	int rc;
	int *bitmask;
	int **maxs;
	int nmaxs;
	char EventName[PAPI_MAX_STR_LEN];

	bitmask = CreateBitmask (ncounters);
	nmaxs = 0;
	maxs = NULL;

	do
	{
		Bitmask_NextValue (bitmask, ncounters);
		if (CheckBitmapCounters (ncounters, counters, bitmask))
		{
			if (nmaxs > 0)
			{
				/* This set has more counters than the rest of sets.
				   Remove them and add this one! */
				if (Bitmask_CountActiveBits (bitmask, ncounters) > Bitmask_CountActiveBits (maxs[0], ncounters))
				{
					int i;
					for (i = 0; i < nmaxs; i++)
						free (maxs[i]);

					maxs = (int **) realloc (maxs, (sizeof(int*)));
					if (maxs == NULL)
					{
						fprintf (stderr, "Error! Cannot re-allocate memory for maximum eventsets\n");
						exit (-6);
					}
					maxs[0] = CreateBitmask (ncounters);
					Bitmask_Copy (bitmask, maxs[0], ncounters);
					nmaxs = 1;
				}
				/* This set has the same number of counters than maximum set. Add it */
				else if (Bitmask_CountActiveBits (bitmask, ncounters) == Bitmask_CountActiveBits (maxs[0], ncounters))
				{
					maxs = (int **) realloc (maxs, ((nmaxs+1)*sizeof(int*)));
					if (maxs == NULL)
					{
						fprintf (stderr, "Error! Cannot re-allocate memory for maximum eventsets\n");
						exit (-6);
					}
					maxs[nmaxs] = CreateBitmask (ncounters);
					Bitmask_Copy (bitmask, maxs[nmaxs], ncounters);
					nmaxs++;
				}
			}
			else
			{
				maxs = (int **) malloc (sizeof(int*));
				if (maxs == NULL)
				{
					fprintf (stderr, "Error! Cannot allocate memory for maximum eventsets\n");
					exit (-6);
				}
				maxs[0] = CreateBitmask (ncounters);
				Bitmask_Copy (bitmask, maxs[0], ncounters);
				nmaxs = 1;
			}
		}
	}
	while (!Bitmask_isLastValue(bitmask, ncounters));

#if 0
	fprintf (stdout, "** Number of combinations found: %d\n", nmaxs);
	fprintf (stdout, "** Maximum events placed per combination: %d\n", Bitmask_CountActiveBits (maxs[0], ncounters));
#endif

	fprintf (stdout, "Combinations maximizing the number of compatible counters:\n");
	for (k = 0; k < nmaxs; k++)
	{
		fprintf (stdout, "* Combination #%d (set of %d): ", k+1, Bitmask_CountActiveBits (maxs[k], ncounters));
		for (j = 0, i = 0; i < ncounters; i++)
			if (maxs[k][i])
			{
				rc = PAPI_event_code_to_name (counters[i], EventName);
				if (rc == PAPI_OK)
					fprintf (stdout, "%s%s", j>0?",":"", EventName);
				else
					fprintf (stdout, "%s%08x", j>0?",":"", counters[i]);
				j++;
			}
		fprintf (stdout, "\n");
	}
}