import java.io.*;

public class BuildDict 
{
	private static BufferedReader console = new BufferedReader( new InputStreamReader( System.in ) );

	private static Dictionary d = new Dictionary(5003);

	public static void processLine(String line)
	{

		String word = "";
		char ch;

		for(int i = 0; i < line.length(); i++)
		{
			// ch is the current character
			ch = line.charAt(i);

			// if ch is a letter, append it to the word
			// being constructed
			if(Character.isLetter(ch) || (ch == '\047' && word.length() != 0))
				word = word + ch;
			// otherwise, if ch is not a letter
			// and there is a word to insert into dictionary
			else if(word.length() > 1)
			{
				word = word.toLowerCase();
				Record result = d.search(word);
				if(result == null)
				{
					Record temp = new Record(word);
					d.insert(temp);
				}
				else
				{
					result.ctr++;
				}

				word = "";
			}
			else if(word.length() == 1)
				word = "";
		}
		
		if(word.length() > 1)
		{
			word = word.toLowerCase();
			if(d.search(word) == null)
			{
				Record temp = new Record(word);
				d.insert(temp);
			}
			else
			{
				d.search(word).ctr++;
			}
		}

	
	}

	public static void mergeSort(Record[] list)
	{
		recursiveMergeSort(list, 0, list.length - 1);
	}

	public static void recursiveMergeSort(Record[] list, int first, int last)
	{
		if(first < last)
		{
			int mid = (first + last) / 2;
			recursiveMergeSort(list, first, mid);
			recursiveMergeSort(list, mid + 1, last);
			merge(list, first, mid, last);
		}
	}

	public static void merge(Record[] list, int first, int mid, int last)
	{
		Record[] temp = new Record[list.length];
		int i = first;
		int j = mid + 1;
		int l = 0;
		
		while((i <= mid) && (j <= last))
		{
			if(list[i].ctr >= list[j].ctr)
			{
				temp[l++] = list[i++];
			}
			else
			{
				temp[l++] = list[j++];
			}
		}
		if(i <= mid)
		{
			for(int k = i; k <= mid; k++)
			{
				temp[l++] = list[k];
			}
		}
		else if(j <= last)
		{
			for(int k = j; k <= last; k++)
			{
				temp[l++] = list[k];
			}
		}
		for(int k = 0; k <= last - first; k++)
		{
			list[first + k] = temp[k];
		}
	}

	public static void main(String [] args)
	{
                try
                {
			System.out.println("Please type the name of the files you want processed.");
			String filenames = console.readLine();
			String[] fileNameArray = filenames.split("[ \t]+");

			FileOutputStream outFile;
			outFile = new FileOutputStream("words.dat"); 
			PrintStream p = new PrintStream(outFile);

                        String line = "";
			for(int i = 0; i < fileNameArray.length; i++)
			{
                        	FileReader fr = new FileReader(fileNameArray[i]);
                        	BufferedReader stdin = new BufferedReader(fr);

                        	line = stdin.readLine();
				while(line != null)
				{
					processLine(line);
                        		line = stdin.readLine();
				}
			}

			Record [] wordList = d.getRecordList();
			mergeSort(wordList);

			for(int i = 0; i < wordList.length; i++)
				p.println(wordList[i].keyWord);// + " " + wordList[i].ctr);

			//d.print(p);
			d.printStatistics();
			p.close();
                }
                catch(java.io.IOException e)
                {
                        System.out.println(e);
                }

	}

}
