#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
 
#define MAXWORD 100

struct lnode {
	int lineno;
	struct lnode *next;
};
 
struct tnode {
        char *word;
        struct lnode *lines;
        struct tnode *left;
        struct tnode *right;
};
 
struct tnode *addtree(struct tnode *, char *, int);
void treeprint(struct tnode *);
void printlines(struct lnode *);
struct tnode *talloc(void);
struct lnode *lalloc(void);
int getword(char *, int *, int);
char *strdupl(char *);
int col;
 
main()
{
        struct tnode *root;
        char word[MAXWORD];
	int line = 1;
        root = NULL;
        while (getword(word, &line, MAXWORD) != EOF)
                if (isalpha(word[0]))
                        root = addtree(root, word, line);
        treeprint(root);
        return 0;
}
 
struct tnode *addtree(struct tnode *p, char *w, int line)
{
	struct lnode *q;
        int cond;
        if (p == NULL) {
                p = talloc();
                p -> word = strdupl(w);
		p -> lines = lalloc();
		p -> lines -> lineno = line;
		p -> lines -> next = NULL;
                p -> left = p -> right = NULL;
        }
        else if ((cond = strcmp(w, p -> word)) == 0) {
		if (line != p -> lines -> lineno) {
			q = lalloc();
			q -> lineno = line;
			q -> next = p -> lines;
			p -> lines = q;
		}
	}
        else if (cond < 0)
                p -> left = addtree(p -> left, w, line);
        else
                p -> right = addtree(p -> right, w, line);
        return p;
}
 
void treeprint(struct tnode *p)
{
        if (p != NULL) {
                treeprint(p -> left);
                printf("%18s:", p -> word);
		col = 0;
		printlines(p -> lines);
		printf("\n");
                treeprint(p -> right);
        }
}

void printlines(struct lnode *q)
{
	if (q != NULL) {
		printlines(q -> next);
		col++;
		if (col > 10) {
			printf("\n                   ");
			col = 1; /* was 0 */
		}
		printf("%6i", q -> lineno);
	}
}
 
struct tnode *talloc(void)
{
        return (struct tnode *) malloc(sizeof(struct tnode));
}

struct lnode *lalloc(void)
{
	return (struct lnode *) malloc(sizeof(struct lnode));
}
 
int getword(char *word, int *line, int lim)
{
        int c;
        char *w = word;
	char ch;
        while (isspace(c = tolower(getchar())))
                if (c == '\n') (*line)++;
        if (c != EOF)
                *w++ = c;
        if (!isalpha(c) && c != '\\') {
                *w = '\0';
                return c;
        }
        for ( ; --lim > 0; w++) {
		*w = tolower(getchar());
		if (*w == '\'') {
			ch = tolower(getchar());
			if (isalpha(ch) && ch != 's') {
				--lim;
				w++;
				*w = ch;
			}
			else {
				ungetc(ch, stdin);
				break;
			}
		}
                else if (!isalpha(*w)) {
                        ungetc(*w, stdin);
                        break;
                }
	}
        *w = '\0';
        return word[0];
}
 
char *strdupl(char *s)
{
        char *p;
        p = (char *) malloc(strlen(s)+1);
        if (p != NULL)
                strcpy(p, s);
        return p;
}