//#pragma GCC optimize("Ofast,unroll-loops")
//#pragma GCC target("avx2,tune=native")
#include <bits/stdc++.h>
using namespace std;
#define file "parentheses"
using ll = long long;
using vi = vector<int>;
inline void rf(){
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
if (fopen(file".inp","r")){
freopen(file".inp","r",stdin);
freopen(file".out","w",stdout);
}
}
int main() {
rf();
string line;
if(!getline(cin, line)){ cout << 0 << "\n"; return 0; }
stringstream ss(line);
vector<int> cvec; int v;
while (ss >> v) cvec.push_back(v);
int n = (int)cvec.size();
if(n==0 || (n&1)){ cout << 0 << "\n"; return 0; }
map<int, vector<int>> pos;
for (int i=0;i<n;i++) pos[cvec[i]].push_back(i+1);
vector<vector<int>> groups;
vector<int> singles;
for (auto &p: pos) {
if ((int)p.second.size() >= 2) groups.push_back(p.second);
else singles.push_back(p.second[0]);
}
sort(singles.begin(), singles.end());
int m = (int)groups.size();
int k = (int)singles.size();
if (m > 25){ cout << 0 << "\n"; return 0; }
vector<int> boundary; boundary.push_back(0);
for(int x: singles) boundary.push_back(x);
boundary.push_back(n+1);
int B = (int)boundary.size()-1;
auto build_segments = [&](const vi &delta, vi &segSum, vi &segLow)->bool{
segSum.assign(B,0); segLow.assign(B,0);
for (int t=0;t<B;t++){
int L=boundary[t], R=boundary[t+1];
int cur=0, mn=0, sum=0;
for(int i=L+1;i<=R-1;i++){
cur += delta[i]; sum += delta[i];
if(cur < mn) mn = cur;
if(t==0 && cur<0) return false;
}
segSum[t]=sum; segLow[t]=mn;
}
return true;
};
vector<int> gsize(m);
for(int i=0;i<m;i++) gsize[i]=(int)groups[i].size();
vector<int> order(m); iota(order.begin(), order.end(), 0);
sort(order.begin(), order.end(),
[&](int a,int b){ return groups[a].back() < groups[b].back(); });
vector<int> suf(m+1,0);
for(int i=m-1;i>=0;--i) suf[i]=suf[i+1]+gsize[order[i]];
int open_min = max(0, n/2 - k), open_max = n/2;
vi delta(n+2,0), segSum, segLow;
ll ans = 0;
function<void(int,int)> dfs = [&](int idx, int open_fixed){
if(open_fixed>open_max) return;
if(open_fixed + suf[idx] < open_min) return;
if(idx==m){
int need = n/2 - open_fixed;
if(need<0 || need>k) return;
if(!build_segments(delta, segSum, segLow)) return;
if(k==0){ ans += (segSum[0]==0); return; }
if(segLow[0]<0) return;
static ll dp[2][55][26];
for(int a=0;a<2;a++) for(int b=0;b<=n;b++) for(int t=0;t<=need;t++) dp[a][b][t]=0;
int cur=0,nxt=1; dp[cur][segSum[0]][0]=1;
for(int i=0;i<k;i++){
for(int b=0;b<=n;b++) for(int t=0;t<=need;t++) dp[nxt][b][t]=0;
int segId=i+1;
for(int bal=0; bal<=n; ++bal){
for(int t=0; t<=need; ++t){
ll ways=dp[cur][bal][t];
if(!ways) continue;
if(t<need){
int b1=bal+1;
if(b1+segLow[segId]>=0){
int b2=b1+segSum[segId];
if(0<=b2 && b2<=n) dp[nxt][b2][t+1]+=ways;
}
}
if(bal>0){
int b1=bal-1;
if(b1+segLow[segId]>=0){
int b2=b1+segSum[segId];
if(0<=b2 && b2<=n) dp[nxt][b2][t]+=ways;
}
}
}
}
swap(cur,nxt);
}
int tailId=k; ll add=0;
for(int bal=0; bal<=n; ++bal){
ll ways=dp[cur][bal][need];
if(!ways) continue;
if(bal+segLow[tailId]>=0 && bal+segSum[tailId]==0) add+=ways;
}
ans+=add;
return;
}
int g = order[idx];
for(int p: groups[g]) delta[p]+=1;
dfs(idx+1, open_fixed + gsize[g]);
for(int p: groups[g]) delta[p]-=1;
for(int p: groups[g]) delta[p]-=1;
dfs(idx+1, open_fixed);
for(int p: groups[g]) delta[p]+=1;
};
dfs(0,0);
cout << ans << "\n";
return 0;
}