/*  2020/2021 North America Championship
    International Collegiate Programming Contest

    Problem ?
    Daily Cron
    M. K. Furon.                    2021-03-31.                       */




#include  <stdio.h>
#include  <stdlib.h>
#include  <string.h>
#include  <ctype.h>
#include  <math.h>




int croncount, hh, i, iocount, job, jobcount, jobtrigger, mm, ss;
int timecount;
unsigned int hourbit, hourmatch;
unsigned long long int minutebit, minutematch, secondbit, secondmatch;
char *token;

char lineimage[1024];

struct cronspec
{
unsigned int hourmap;
unsigned long long int minutemap;
unsigned long long int secondmap;
} cronentry[100];




void abend (char *message)
{
(void) fputs (message, stderr);
(void) fputc ('\n', stderr);
exit (4);
}




unsigned long long int valuemap (char *valuelist, int maxvalue)
{
unsigned int bitcount, number1, number2;
unsigned long long int bitsset, result;
char *nextvalue;

/*  Turn a list of values into a bit map for those values.  The
    maximum value constrains the size of the bit map.  Asterisk
    means "all values".                                               */
if (*valuelist == '*')              /*  If all values "wild card"     */
   result = (1LL << (maxvalue + 1)) - 1LL;
else
   {
   result = 0;
   while (*valuelist)
      {
      number1 = (int) strtoul (valuelist, &nextvalue, 10);
      if ((*nextvalue == ((char) 0))  ||  (*nextvalue == ','))
         {
	 /*  Number is a single value.                                */
	 result |= (1LL << number1);
	 if (*nextvalue == ',')
	    nextvalue++;
	 valuelist = nextvalue;
	 }
      else if (*nextvalue == '-')   /*  If range is specified         */
         {
	 nextvalue++;
	 number2 = (int) strtoul (nextvalue, &nextvalue, 10);
	 if (number2 <= number1)
	    abend ("Incorrect range specified.");
	 /*  Set the bits corresponding to the values in the range.   */
	 bitcount = number2 - number1 + 1;
	 bitsset = (1LL << bitcount) - 1LL;
	 result |= bitsset << number1;
	 if (*nextvalue == ',')
	    nextvalue++;
	 valuelist = nextvalue;
	 }
      }
   }

return (result);
}




int main (int argc, char *argv[], char *envp[])
{
/*  Ingest the "crontab" time specifications, one per line.           */
(void) fgets (lineimage, 1020, stdin);
iocount = sscanf (lineimage, "%d", &croncount);
if (iocount != 1)
   abend ("Incorrect cron line count.");

for (i = 0; i < croncount; i++)
   {
   (void) fgets (lineimage, 1020, stdin);
   /*  Strip the trailing new-line from the input buffer.             */
   lineimage[((strlen (lineimage)) - 1)] = (char) 0;
   token = strtok (lineimage, " \t");
   cronentry[i].hourmap = (int) valuemap (token, 23);
   token = strtok (NULL, " \t");
   cronentry[i].minutemap = valuemap (token, 59);
   token = strtok (NULL, " \t");
   cronentry[i].secondmap = valuemap (token, 59);
   }
   
/*  Process the entries for each second of the day.  If at least
    one entry is triggered in a given second, increment the time
    counter.  Increment the job counter for each job triggered.       */
jobcount = timecount = 0;
for (hh = 0; hh < 24; hh++)
   {
   hourbit = 1 << hh;
   for (mm = 0; mm < 60; mm++)
      {
      minutebit = 1LL << mm;
      for (ss = 0; ss < 60; ss++)
         {
	 secondbit = 1LL << ss;
         jobtrigger = 0;
	 for (job = 0; job < croncount; job++)
	    {
	    hourmatch = hourbit & cronentry[job].hourmap;
	    minutematch = minutebit & cronentry[job].minutemap;
	    secondmatch = secondbit & cronentry[job].secondmap;
	    if (hourmatch && minutematch && secondmatch)
	       jobtrigger++;
	    }
	 if (jobtrigger)
	    {
	    timecount++;
	    jobcount += jobtrigger;
	    }
	 }
      }
   }

(void) printf ("%d %d\n", timecount, jobcount);
return (0);
}
