#include<iostream>
#define SIZE 100000
char data[SIZE][501];
typedef struct node{
int value;
struct node *next;
struct node *pre;
char da[501];

}node;
int dex = 0;
node HashTbale[SIZE];
node HashIndex[SIZE];
int val;
node *getNewNode()
{
return &HashIndex[dex++];
}
/*node InsertNewNode(int key, node *NewNode)
{
NewNode->next = HashTbale[key].next;
HashTbale[key].next = NewNode;
}*/
void insertNode(int key, node *newNode)
{
node * head = &HashTbale[key];

newNode->pre = head;
newNode->next = head->next;

head->next = newNode;
newNode->next->pre = newNode;
}
void init(int N){
dex = 0; //reset hash pool
for (int i = 0; i < N; i++){
HashTbale[i].pre = &HashTbale[i];
HashTbale[i].next = &HashTbale[i];
}
}

int getNum(char data[]){
int val = 0;
for (int i = 0; i < 15; i++){
val = val * 26 + data[i] - 'a';
val %= SIZE;
}
return val;
}
bool same(char str2[], char str1[])
{
for (int i = 0; i < 500; i++){
if (str1[i] != str2[i])
return false;
}
return true;
}
node *search(node *newNode)
{
int key = getNum(newNode->da);
node *x = HashTbale[key].next;
while (x != &HashTbale[key] && !same(x->da, newNode->da))
{
x = x->next;
}
if (x != &HashTbale[key])
return x;
else return NULL;


}
int main()
{
init(SIZE);
node *curNode;
int key = 0;
int max = 1;
for (int i = 0; i < SIZE; i++){
node * newNode = getNewNode();
newNode->value = 1;
for (int j = 0; j < 500; j++){
newNode->da[j] = rand() % 26 + 'a';
}
newNode->da[500] = '\0';

node * tmpNode = search(newNode);
if (tmpNode != NULL){
tmpNode->value++;
if (tmpNode->value > max)
max = tmpNode->value;
}
else{
int key = getNum(newNode->da);
insertNode(key, newNode);
}
}
printf("%d\n", max);
return 0;

}