Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
	"strings"
)

func main() {
	stdin := bufio.NewScanner(os.Stdin)
	index := make(map[string]string)
	keys := []string{}
	for stdin.Scan() {
		l := strings.Split(stdin.Text(), " ")
		if l[0] == "0" {
			break
		}
		if index[l[0]] == "" {
			keys = append(keys, l[0])
		}
		index[l[0]] += l[1] + " "
	}
	sort.Strings(keys)
	for _, k := range keys {
		fmt.Println(k)
		p := strings.Split(strings.TrimRight(index[k], " "), " ")
		pages := []int{}
		for _, v := range p {
			i, _ := strconv.Atoi(v)
			pages = append(pages, i)
		}
		sort.Ints(pages)
		for i, v := range pages {
			if i > 0 {
				fmt.Printf(" ")
			}
			fmt.Printf("%d", v)
		}
		fmt.Println()
	}
}

C++: #include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;

int main(){
  pair< string ,int > book[1001];
  string name;
  int n=0 ,num;
  bool flag=true;
  while( cin >> name >> num ){
    book[n].first  = name;
    book[n].second = num;
    n++;
  }

  sort( book ,book+n );
  for( int i=0 ; i<n ; i++ ){
    for( int j=0 ; j<n ; j++ ){
      if( i != j && book[i].first.find(book[j].first) != string::npos ){
	book[j].first = ' ';
      }
    }
  }
  for( int i=0 ; i<n ; i++ ){
    if( book[i].first.compare( " " ) == 0 )
      cout << ' ' << book[i].second;
    else{
      if( !i ){
	cout << book[i].first << endl << book[i].second;
	flag = true;
      }
      else{
	cout << endl << book[i].first << endl << book[i].second;
	flag = false;
      }
    }
  }
  if( !flag ) cout << endl;
}

C++: #include <iostream>
#include <string>
#include <map>
#include <set>
using namespace std;

int main(){
  string phrase;
  int page;
  map<string, set<int> > dictionary;

  while(cin >> phrase >> page){
    //cin >> phrase >> page;
    // if(phrase == "end") break;
    dictionary[phrase].insert(page);
  }

  map<string, set<int> >::iterator p1;
  set<int>::iterator p2;

  for(p1 = dictionary.begin(); p1 != dictionary.end(); p1++){
    cout << (*p1).first << endl;

    p2 = dictionary[(*p1).first].begin();
    cout << *p2;
    for( p2++; p2 != dictionary[(*p1).first].end(); p2++){
      cout << " " << *p2;
    }
    cout << endl;

  } 

  return 0;
}

C++: #include<iostream>
#include<map>
#include<set>

using namespace std;

int main(void){
  map<string, set<int> > m;
  map<string, set<int> >::iterator it;
  set<int>::iterator itr;
  string s;
  int n;

  while(cin>>s>>n){
    m[s].insert(n);
  }
  for(it=m.begin();it!=m.end();it++){
    cout <<(*it).first<<endl;
    for(itr=(*it).second.begin();itr!=(*it).second.end();itr++){
      cout<< *itr;
      itr++;
      if(itr!=(*it).second.end()){
	cout<<" ";
      }
      itr--;
    }
    cout <<endl;
  }
  
}

C++: #include <iostream>
#include <vector>
#include <string>
#include <map>
#include <algorithm>
using namespace std;

int main(){
	string s;
	int n;
	map<string, vector<int> > m;
	while (1){
		if (cin.eof()) break;
		cin >> s >> n;
		m[s].push_back(n);
	}
	map<string, vector<int> >::iterator it = m.begin();
	while (it != m.end()){
		int flag = 0;
		cout << (*it).first << endl;
		sort((*it).second.begin(), (*it).second.end());
		for (int i = 0; i < (*it).second.size(); i++){
			if (!flag){
				cout << (*it).second[i];
				flag = 1;
			}
			else cout << " " << (*it).second[i];
		}
		cout << endl;
		++it;
	}
	return 0;
}

C++: #include <iostream>
#include <string>
using namespace std;
class data{
public:
  string words;  
  int page;
  bool operator < (const data& s)const{
    if(words < s.words) return true;
    else if(words > s.words) return false;
    else{
      if(page < s.page) return true;
      else return false;
    }
  }
};
int main(){
  int i=0;
  data in[1000];
  while(1){
    in[i].words="";
    char c;
    if(scanf("%c", &c)==EOF) break;
    in[i].words+=c;
    for(int j=1;;j++){
      scanf("%c", &c);
      if(c==' ') break;
      in[i].words+=c;
    }
    cin >> in[i].page;
    getchar();
    i++;
  }
  
  sort(in,in+i);

  cout << in[0].words << endl << in[0].page;
  for(int j=1;j<i;j++){
    if(in[j-1].words != in[j].words){
      cout << endl;
      cout << in[j].words << endl << in[j].page;
    }
    else{
      cout << ' ' << in[j].page;
    }
  }
  cout << endl;
  return 0;
}

C++: #include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;

struct book_info{
	char phrase[32];
	int pageNum[101];
};

int main(){
	
	int i,page;
	char inputStr[32];
	bool flag;
	struct book_info index[101]={'\0',0};
	
	memset(inputStr,'\0',sizeof(inputStr));
	
	
	//入力
	for(i=0;;i++){
		
		if(scanf("%s %d",inputStr,&page)==EOF){
			break;
		}
		
		flag=true;
		
		//入力済みの単語かどうかを調べる
		int j;
		for(j=0;j<i;j++){
			//入力済みなら
			if(strcmp(index[j].phrase,inputStr)==0){
				//ページ番号の記憶
				for(int k=0;k<100;k++){
					if(index[j].pageNum[k]==0){
						index[j].pageNum[k]=page;
						break;
					}
				}
				flag=false;
				break;
			}
		}
		
		//入力されてないなら
		if(flag){
				strcpy(index[j+1].phrase,inputStr);
				index[j+1].pageNum[0]=page;
		}
		
		memset(inputStr,'\0',sizeof(inputStr));
	}
	
	
	//単語昇順バブルソート
	for(int j=0;j<i;j++){
		for(int k=i-1;k>j;k--){
			if(strcmp(index[k-1].phrase,index[k].phrase)>0){
				   struct book_info temp;
				   temp=index[k];
				   index[k]=index[k-1];
				   index[k-1]=temp;				
			}
		}
	}
	
	//単語昇順かつページ番号昇順バブルソート
	for(int g=0;g<i;g++){
		for(int j=0;j<100;j++){
			for(int k=100-1;k>j;k--){
				if((index[g].pageNum[k-1]>index[g].pageNum[k]) && 
				    index[g].pageNum[k-1]!=0 &&
				    index[g].pageNum[k]!=0){		
						int temp;
						temp=index[g].pageNum[k];
						index[g].pageNum[k]=index[g].pageNum[k-1];
						index[g].pageNum[k-1]=temp;				
				}
			}
		}
	}
	
	for(int j=0;j<i;j++){
		if(index[j].phrase[0]!='\0'){
			cout<<index[j].phrase<<endl;
		}
		for(int k=0;k<100 && index[j].pageNum[k]!=0;k++){
			if(index[j].pageNum[k+1]!=0){
				cout<<index[j].pageNum[k]<<" ";
			}else{
				cout<<index[j].pageNum[k]<<endl;
			}
		}
	}
}

C++: #include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

int main()
{
    map<string, vector<int> > index;
    for(;;){
        string s;
        int n;
        if(!(cin >> s >> n))
            break;
        index[s].push_back(n);
    }

    map<string, vector<int> >::iterator it;
    for(it=index.begin(); it!=index.end(); ++it){
        cout << it->first << endl;
        sort(it->second.begin(), it->second.end());
        cout << it->second[0];
        for(unsigned i=1; i<it->second.size(); ++i){
            cout << ' ' << it->second[i];
        }
        cout << endl;
    }

    return 0;
}

C++: #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <time.h>
#include <math.h>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
#include <iterator>
#include <sstream>
#include <string>
#include <bitset>
using namespace std;
#define FOR(I,F,N) for(int I = F; I < (int)(N); I++)
#define rep(i, n) FOR(i, 0, n)
#define FIN(V) cout<<V<<endl
#define pb push_back
#define INF (1 << 28)

template<typename T>
void remove(vector<T>& vector, unsigned int index){
vector.erase(vector.begin() + index);
}

typedef pair<int, int> P;
typedef long long ll;
typedef priority_queue<int> pq;
int StrToInt(string);
string IntToStr(int);
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};

map<string, vector<int> > list;

int main(void){
	string S;
	int n;
	while(cin >> S >> n){
		list[S].push_back(n);
	}
	while(cin >> S){
		rep(i, list[S].size()){
			if(i != 0)cout << " ";
			cout << list[S][i];
		}
		cout << endl;
	}
	

	return 0;
}



int StrToInt(string s){
	stringstream ss;
	ss << s;
	int val;
	ss >> val;
	return val;
}
string IntToStr(int i){
	stringstream ss;
	ss << i;
	return ss.str();
}