#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <cctype>
using namespace std;

class Vertex;

struct VertexStorage
{
	map<string,Vertex*> storage;
	map<string,int>cnt;
	void add(Vertex* v);
	Vertex* add(const string& name);
	Vertex* find(const string& name)const;
	int count(const string& name)const;
	map<string,Vertex*>::const_iterator begin()const{return storage.begin();} 
	map<string,Vertex*>::const_iterator end()const{return storage.end();} 
};


struct Vertex
{
	string name;
	VertexStorage next;
	Vertex():name("none"),next(){}
	Vertex(const string& name):name(name),next(){}
	void addlink(Vertex* v){ next.add(v);}
};

void VertexStorage::add(Vertex* v)
{
	//if (find(v.name)==nullptr)
	storage[v->name]=v;
	cnt[v->name]++;
}


Vertex* VertexStorage::find(const string& name)const
{
	auto it=storage.find(name);
	return (it==storage.end())?nullptr:it->second;
}

Vertex* VertexStorage::add(const string& name)
{
	Vertex* present=find(name);
	if (present==nullptr) 
	{
		Vertex* newvertex=new Vertex(name);
		add(newvertex);
		return newvertex;
	}
	else 
	{
		add(present);
		return present;
	}
}

int VertexStorage::count(const string& name)const
{
	auto it=cnt.find(name);
	return (it==cnt.end())?0:it->second; //0 if not found
}

struct Graph
{
	VertexStorage V;
	Vertex* addvertex(const string& name){return V.add(name);}
	Vertex* find(const string& name){return V.find(name);}
	int Vcount(){return V.storage.size();} // 
};


 

int main() {
	
	string from, to;
	
	cin >>from >>to;
	
	string word;Vertex* curr=nullptr;Graph gr;
	while (cin >> word)
	{
		bool stop_sentence = ( !word.empty() &&
		    (word[word.length()-1]=='.' ||word[word.length()-1]=='!'||word[word.length()-1]=='?'));
		while (!word.empty()&&ispunct (word[0])) word.erase(0,1);
		while (!word.empty()&&ispunct (word[word.length()-1])) word.erase(word.length()-1,1);
		if (!word.empty()) 
		{
			Vertex* next=gr.addvertex(word);
			if (curr!=nullptr) curr->addlink(next);
			curr=next;
		}
		if (stop_sentence) curr=nullptr;
	}
	
	cout <<"Statistics:"<<endl;
	cout <<"Total words = " <<gr.Vcount()<<endl;
	cout <<"Word " <<from <<" occurs " <<gr.V.count(from) <<" times."<<endl;
	cout <<"Word " <<to <<" occurs " <<gr.V.count(to) <<" times."<<endl;
	Vertex* fromVertex=gr.find(from);
	if (fromVertex!=nullptr)
	{
		cout <<"Pair " <<from <<"->" <<to <<" occurs " <<fromVertex->next.count(to) <<" times."<<endl;
		cout <<"Words between " <<from <<" and " <<to <<":" <<endl;
		for (auto wv: fromVertex->next)
			if (wv.second->next.find(to)!=nullptr) cout <<wv.first <<" ";
		cout <<endl;
	}
	
	
	return 0;
}