Problem: On the Internet shopping site, on the same page as the product that the user is currently viewing, some other products that other users have bought in the past along with the product that they are currently viewing are displayed. It is believed that sales can be increased by presenting products that are considered to be highly relevant.

Similar things can be seen in local supermarkets (such as bread and jam) as a way to place items that are often bought together nearby. Your job is to write a program that will help you devise product placement. This time, I would like to set a certain standard number of times and find a combination of two products for which the number of times bought together is equal to or greater than the standard number of times.

When given the information of the products bought together and the standard number of times, create a program that outputs the combination of the two products bought together more than the standard number of times.



Input

The input is given in the following format.


N F
info1
info2
::
infoN


The first line gives the number of pieces of information N (1 ≤ N ≤ 100) and the reference number F (1 ≤ F ≤ 100) of the items bought together. The following N lines are given information on the products bought together. Information about the products bought together infoi is given in the following format.


M item1 item2 ... itemM


M (1 ≤ M ≤ 10) indicates how many products this information contains. itemj is the name of the item bought in this purchase and is a string of 1 to 30 length consisting of only lowercase letters. The same product is never given in infoi.

Output

The number of combinations of two products bought together more than the reference number of times is output on the first line, and all combinations are output on the second and subsequent lines. However, if there is no combination, nothing is output after the second line.

The output order is as follows after arranging the product names in the combination in the lexicographic order (the order in which the words are arranged in the English-Japanese dictionary).

* Compare the first product names, and the one with the earliest in lexicographic order comes first.
* If they are the same, compare the second product names and the lexicographic order comes first.



Separate product names with a single space, and separate product combinations with a single line break.

Examples

Input

5 2
3 bread milk banana
2 milk cornflakes
3 potato bread milk
4 cornflakes bread milk butter
2 potato bread


Output

3
bread milk
bread potato
cornflakes milk


Input

5 5
3 bread milk banana
2 milk cornflakes
3 potato bread milk
4 cornflakes bread milk butter
2 potato bread


Output

0

Solution (in CPP):

Solution:
#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>

using namespace std;

struct Info{
	char name[31];
};

struct Ans{
	char left[31],right[31];
};

bool strCmp(char* base, char* comp){
	int length1 = 0,length2 = 0;
	for(int i=0;base[i] != '\0'; i++)length1++;
	for(int i=0;comp[i] != '\0'; i++)length2++;
	if(length1 != length2)return false;

	for(int i=0;base[i] != '\0'; i++){
		if(base[i] != comp[i])return false;
	}
	return true;
}

void strcpy(char* to,char* str){
	for(int i=0;str[i] != '\0';i++){
		to[i] = str[i];
		to[i+1] = '\0';
	}
}

int strCmp2(char* left,char* right){
	int i;

	if(strCmp(left,right))return 3;

	for(i=0;left[i] != '\0' && right[i] != '\0'; i++){
		if(left[i] != right[i]){
			if(left[i] < right[i])return 1;
			else{
				return 2;
			}
		}
	}
	if(left[i] == '\0')return 1;
	else{
		return 2;
	}
}



int main(){

	int F,N,index,base;
	scanf("%d %d",&N,&F);
	int num_of_data[N];
	int** data = new int*[N];
	for(int i = 0; i < N; i++){
		data[i] = new int[10];
	}
	int** checkTable = new int*[1000];
	for(int i = 0; i < 1000; i++){
		checkTable[i] = new int[1000];
		for(int k = 0; k < 1000; k++)checkTable[i][k] = 0;
	}

	Info info[10*N];
	index = 0;

	char buf[31];
	bool FLG;

	for(int loop = 0; loop < N; loop++){
		scanf("%d",&num_of_data[loop]);

		for(int i = 0; i < num_of_data[loop];i++){
			scanf("%s",buf);

			FLG = false;
			for(int k = 0; k < index; k++){
				if(strCmp(info[k].name,buf)){
					FLG = true;
					data[loop][i] = k;
					break;
				}
			}
			if(!FLG){
				strcpy(info[index].name,buf);
				data[loop][i] = index;
				index++;
			}
		}
	}

	for(int loop = 0; loop < N; loop++){
		for(int i = 0; i < num_of_data[loop];i++){

			base = data[loop][i];

			for(int k = 0; k < num_of_data[loop];k++){
				if(k != i){
					checkTable[base][data[loop][k]]++;
				}
			}
		}
	}

	Ans* ans = (Ans*)malloc(sizeof(Ans)*(index*index));
	int ans_index = 0;

	for(int i = 0; i < index-1; i++){
		for(int k = i+1; k < index; k++){
			if(checkTable[i][k] >= F){
				if(strCmp2(info[i].name,info[k].name) == 1){
					strcpy(ans[ans_index].left,info[i].name);
					strcpy(ans[ans_index].right,info[k].name);
					ans_index++;
				}else{
					strcpy(ans[ans_index].left,info[k].name);
					strcpy(ans[ans_index].right,info[i].name);
					ans_index++;
				}
			}
		}
	}

	for(int i = 1; i <= ans_index-1; i++){
		for(int k = ans_index-1; k >= i;k--){
			if(strCmp2(ans[k].left,ans[k-1].left) == 1)swap(ans[k],ans[k-1]);
			else if(strCmp2(ans[k].left,ans[k-1].left) == 3 && strCmp2(ans[k].right,ans[k-1].right) == 1)swap(ans[k],ans[k-1]);
		}
	}

	printf("%d\n",ans_index);

	for(int i = 0; i < ans_index; i++){
		printf("%s %s\n",ans[i].left,ans[i].right);
	}

    return 0;
}