/*some lines are necessary for too long floating point numbers*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BOSLUK_ATLA for(;kutu==' ' || kutu=='\n' || kutu=='\t';kutu=getchar())
typedef struct listtype listtype;
typedef struct nodetype nodetype;
typedef struct histtype histtype;
 
struct listtype /*for list elements of nodes */
{
 char quantity;
 struct listtype *samelink;
 struct nodetype *nodelink;
}firstlist;
 
struct nodetype  /*for node representation    */
{
char *name;
char kind;
 union
 {
  struct listtype *listlink;
  double price;
 }paket;
}firstnode;

struct histtype /*for holding pointers to nodes seen before*/
{
 struct nodetype *nodelink;
 struct histtype *hlink;
} *histbas;
 
char st[40]; /*holds read names and prices temporarily*/
char kutu;
int sayac;
double para,result;

/*reads count of parts*/
int Read_Count(void)
{
 int  count=0;
 BOSLUK_ATLA;
 while(kutu>='0' && kutu<='9')
 {
  count=count*10+kutu-'0';
  kutu=getchar();
 }
 if(count)
 {
  BOSLUK_ATLA;
  kutu=getchar();
  BOSLUK_ATLA;
 }
 if(count)
   return(count);
 else
   return(1);
} 

/*reads names of parts and puts into st, sayac becomes length of name*/
void Read_Name(void)
{
sayac=0;
for(;kutu>='A' && kutu<='Z';kutu=getchar())
st[sayac++]=kutu;
st[sayac]=0;
BOSLUK_ATLA;
}

/* reads prise of basic parts */ 
double Read_Price()
{
int sayac=0;
double result;
kutu=getchar();
BOSLUK_ATLA;
for(;(kutu>='0' && kutu<='9') || kutu=='.';kutu=getchar())
st[sayac++]=kutu;
st[sayac]=0;
result=atof(st);
for(;kutu!=']';kutu=getchar());
kutu=getchar();
return(result);
}

/*controls whether the read name has been read before*/
/*and avoids creating a new node instead of pointing to the old node*/
void Name_Control(listtype *newnode)
{
 histtype *temp=histbas;
 while(temp->hlink)
 {
  if(!strcmp(st,temp->hlink->nodelink->name))
  {
   newnode->nodelink=temp->hlink->nodelink;
   break;
  }
  temp=temp->hlink;
 }
 if(!temp->hlink)
 {
  temp->hlink=(histtype *)malloc(sizeof(histtype));
  temp->hlink->nodelink=NULL;
  temp->hlink->hlink=NULL;
  newnode->nodelink=(nodetype *)malloc(sizeof(nodetype));
  newnode->nodelink->kind=2;
  newnode->nodelink->name=(char *)malloc(sayac+1);
  strcpy(newnode->nodelink->name,st);
  temp->hlink->nodelink=newnode->nodelink;
 }
} 

/*recursive function for reading the input and building up the tree*/
void Start_Reading(listtype *newnode)
{
 while(1)
 switch(kutu)
 {
  case ',' :newnode->samelink=(listtype *)malloc(sizeof(listtype));
            newnode->samelink->samelink=NULL;
            newnode->samelink->nodelink=NULL;
            kutu=getchar();
            BOSLUK_ATLA;
            newnode=newnode->samelink;
            break;
  case '[' :para=Read_Price();
            if(newnode->nodelink->kind==2)
            {
             newnode->nodelink->kind=0;/*becomes basic*/
             newnode->nodelink->paket.price=para;
            }
            BOSLUK_ATLA;
            break;
  case ')' :kutu=getchar();
            return;
  case '(' :kutu=getchar();
            BOSLUK_ATLA;
            if(newnode->nodelink->kind==2)
            {
             newnode->nodelink->kind=1;/*becomes composite*/
             newnode->nodelink->paket.listlink=(listtype *)malloc
                                  (sizeof(listtype));
             newnode->nodelink->paket.listlink->nodelink=NULL;
             newnode->nodelink->paket.listlink->samelink=NULL;
             Start_Reading(newnode->nodelink->paket.listlink);
            }
            break;
  case '\t':
  case '\n':
  case ' ' :kutu=getchar();
            break;
  default  :newnode->quantity=Read_Count();
            Read_Name();
            Name_Control(newnode);
            break;
 }                                                                              
}

void Initialization(void)
{
histbas=(histtype *)malloc(sizeof(histtype));
histbas->hlink=NULL;
histbas->nodelink=NULL;
firstlist.samelink=NULL;
firstlist.nodelink=NULL;
} 

/*for reading the root and printing if it is basic*/
void First_Reading(void)
{
 Read_Name();
 firstnode.name=(char *)malloc(sayac+1);
 strcpy(firstnode.name,st);
 if(kutu=='[')
 {
  printf("%f",Read_Price());
  exit(0);
 }
 else
 {
  firstnode.kind=1;
  firstnode.paket.listlink=&firstlist;
 }
 kutu=getchar();
 BOSLUK_ATLA;
} 

/*recursive function for traversing the tree and calculating result*/
void Calculate(nodetype *newnode,long count)
{
 listtype *temp;
 if(!newnode->kind)
   result+=count*newnode->paket.price;
 else
 {
  temp=newnode->paket.listlink;
  while(temp)
  {
   Calculate(temp->nodelink,count*temp->quantity);
   temp=temp->samelink;
  }
 }
} 

int main(void)
{
kutu=getchar();
BOSLUK_ATLA;
Initialization();
First_Reading();
Start_Reading(&firstlist);
Calculate(&firstnode,1);
printf("%f",result);
return(0);                                                                      
}
