/*
dp 如果是统计最少加多少个括号 就是区间dp
如果区间两头是匹配的 就可以用 i+1 j-1 更新
然而这题要输出方案
就类似记路径 记背包选哪几个一样
维护一个bj表示 i到j的最优解是由 分成哪两份转移来的
如果无法分 就是-1
最后递归搞输出方案 递归终点就是需要改变的点
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int l,f[110][110],bj[110][110],a[110];
char s[110];
void Dfs(int x,int y)
{
if(x>y)return;
if(x==y)a[x]=1;
if(bj[x][y]==-1)Dfs(x+1,y-1);
else if(bj[x][y]>0)
{
Dfs(x,bj[x][y]);
Dfs(bj[x][y]+1,y);
}
}
int main()
{
scanf("%s",s+1);
l=strlen(s+1);
if(l==0)//特判特判
{
printf("\n");
return 0;
}
for(int i=1;i<=l;i++)
f[i][i]=1;
for(int i=l-1;i>=1;i--)
for(int j=i+1;j<=l;j++)
{
f[i][j]=99999999;
if((s[i]=='('&&s[j]==')')||(s[i]=='['&&s[j]==']'))
if(f[i][j]>f[i+1][j-1])
{
f[i][j]=f[i+1][j-1];
bj[i][j]=-1;
}
for(int k=i;k<j;k++)
if(f[i][k]+f[k+1][j]<f[i][j])
{
f[i][j]=f[i][k]+f[k+1][j];
bj[i][j]=k;
}
}
Dfs(1,l);
for(int i=1;i<=l;i++)
if(a[i])
{
if(s[i]=='('||s[i]==')')printf("()");
else printf("[]");
}
else printf("%c",s[i]);
return 0;
}