//broj test Caseova
int numOfTestCases = int.Parse(Console.ReadLine());
while (numOfTestCases > 0)
{
string inputLineTwo = Console.ReadLine();
string[] inputs = inputLineTwo.Split(' ');
int N = Convert.ToInt32(inputs[0]);
int X = Convert.ToInt32(inputs[1]);
string inputLineThree = Console.ReadLine();
string[] arrayInputs = inputLineThree.Split(' ');
int[] arrayOfInt = new int[N];
for(int i = 0; i < arrayOfInt.Length; i++)
{
arrayOfInt[i] = int.Parse(arrayInputs[i]);
}
int[] output = GetFullInfo(arrayOfInt, X);
Console.WriteLine($"{output[0]} {output[1]}");
numOfTestCases--;
}
//vraca niz intova
int[] GetFullInfo(int[] arr, int x)
{
//na indexu 0 ce se cuvati maksimalan broj ponavljajucih elemenata u nizu
//na indexu 1 ce se cuvati minimalan broj operacija za taj broj elemenata u nizu
int[] output = new int[2];
//niz u koji se spasavaju vrijednosti nakon xor operacije
int[] arrayAfterOperations = new int[arr.Length];
for(int i = 0; i < arr.Length; i++)
{
arrayAfterOperations[i] = arr[i] ^ x;
//Console.WriteLine($"nova vrijednost: {arrayAfterOperations[i]}");
}
//niz u koji se smjestaju vrijednosti jednakih elemenata iz proslijedjenog niza
//i iz novog niza nakon xor operacije
int[] numOfEqual = new int[arr.Length];
for(int i = 0; i < arr.Length; i++)
{
numOfEqual[i] = arr.Count(x => x == arrayAfterOperations[i]);
//Console.WriteLine($"isti: {arrayAfterOperations.Count(x => x == arr[i])}");
}
//najveci broj jednakih elemenata u AfterArray nizu (Max() vraca prvi element u nizu ako ima vise istih)
int maxNumOfEqualElInAfterArr = numOfEqual.Max();
//indeks elementa koji se najvise ponavlja
int indexOfFirstMax = numOfEqual.ToList().IndexOf(maxNumOfEqualElInAfterArr);
//Sada za taj broj koji se najvise ponavlja u AfterArray, njegov indeks je jednak indeksu
//elementa iz Arr niza koji se najmanje ponavlja u Arr nizu (ovo je bitno zbog broja operacija)
int maxOfEqualInArr = arr.Count(x => x == arr[indexOfFirstMax]);
//duplikati
int dupl = 0;
//grupise sve elemente i trazi da li ima duplikata u Arr nizu
dupl = arr.GroupBy(x => x)
.Where(g => g.Count() > 1).Count();
if(dupl > 0) {
//ako ima duplikata, onda se u ovu varijablu spasava najveci broj ponavljanja
dupl = arr.GroupBy(x => x)
.Where(g => g.Count() > 1).Select(y => y.Count()).ToList().Max();
}
else
{
dupl = 0;
}
//ako je broj ponavljanja u arr nizu veci od zbira ponavljanja u modifikovanom AftetArr i proslijedjenom
//Arr, onda je maksimalan broj elemenata koji se ponavljaju dupl (ostaje isti kao u proslijedjenom stringu)
//sto znaci da ne treba nijedna operacija da se izvrsi pa je min br operacija 0
if (dupl > maxNumOfEqualElInAfterArr + maxOfEqualInArr) {
output[0] = dupl;
output[1] = 0;
return output;
}
else {
output[0] = maxNumOfEqualElInAfterArr + maxOfEqualInArr;
}
//Ako nema jednakih elemenata u novom nizu AfterArr onda je i broj operacija 0
if (maxNumOfEqualElInAfterArr == 0)
{
output[1] = maxNumOfEqualElInAfterArr;
return output;
}
int numOfMinOperations = 0;
List<int> minOper = new List<int>();
//ako ima vise maksimuma u nizu koji pokazuje broj ponavljanja elemenata, treba proci kroz
//sve te maksimalne elemente da se odredi minimalan broj operacija
if (numOfEqual.Count(x => x == maxNumOfEqualElInAfterArr) > 1)
{
for (int i = 0; i < numOfEqual.Length; i++)
{
//kada naidje na maksimalnu cifru
if(numOfEqual[i] == maxNumOfEqualElInAfterArr)
{
//u listu dodaje broj ponavljanja elementa koji se nalazi na indexu (i)
//iz arr niza.Taj broj ponavljanja je ujedno i najmanji broj operacija
//vezan za taj element koji se nalazi na indexu (i)
minOper.Add(arr.Count(x => x == arr[i]));
}
}
}
//najmanji broj operacija je maksimalan broj ponavljanja iz proslijedjenog
//niza arr ukoliko je lista minOper prazna.
int minOperacije = maxOfEqualInArr;
//ako lista nije prazna
if (minOper.Count() > 0) {
//onda je min broj operacija jednak najmanjem elementu iz liste minOper
minOperacije = minOper.Min();
}
output[1] = minOperacije;
return output;
}