//Ilie Dumitru
#include<cstdio>
#include<cstring>
typedef long long int ll;
const int NMAX=100005;
const ll MOD=1000000007;
FILE* f=fopen("evaluare.in", "r"), *g=fopen("evaluare.out", "w");
struct node
{
int val;
char op;
node* l, *r;
};
int eval(node* n)
{
if(!n)
return 0;
switch(n->op)
{
case '+':
return eval(n->l)+eval(n->r);
case '-':
return eval(n->l)-eval(n->r);
case '*':
return eval(n->l)*eval(n->r);
case '/':
return eval(n->l)/eval(n->r);
default:
return n->val;
}
}
void print(node* n)
{
if(n->op)
{
if((n->l->op=='+' || n->l->op=='-') && (n->op=='*' || n->op=='/'))
{
printf("(");
print(n->l);
printf(")");
}
else
print(n->l);
printf("%c", n->op);
if(((n->r->op=='+' || n->r->op=='-') && (n->op=='*' || n->op=='/')) || ((n->op=='-' || n->op=='/') && n->r->op))
{
printf("(");
print(n->r);
printf(")");
}
else
print(n->r);
}
else
printf("%d", n->val);
}
struct prior
{
int p, ind;
};
char expr[NMAX];
int priorities[NMAX], l;
prior segTree[NMAX<<2];
const int INTMAX=(-1)^(1<<31);
prior computeSegTree(int n, int l, int r)
{
if(l==r)
{
if(priorities[l])
segTree[n].p=priorities[l];
else
segTree[n].p=INTMAX;
segTree[n].ind=l;
}
else
{
int mid=(l+r)>>1;
prior m0=computeSegTree((n<<1)|1, l, mid);
prior m1=computeSegTree((n<<1)+2, mid+1, r);
if(m0.p<m1.p)
segTree[n]=m0;
else
segTree[n]=m1;
}
return segTree[n];
}
void querySegTree(int n, int l, int r, int a, int b, int& min, int& pos)
{
if(l>=a && r<=b)
{
if(segTree[n].p<min)
min=segTree[n].p, pos=segTree[n].ind;
}
else if(l<=b && r>=a)
{
int mid=(l+r)>>1;
if(a<=mid)
querySegTree((n<<1)|1, l, mid, a, b, min, pos);
if(mid<b)
querySegTree((n<<1)+2, mid+1, r, a, b, min, pos);
}
}
void computePriorities()
{
int i, prnt=0, prioritPerParant=2;
for(i=0;expr[i];++i)
{
if(expr[i]=='(')
prnt+=prioritPerParant;
else if(expr[i]==')')
prnt-=prioritPerParant;
else if(expr[i]=='+' || expr[i]=='-')
priorities[i]=prnt+1;
else if(expr[i]=='*' || expr[i]=='/')
priorities[i]=prnt+2;
}
}
node* computeTree(int start, int end) // [start, end]
{
int i, minPr=INTMAX, posMinPr=start-1;
querySegTree(0, 0, l-1, start, end, minPr, posMinPr);
node* n=new node;
n->val=0;
n->op=0;
n->l=0;
n->r=0;
if(minPr==INTMAX)
{
//val
for(i=start;i<=end;++i)
if(expr[i]>='0' && expr[i]<='9')
n->val=n->val*10+expr[i]-'0';
}
else
{
//op
n->op=expr[posMinPr];
n->l=computeTree(start, posMinPr-1);
n->r=computeTree(posMinPr+1, end);
}
return n;
}
void clearMem(node*& n)
{
if(n->op)
{
clearMem(n->l);
clearMem(n->r);
}
delete n;
}
int main()
{
fgets(expr, NMAX, f);
l=strlen(expr);
if(expr[l-1]=='\n')
expr[--l]=0;
computePriorities();
computeSegTree(0, 0, l-1);
node* tree=computeTree(0, l-1);
//print(tree);
fprintf(g, "%d", eval(tree));
clearMem(tree);
fclose(f);
fclose(g);
return 0;
}