#include<stdio.h>
#include<string.h>
#include<memory.h>
#include<math.h>
#include<algorithm>
#include<vector>

using namespace std;

int Max = 0;

struct S
{
	S* up;
	vector<S*> mass;
};

S tree;

void read( S* a , int deep )
{
	if( a == NULL ) return;
	if( deep > Max )
		Max = deep;
	char c = getchar();
	if( 'u' == c )
		read( a->up , deep - 1 );
	else
	{
		if( c != 'd' ) return;
		S* n = new S();
		a->mass.push_back( n );
		n->up = a;
		read( n , deep + 1 );
	}
}

int func(S* ass)
{
	if( ass->mass.size() == 0 ) return 0;
	if( ass->mass.size() == 1 ) return 1 + func( ass->mass[ 0 ] );
	int s = 0;
	for(int i = 1;i < ass->mass.size();++i)
	{
		int g = func( ass->mass[ i ] ) + i;
		if( g > s )
			s = g;
	}
	return 1 + s;
}
int main()
{
	freopen(  "input.txt" , "r" , stdin  );
	freopen( "output.txt" , "w" , stdout );
	tree.up = NULL;
	read( &tree , 0 );
	printf( "%d " , Max );
	int Max2 = func( &tree );
	printf( "%d" , Max2 );
	return 0;
}


/*
char mass[ 200 ][ 200 ];

int m , n;

int A , B;

int num[ 200 ][ 200 ];
int path[ 200 ][ 200 ];

int paths[ 200 ];
scanf( "%d%d" , &m , &n );
	int i , j;
	for(i = 0;i < m;++i)
		scanf( "%s" , mass[ i ] );
	scanf( "%d%d" , &A , &B );
	A--;
	B--;
	for(i = A;i < B;++i)
	{
		if( i == A )
		{
			for(j = 0;j < n;++j)
				num[ i ][ j ] = 0;
			continue;
		}
		bool have = false;
		for(j = 0;j < n;++j)
		{
			if( mass[ i ][ j ] != 'O' ) continue;
			int min = 1 << 29;

			for(int k = 0;k < n;++k)
			{
				if( mass[ i - 1 ][ k ] != 'O' ) continue;
				have = true;
				int s = num[ i - 1 ][ k ];
				if( k != j ) s++;
				if( min > s )
				{
					min = s;
					num[ i ][ j ] = min;
					path[ i ][ j ] = k;
					
				}
			}
			
		}
		if( !have  )
			{
				printf( "Not available" );
				return 0;
			}
	}
	int Min = 1 << 29;
	int index = -1;
	for(i = 0;i < n;++i)
		if( mass[ B - 1 ][ i ] == 'O' && Min > num[ B - 1 ][ i ] )
		{
			Min = num[ B - 1 ][ i ];
			index = i;
		}
	
	paths[ B ] = index;
	for(i = B - 1;i > A;--i)
	{
		paths[ i ] = path[ i ][ paths[ i + 1 ] ];
	}

	int left = A + 1;
	int cur = paths[ A + 1 ];
	
	for(i = A + 1;i <= B;++i)
	{
		if( paths[ i ] == cur )
			continue;
		printf( "%c: %d-%d\n" , 'A' + cur , left , i );
		left = i;
		cur = paths[ i ];
	}
	printf( "%c: %d-%d\n" , 'A' + cur , left , B + 1 );


bool isUsed[ 1005 ];
int Pair[ 1005 ];
bool M[ 1005 ][ 1005 ];

int L , R , Result;
bool DFSL(int);

bool DFSR(int j)
{
	isUsed[ j ] = true;
	if( Pair[ j ] != -1 )
		return DFSL( Pair[ j ] );
	return true;
}

bool DFSL(int i)
{
	for(int j = 0;j < R;++j)
		if( M[ i ][ j ] && !isUsed[ j ] )
			if( DFSR( j ) )
			{
				Pair[ j ] = i;
				return true;
			}
	return false;
}
void pairs()
{
	for(int i = 0;i < L;++i)
	{
		for(int j = 0;j < R + 1;++j)
			isUsed[ j ] = false;
		if( DFSL( i ) )
			++Result;
	}
}
*/

/*
z - 
vector<int> calc_z(const char* s)
{
	vector<int> z;
	int len = strlen( s );
	z.resize( len );
	z[ 0 ] = 0;
	int l = 0 , r = 0;
	int j;
	for(int i = 1;i < len;++i)
		if( i > r )
		{
			for(j = 0;(i + j < len) && (s[ i + j ] == s[ j ]);++j);
			z[ i ] = j;
			l = i;
			r = i + j - 1;
		}
		else
			if( z[ i - l ] < r - i + 1 )
				z[ i ] = z[ i - l ];
			else
			{
				for(j = 1;(i + j < len) && (s[ i + j ] == s[ r - i + j ]);++j);
				z[ i ] = r - i + j;
				l = i;
				r = r + j - 1;
			}
	return z;
}
*/