#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<set>
#include<queue>
#include<map>
#include<math.h>
#include<stack>
using namespace std;
#define PI acos(-1)
stack<char>ope;
stack<int>num;
//返回操作优先级
int operator_level(char ch){
if(ch == '(')return 4;
else if(ch == '*' || ch == '/')return 3;
else if(ch == '+' || ch == '-')return 2;
else if(ch == ')')return 1;
}
//计算最上方两个数
int CalcTop(){
//取出栈最上方的数
int temp2 = num.top();
num.pop();
//取出上方第二个
int temp1 = num.top();
num.pop();
//取出操作符栈最上方操作
char ch = ope.top();
ope.pop();
if(ch == '+')
num.push(temp1+temp2);
else if(ch == '-')
num.push(temp1 - temp2);
else if(ch == '*')
num.push(temp1 * temp2);
else
num.push(temp1 / temp2);
}
string s;
int main(){
cin >> s;
int nowflag = 0;// 1->ope 2->num
int temp = 0;
//判断是不是负数
int MinNumFlag = 0;
//如果是负号开场,那么设置负号位为1
for(int i = 0; i < s.length(); i++){
if(i == 0 && s[i] == '-'){
ope.push('-');
num.push(0);
continue;
}
//如果是数字,nowflag设置为2
if(s[i] >= '0' && s[i] <= '9'){
nowflag = 2;
temp *= 10;
temp += s[i]-'0';
}
else{
//如果这个字符前一位是数字
if(nowflag == 2){
//如果这个是负数,压入-temp,负数位设置为0,如果是正数,直接压入正数
if(MinNumFlag){
num.push(-temp);
MinNumFlag = 0;
}
else{
num.push(temp);
}
//将数字缓存值设为0
temp = 0;
}
//如果上一个字符是操作符并且这个字符是 - ,那么上一个字符一定是前括号,所以把负数位设置为0直接continue
if(nowflag == 1 && s[i]=='-'){
MinNumFlag = 1;
continue;
}
//否则开始准备接收操作符
nowflag = 1;
//如果操作符堆栈为空 或者 现操作符优先级大于堆栈顶操作符优先级 或者 现操作符为前括号,则直接压入堆栈
if(ope.empty() || operator_level(s[i]) > operator_level(ope.top()) || s[i]=='('){
ope.push(s[i]);
continue;
}
//当操作符堆栈不为空,且现操作符优先级不大于堆栈顶优先级,并且这个操作符不是后括号的时候,直接计算前两个
while(!ope.empty() && operator_level(s[i]) <= operator_level(ope.top()) && ope.top()!='(')
CalcTop();
//如果是后括号,直接压入后括号
if(s[i]!=')'){
ope.push(s[i]);
}
//如果后括号前就是前括号,直接将前括号删掉
if(s[i] == ')' && ope.top() == '('){
ope.pop();
}
}
}
//如果结束输入时,最后一个字符是数字,那个把前面的数字压入数字堆栈
if(nowflag == 2){
if(MinNumFlag){
num.push(-temp);
MinNumFlag = 0;
}
else{
num.push(temp);
}
temp = 0;
}
while(!ope.empty())CalcTop();
printf("%d\n",num.top());
}