#include <algorithm>
#include <cstdio>
#include <vector>

using namespace std;

// excerpt from Juergen Werner's graph library

typedef vector<int> VI;
typedef vector<VI> VVI;

void DFS_visit_push(VVI &a, VI &v, VI &color, int act)
{
    color[act] = 1;
    for (VI::iterator it = a[act].begin(); it != a[act].end(); ++it)
        if (!color[*it])
            DFS_visit_push(a, v, color, *it);
    v.push_back(act);
}

/* I    a : unweighted graph                     */
/* RETURNS: topological order of vertices 0..n-1 */
VI Topological_sort(VVI &a)
{
    VI topo, color(a.size(), 0);
    for (int i=0; i<(int)a.size(); i++)
        if (!color[i])
            DFS_visit_push(a, topo, color, i);
    reverse(topo.begin(), topo.end());
    return topo;
}

/* I    a : unweighted graph              */
/* RETURNS: strongly connected components */
VVI SCC(VVI &a)
{
    VI toporder = Topological_sort(a);
    VVI a_t(a.size()), scc;
    for (int i=0; i<(int)a.size(); i++)
        for (VI::iterator it = a[i].begin(); it != a[i].end(); ++it)
            a_t[*it].push_back(i);
    VI color(a.size(), 0);
    for (VI::iterator it = toporder.begin(); it != toporder.end(); ++it)
        if (!color[*it])
        {
            VI component;
            DFS_visit_push(a_t, component, color, *it);
            scc.push_back(component);
        }
    return scc;
}

// end of graph library

const int NODES = 1<<24;

int main() {
  // read edges of graph
  VVI a(NODES);
  int from, to, edge_count = 0;
  while (scanf(" %x %x ", &from, &to) == 2) {
    a[from].push_back(to);
    ++edge_count;
  }
  printf("The graph has %d nodes and %d edges.\n", a.size(), edge_count);
  // calculate strongly connected components
  VVI scc = SCC(a);
  printf("The graph has %d strongly connected components.\n", scc.size());
  printf("The component sizes are:");
  for (VVI::iterator it = scc.begin() ; it != scc.end() ; ++it)
    printf(" %d", it->size());
  printf("\n");
  printf("The components are (one per line):\n");
  for (VVI::iterator it = scc.begin() ; it != scc.end() ; ++it) {
    for (VI::iterator jt = it->begin() ; jt != it->end() ; ++jt)
      printf(" 0x%06x", *jt);
    printf("\n");
  }
  return 0;
}