Problem:
Problem L: Select Sets
Problem
整数の集合が
N
個ある。 これらの集合にはそれぞれ1から
N
までの番号が割り振られている。
i
番目の集合の要素数は
K
i
であり、その集合の要素の中で
j
番目に小さい整数は
a
i,j
である。
太郎君はこの中から任意の数だけ集合を選ぶことになった。  ただ適当に選ぶだけではつまらないと思った太郎君は、少なくとも3つの集合を選ぶことにした。また、"選んだ集合の和集合の要素数"と"選んだ集合の積集合の要素数"の積ができるだけ大きくなるように選ぶことにした。
太郎君が最適に集合を選んだとき、"選んだ集合の和集合の要素数"と"選んだ集合の積集合の要素数"の積の最大値を求めよ。
Input
入力は以下の形式で与えられる。
N
K
1
a
1,1
a
1,2
...
a
1,K
1
K
2
a
2,1
a
2,2
...
a
2,K
2
...
K
N
a
N,1
a
N,2
...
a
N,K
N
Constraints
入力は以下の条件を満たす。
入力は全て整数である。
3 ≤
N
≤ 20,000
1 ≤
a
i,j
≤ 22
a
i,j
<
a
i,j+1
( 1 ≤
i
≤
N
)
    ( 1 ≤
j
<
K
i
)
Output
太郎君が最適に選んだときの"選んだ集合の和集合の要素数"と"選んだ集合の積集合の要素数"の積の最大値を出力せよ。
Sample Input 1
4
1 5
2 3 5
3 3 5 7
4 3 5 7 9
Sample Output 1
8
Sample Input 2
5
4 1 4 5 6
4 1 7 8 9
3 1 2 3
3 1 2 3
3 1 2 3
Sample Output 2
9
Sample Input 3
3
2 3 4
2 2 5
2 1 6
Sample Output 3
0

Submitted solutions:

code_snippet: // AOJ #3011 Select Sets
// 2025.3.21

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(int n) { // 整数の表示（出力）
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

int main(){
    int N = Cin();
    const int M = 22;
    int size = 1 << M;
    vector<int> freq(size, 0);
    for(int i = 0; i < N; i++){
        int k = Cin();
        int mask = 0;
        for(int j = 0; j < k; j++){
            int x = Cin()-1;
            mask |= (1 << x);
        }
        freq[mask]++;
    }

    vector<int> G(size, 0), B(size, 0);
    for (int s = 0; s < size; s++){
        G[s] = freq[s];
        B[s] = (freq[s] > 0 ? s : 0);
    }
    for (int i = 0; i < M; i++){
        for (int mask = 0; mask < size; mask++){
            if(!(mask & (1 << i))){
                G[mask] += G[mask | (1 << i)];
                B[mask] |= B[mask | (1 << i)];
            }
        }
    }
    int ans = 0;
    for (int I = 0; I < size; I++){
        if(G[I] >= 3){
            int U = B[I];
            int prod = __builtin_popcount(U) * __builtin_popcount(I);
            ans = max(ans, prod);
        }
    }
    Cout(ans);
    return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 52312
final_rank: 1

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<utility>
#include<set>
#include<map>
#include<stack>
using namespace std;
typedef long long ll;
const ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int> P;
typedef pair<ll, ll> LP;
typedef vector<int> vec;
typedef long double ld;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define stop char nyaa;cin>>nyaa;


void solve() {
	int n;
	cin >> n;
	vector<int> cnt(1 << 22), a(1 << 22);
	rep(i, n) {
		int k;
		cin >> k;
		int bit = 0;
		rep(i, k) {
			int x;
			cin >> x;
			bit += (1 << (x - 1));
		}
		++cnt[bit];
		a[bit] = bit;
	}
	rep(j, 22) {
		rep(i, 1 << 22) {
			if (i&(1 << j)) {
				cnt[i ^ (1 << j)] += cnt[i];
				a[i ^ (1 << j)] |= a[i];
			}
		}
	}
	int ans = 0;
	vector<int> b(1 << 22);
	rep(i, 1 << 22)rep(j, 22) {
		if (i&(1 << j))b[i]++;
	}
	rep(i, 1 << 22) {
		if (cnt[i] < 3)continue;
		ans = max(ans,b[i]*b[a[i]]);
	}
	cout << ans << endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(6);
	solve();
	//stop
		return 0;
}
accuracy: 1
time_ms: 320
memory_kb: 51924
final_rank: 5

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 22

int POW[NUM+1],RANK[4194304],max_union[4194304],num[4194304];
vector<int> STATE[NUM+1];
set<int> SET[4194304];


void calc(){

	int count;

	for(int state = 0; state < POW[NUM]; state++){
		count = 0;
		for(int loop = 0; loop < NUM; loop++){
			if(state & (1 << loop)){
				count++;
			}
		}
		RANK[state] = count;
		STATE[count].push_back(state);
	}
}


int main(){

	for(int i = 0; i < NUM+1; i++)POW[i] = pow(2,i);
	for(int i = 0; i < POW[NUM]; i++){
		num[i] = 0;
		max_union[i] = i;
	}

	calc();

	int N;
	scanf("%d",&N);

	int k,tmp,sum;
	for(int loop = 0; loop < N; loop++){
		scanf("%d",&k);
		sum = 0;
		for(int i = 0; i < k; i++){
			scanf("%d",&tmp);
			tmp--;
			sum += POW[tmp];
		}
		num[sum]++;
		SET[sum].insert(sum);
	}

	int current_state,plus_one_bit_state;
	int ans = 0,copy_count;

	for(int num_bit = NUM; num_bit >= 1; num_bit--){
		for(int k = 0; k < STATE[num_bit].size(); k++){
			current_state = STATE[num_bit][k];

			for(int add_bit = 0; add_bit < NUM; add_bit++){
				if(current_state & (1 << add_bit))continue;

				plus_one_bit_state = current_state+POW[add_bit];

				if(SET[plus_one_bit_state].size() > 0){

					set<int>::iterator it = SET[plus_one_bit_state].begin();
					copy_count = 0;
					while(SET[current_state].size()+copy_count < 3 && it != SET[plus_one_bit_state].end()){
						SET[current_state].insert(*it);
						it++;
						copy_count++;
					}
					max_union[current_state] |= max_union[plus_one_bit_state];
				}
			}

			if((SET[current_state].size() >= 3) ||
					(num[current_state] > 0 && num[current_state]+SET[current_state].size()-1 >= 3)){
				ans = max(ans,RANK[max_union[current_state]]*RANK[current_state]);
			}
		}
	}

	printf("%d\n",ans);

	return 0;
}
accuracy: 1
time_ms: 1550
memory_kb: 770232
final_rank: 11

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 22

int POW[NUM+1],RANK[4194304],max_union[4194304],pre_1[4194304];
vector<int> STATE[NUM+1];
set<int> SET[4194304];


void calc(){

	int count;

	for(int state = 0; state < POW[NUM]; state++){
		count = 0;
		for(int loop = 0; loop < NUM; loop++){
			if(state & (1 << loop)){
				count++;
			}
		}
		RANK[state] = count;
		STATE[count].push_back(state);
	}
}


int main(){

	for(int i = 0; i < NUM+1; i++)POW[i] = pow(2,i);
	for(int i = 0; i < POW[NUM]; i++){
		max_union[i] = i;
	}

	calc();

	int N;
	scanf("%d",&N);

	int k,tmp,sum;
	for(int loop = 0; loop < N; loop++){
		scanf("%d",&k);
		sum = 0;
		for(int i = 0; i < k; i++){
			scanf("%d",&tmp);
			tmp--;
			sum += POW[tmp];
		}
		SET[sum].insert(sum);
	}

	int current_state,plus_one_bit_state;
	int ans = 0,copy_count;

	for(int num_bit = NUM; num_bit >= 1; num_bit--){
		for(int k = 0; k < STATE[num_bit].size(); k++){
			current_state = STATE[num_bit][k];

			for(int add_bit = 0; add_bit < NUM; add_bit++){
				if(current_state & (1 << add_bit))continue;

				plus_one_bit_state = current_state+POW[add_bit];

				if(SET[plus_one_bit_state].size() > 0){

					set<int>::iterator it = SET[plus_one_bit_state].begin();
					copy_count = 0;
					while(copy_count < 3 && it != SET[plus_one_bit_state].end()){
						SET[current_state].insert(*it);
						it++;
						copy_count++;
					}
					max_union[current_state] |= max_union[plus_one_bit_state];
				}
			}

			if(SET[current_state].size() >= 3){
				ans = max(ans,RANK[max_union[current_state]]*RANK[current_state]);
			}
		}
	}

	printf("%d\n",ans);

	return 0;
}
accuracy: 0.08333333333333333
time_ms: 1160
memory_kb: 446412
final_rank: 15

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 22

int POW[NUM+1],RANK[4194304],num[4194304],max_union[4194304];
vector<int> STATE[NUM+1];


void calc(){

	int count;

	for(int state = 0; state < POW[NUM]; state++){
		count = 0;
		for(int loop = 0; loop < NUM; loop++){
			if(state & (1 << loop)){
				count++;
			}
		}
		RANK[state] = count;
		STATE[count].push_back(state);
	}
}


int main(){

	for(int i = 0; i < NUM+1; i++)POW[i] = pow(2,i);
	for(int i = 0; i < POW[NUM]; i++){
		num[i] = 0;
		max_union[i] = i;
	}

	calc();

	int N;
	scanf("%d",&N);

	int k,tmp,sum;
	for(int loop = 0; loop < N; loop++){
		scanf("%d",&k);
		sum = 0;
		for(int i = 0; i < k; i++){
			scanf("%d",&tmp);
			tmp--;
			sum += POW[tmp];
		}
		num[sum]++;
	}

	int current_state,plus_one_bit_state;
	int ans = 0,first_num;

	for(int num_bit = NUM; num_bit >= 1; num_bit--){
		for(int k = 0; k < STATE[num_bit].size(); k++){
			current_state = STATE[num_bit][k];
			first_num =  num[current_state];

			for(int add_bit = 0; add_bit < NUM; add_bit++){
				if(current_state & (1 << add_bit))continue;

				plus_one_bit_state = current_state+POW[add_bit];

				if(num[plus_one_bit_state] > 0){
					num[current_state] += num[plus_one_bit_state];
					max_union[current_state] |= max_union[plus_one_bit_state];
				}
			}

			if(first_num > 0 && num[current_state] >= 3){
				ans = max(ans,RANK[max_union[current_state]]*RANK[current_state]);
			}
		}
	}

	printf("%d\n",ans);

	return 0;
}
accuracy: 0.19444444444444445
time_ms: 290
memory_kb: 71436
final_rank: 12

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 22

int POW[NUM+1],RANK[4194304],num[4194304],max_union[4194304];
vector<int> STATE[NUM+1];


void calc(){

	int count;

	for(int state = 0; state < POW[NUM]; state++){
		count = 0;
		for(int loop = 0; loop < NUM; loop++){
			if(state & (1 << loop)){
				count++;
			}
		}
		RANK[state] = count;
	}
}


int main(){

	for(int i = 0; i < NUM+1; i++)POW[i] = pow(2,i);
	for(int i = 0; i < POW[NUM]; i++){
		num[i] = 0;
		max_union[i] = i;
	}

	calc();

	int N;
	scanf("%d",&N);

	int k,tmp,sum;
	for(int loop = 0; loop < N; loop++){
		scanf("%d",&k);
		sum = 0;
		for(int i = 0; i < k; i++){
			scanf("%d",&tmp);
			tmp--;
			sum += POW[tmp];
		}
		num[sum]++;
		STATE[RANK[sum]].push_back(sum);
	}

	for(int i = 1; i <= NUM; i++){
		sort(STATE[i].begin(),STATE[i].end());
		STATE[i].erase(unique(STATE[i].begin(),STATE[i].end()),STATE[i].end());
	}

	int current_state,plus_one_bit_state;
	int ans = 0;

	for(int num_bit = NUM; num_bit >= 1; num_bit--){
		for(int k = 0; k < STATE[num_bit].size(); k++){
			current_state = STATE[num_bit][k];

			for(int add_bit = 0; add_bit < NUM; add_bit++){
				if(current_state & (1 << add_bit))continue;

				plus_one_bit_state = current_state+POW[add_bit];

				if(num[plus_one_bit_state] > 0){
					num[current_state] += num[plus_one_bit_state];
					max_union[current_state] |= max_union[plus_one_bit_state];
				}
			}

			if(num[current_state] >= 3){
				ans = max(ans,RANK[max_union[current_state]]*RANK[current_state]);
			}
		}
	}

	printf("%d\n",ans);

	return 0;
}
accuracy: 0.1111111111111111
time_ms: 80
memory_kb: 52520
final_rank: 13

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 22

int POW[NUM+1],RANK[4194304],num[4194304],max_union[4194304];
vector<int> STATE[NUM];


void calc(){

	int count;

	for(int state = 0; state < POW[NUM]; state++){
		count = 0;
		for(int loop = 0; loop < NUM; loop++){
			if(state & (1 << loop)){
				count++;
			}
		}
		RANK[state] = count;
	}
}


int main(){

	for(int i = 0; i < NUM+1; i++)POW[i] = pow(2,i);
	for(int i = 0; i < POW[NUM]; i++){
		num[i] = 0;
		max_union[i] = i;
	}

	calc();

	int N;
	scanf("%d",&N);

	int k,tmp,sum;
	for(int loop = 0; loop < N; loop++){
		scanf("%d",&k);
		sum = 0;
		for(int i = 0; i < k; i++){
			scanf("%d",&tmp);
			tmp--;
			sum += POW[tmp];
		}
		num[sum]++;
		STATE[RANK[sum]].push_back(sum);
	}

	for(int i = 1; i <= NUM; i++){
		sort(STATE[i].begin(),STATE[i].end());
		STATE[i].erase(unique(STATE[i].begin(),STATE[i].end()),STATE[i].end());
	}

	int current_state,plus_one_bit_state;
	int ans = 0;

	for(int num_bit = NUM-1; num_bit >= 1; num_bit--){
		for(int k = 0; k < STATE[num_bit].size(); k++){
			current_state = STATE[num_bit][k];

			for(int add_bit = 0; add_bit < NUM; add_bit++){
				if(current_state & (1 << add_bit))continue;

				plus_one_bit_state = current_state+POW[add_bit];

				if(num[plus_one_bit_state] > 0){
					num[current_state] += num[plus_one_bit_state];
					max_union[current_state] |= max_union[plus_one_bit_state];
				}
			}

			if(num[current_state] >= 3){
				ans = max(ans,RANK[max_union[current_state]]*RANK[current_state]);
			}
		}
	}

	printf("%d\n",ans);

	return 0;
}
accuracy: 0.08333333333333333
time_ms: 60
memory_kb: 52588
final_rank: 14

code_snippet: #include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <string>
#include <algorithm>
#include <iostream>
#include <string>
#include <map>
#include <set>
#include <functional>
#include <iostream>
#define MOD 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

int n;
int k[20001],bit[20001];

int dp[1<<22];
set<int> cnt[1<<22];

int main(void){
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&k[i]);
		for(int j=0;j<k[i];j++){
			int a=0;
			scanf("%d",&a);
			a--;
			bit[i]+=(1<<a);
		}
		dp[bit[i]]=bit[i];
		if(cnt[bit[i]].size()<3)cnt[bit[i]].insert(i);
	}
	int res=0;
	for(int i=(1<<22)-1;i>=0;i--){
		for(int j=0;j<22;j++){
			if(!((i>>j) & 1)){
				dp[i]|=dp[i+(1<<j)];
				set<int>::iterator it=cnt[i+(1<<j)].begin();
				while(cnt[i].size()<3 && it!=cnt[i+(1<<j)].end()){
					cnt[i].insert(*it);
					it++;
				}
			}
		}
		if(cnt[i].size()==3){
			int v=__builtin_popcount(i)*__builtin_popcount(dp[i]);
			res=max(res,v);
		}
	}
	printf("%d\n",res);
	return 0;
}
accuracy: 1
time_ms: 890
memory_kb: 805904
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;

#define MAX 22

int N,ans=0;
int A[(1<<MAX)];
int dp[(1<<MAX)];
int prx[(1<<MAX)];
int pry[(1<<MAX)];
int prz[(1<<MAX)];

void insert(int &a,int &b,int &c,int x){
  if(x==-1||a==x||b==x||c==x)return;
  c=b;
  b=a;
  a=x;
}

int main(){
  scanf("%d",&N);
  for(int i=0;i<N;i++){
    int k,a,bit=0;
    scanf("%d",&k);
    for(int j=0;j<k;j++){
      scanf("%d",&a);
      a--;
      bit|=(1<<a);
    }
    A[bit]++;
  }
  
  for(int i=(1<<MAX)-1;i>0;i--){
    int a=-1,b=-1,c=-1;
    if(A[i]){
      dp[i]=i;
      a=i;
    }
    
    for(int j=0;j<MAX;j++){
      int nbit=i|(1<<j);
      if(i==nbit)continue;
      dp[i]|=dp[nbit];
      insert(a,b,c,prx[nbit]);
      insert(a,b,c,pry[nbit]);
      insert(a,b,c,prz[nbit]);
    }
    prx[i]=a;
    pry[i]=b;
    prz[i]=c;
    int cnt=0;
    if(a!=-1)cnt+=A[a];
    if(b!=-1)cnt+=A[b];
    if(c!=-1)cnt+=A[c];
    if(cnt>=3)ans=max(ans,__builtin_popcount(i)*__builtin_popcount(dp[i]));
  }
  printf("%d\n",ans);
  return 0;
}
accuracy: 1
time_ms: 950
memory_kb: 84984
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int N=22,Z=(1<<N)-1;
int f[1<<N],d[1<<N],n,ans;
set<int> s[1<<N];
void zeta(){
  for(int i=0; i<N; i++) {
    for(int j=0; j<(1<<N); j++) {
      if(j&1<<i) continue;
      f[j]&=f[j|(1<<i)];
      d[j]|=d[j|(1<<i)];
      for(set<int>::iterator it=s[j|(1<<i)].begin(); it!=s[j|(1<<i)].end()&&s[j].size()<3; it++) s[j].insert(*it);
    }
  }
}
int main() {
  fill(f,f+(1<<N),Z);
  cin >> n;
  for(int i=0; i<n; i++) {
    int x=0,y,k;
    cin >> k;
    for(int j=0; j<k; j++) {
      cin >> y;
      x|=1<<(y-1);
    }
    f[x]=d[x]=x;
    s[x].insert(i);
  }
  zeta();
  for(int i=0; i<(1<<N)-1; i++) {
    if(s[i].size()>=3) ans=max(ans,__builtin_popcount(f[i])*__builtin_popcount(d[i]));
  }
  cout << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 1220
memory_kb: 822268
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long LL;

#define CIN_ONLY if(1)
struct cww{cww(){
    CIN_ONLY{
        ios::sync_with_stdio(false);cin.tie(0);
    }
}}star;
#define fin "\n"
#define FOR(i,bg,ed) for(int i=(bg);i<(ed);i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
#define fi first
#define se second
#define pb push_back
#define DEBUG if(0)
#define REC(ret, ...) std::function<ret (__VA_ARGS__)>
template <typename T>inline bool chmin(T &l,T r)
{bool a=l>r;if(a)l=r;return a;}
template <typename T>inline bool chmax(T &l,T r)
{bool a=l<r;if(a)l=r;return a;}
template <typename T>
istream& operator>>(istream &is,vector<T> &v){
    for(auto &it:v)is>>it;
    return is;
}
#define CNT __builtin_popcount
const int M=1<<22;
int s[M];
int id[M][3];
int main(){
    int N;
    cin>>N;
    REP(i,M)REP(j,3)id[i][j]=-1;
    REP(i,N){
        int k;cin>>k;
        int a=0;
        REP(j,k){
            int b;cin>>b;
            a|=(1<<(b-1));
        }
        s[a]=a;
        k=0;
        for(;k<2&&id[a][k]!=-1;k++);
        id[a][k]=i;
    }
    int res=0;
    FOR(i,1,M+1){
        int bit=M-i;
        int cnt=0;
        for(;cnt<3&&id[bit][cnt]!=-1;cnt++);
        REP(j,22){
            int nxt=bit|(1<<j);
            s[bit]|=s[nxt];
            REP(k,3){
                if(cnt==3||id[nxt][k]==-1)break;
                if(id[nxt][k]!=id[bit][0]&&id[nxt][k]!=id[bit][1]&&id[nxt][k]!=id[bit][2])
                    id[bit][cnt++]=id[nxt][k];
            }
        }
        if(id[bit][2]!=-1)
            chmax(res,CNT(bit)*CNT(s[bit]));
    }
    cout<<res<<endl;
    return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 68740
final_rank: 4

code_snippet: #include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

typedef int _loop_int;
#define REP(i,n) for(_loop_int i=0;i<(_loop_int)(n);++i)
#define FOR(i,a,b) for(_loop_int i=(_loop_int)(a);i<(_loop_int)(b);++i)
#define FORR(i,a,b) for(_loop_int i=(_loop_int)(b)-1;i>=(_loop_int)(a);--i)

#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define DEBUG_VEC(v) cout<<#v<<":";REP(i,v.size())cout<<" "<<v[i];cout<<endl
#define ALL(a) (a).begin(),(a).end()

#define CHMIN(a,b) a=min((a),(b))
#define CHMAX(a,b) a=max((a),(b))

// mod
const ll MOD = 1000000007ll;
#define FIX(a) ((a)%MOD+MOD)%MOD

// floating
typedef double Real;
const Real EPS = 1e-11;
#define EQ0(x) (abs(x)<EPS)
#define EQ(a,b) (abs(a-b)<EPS)
typedef complex<Real> P;

// 0 : max sum
// 1 : three count
// 2 : id 1
// 3 : id 2
int dp[1<<22][4];

int main(){
  // init
  REP(i,1<<22){
    dp[i][0] = 0;
    dp[i][1] = false;
    dp[i][2] = dp[i][3] = -1;
  }
  int n;
  scanf("%d",&n);
  REP(i,n){
    int id = 0;
    int k;
    scanf("%d",&k);
    REP(j,k){
      int a;
      scanf("%d",&a);
      id |= (1<<(a-1));
    }
    dp[id][0] |= id;
    if(!dp[id][1]){
      if(dp[id][2]==-1){
        dp[id][2] = i;
      }else if(dp[id][2]!=i){
        if(dp[id][3]==-1){
          dp[id][3] = i;
        }else if(dp[id][3]!=i){
          dp[id][1] = true;
        }
      }
    }
  }
  FORR(i,1,1<<22){
    REP(j,22)if(i&(1<<j)){
      int to = i ^ (1<<j);
      dp[to][0] |= dp[i][0];
      if(dp[i][1]){
        dp[to][1] = true;
      }else if(!dp[to][1]){
        if(dp[i][2]!=-1){
          int add = dp[i][2];
          if(dp[to][2]==-1){
            dp[to][2] = add;
          }else if(dp[to][2]!=add){
            if(dp[to][3]==-1){
              dp[to][3] = add;
            }else if(dp[to][3]!=add){
              dp[to][1] = true;
            }
          }
        }
        if(dp[i][3]!=-1){
          int add = dp[i][3];
          if(dp[to][2]==-1){
            dp[to][2] = add;
          }else if(dp[to][2]!=add){
            if(dp[to][3]==-1){
              dp[to][3] = add;
            }else if(dp[to][3]!=add){
              dp[to][1] = true;
            }
          }
        }
      }
    }
  }
  int ans = 0;
  REP(i,1<<22)if(dp[i][1]){
    CHMAX(ans, __builtin_popcount(i) * __builtin_popcount(dp[i][0]));
  }
  printf("%d\n",ans);
  return 0;
}
accuracy: 1
time_ms: 310
memory_kb: 68716
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;

#define int long long

#define rep(i,n) for(int i=0;i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define pb push_back
#define fi first
#define se second

typedef vector<int>vint;
typedef pair<int,int>pint;
typedef vector<pint>vpint;

template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

int N;

int C[1<<22];
int O[1<<22];
bool ex[1<<22];

short cnt[1<<22][22];

signed main(){
    scanf("%lld",&N);
    rep(i,N){
        int x=0;
        int k;scanf("%lld",&k);
        while(k--){
            int a;scanf("%lld",&a);
            a--;
            x^=1<<a;
        }
        cnt[x][0]++;
        O[x]=x;
    }

    for(int i=1<<22;i>=0;i--){
        for(int j=0;j<22;j++){
            if(i>>j&1)O[i^(1<<j)]|=O[i];
        }
    }

    int ans=0;

    for(int i=1<<22;i>=0;i--){
        for(int j=0;j<22;j++){
            if(i>>j&1){
                cnt[i^(1<<j)][j]+=cnt[i][j];
            }
            if(j!=21)cnt[i][j+1]+=cnt[i][j];
        }
        if(cnt[i][21]>=3)chmax(ans,__builtin_popcount(i)*__builtin_popcount(O[i]));
    }
    cout<<ans<<endl;
}
accuracy: 1
time_ms: 510
memory_kb: 216216
final_rank: 7

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

#define rep(i, N) for (int i = 0; i < N; i++)

int main() {
	int N; cin >> N;
	vector<int> a(N);
	rep(i, N) {
		int K; scanf("%d", &K);
		while (K--) {
			int x; scanf("%d", &x);
			a[i] |= 1<<(x - 1);
		}
	}
	int M = 22;
	vector<int> dp(1<<M);
	rep(i, N) dp[a[i]] = a[i];
	for (int S = (1<<M) - 1; S >= 0; S--)
		rep(i, M) if (!(S>>i & 1)) {
			int _S = S | 1<<i;
			dp[S] |= dp[_S];
		}
	int ma = 0;
	rep(S, 1<<M) {
		int k1 = 0, k2 = 0;
		rep(i, M) {
			if (S>>i & 1) k1++;
			if (dp[S]>>i & 1) k2++;
		}
		int ans = k1 * k2;
		if (ans <= ma) continue;
		int cnt = 0;
		rep(i, N) if ((a[i] & S) == S) cnt++;
		if (cnt >= 3) ma = max(ma, ans);
	}
	cout << ma << endl;
}
accuracy: 1
time_ms: 300
memory_kb: 19220
final_rank: 3

code_snippet: #include <bits/stdc++.h>
#define rep(i,N) for(int i=0;i<N;i++)
#define chmax(x,y) x=max(x,y)
#define show(x) cout<<#x<<" "<<x<<endl
using namespace std;
int N;
int b[1<<22];
int bo[1<<22];
void zetan(int* f,int N){
	rep(i,N) rep(j,1<<N) if(0==(j&1<<i)) f[j]+=f[j|(1<<i)];
}
void zetao(int* f,int N){
	rep(i,N) rep(j,1<<N) if(0==(j&1<<i)) f[j]|=f[j|(1<<i)];
}

int pc(int x){
	if(x==0) return 0;
	return __builtin_popcount(x);
}
int main(){
	int N;
	cin>>N;
	rep(i,N){
		int k;
		cin>>k;
		int v=0;
		rep(i,k){
			int x;
			cin>>x;
			x--;
			v|=1<<x;
		}
		b[v]++;
		bo[v]=v;
	}
	zetan(b,22);
	zetao(bo,22);
	int ans = 0;
	rep(i,1<<22) if(b[i]>=3){
//		show(i);
//		show(bo[i]);
		chmax(ans,pc(i)*pc(bo[i]));
	}
	cout<<ans<<endl;
}
accuracy: 1
time_ms: 190
memory_kb: 35808
final_rank: 2