Problem:
Whispering Game
PCK is planning a message game as entertainment for his friend's birthday party.
Five party participants line up in a horizontal line and challenge each other in a message game. If the message is correctly conveyed to the person on the right, the challenge is successful and prizes are given to the five participants. However, in order to convey the message correctly, the speaker and the listener must be able to use a common language.
The party will bring together friends from all over the world, and to estimate the budget for the prizes, PCK decides to calculate the number of ways the participants can line up for the message game to be successful.
Given the number of people attending the party, and a list of languages that each participant can use, write a program to find the number of ways in which the message game can succeed.
Input
The input is given in the following format.
$N$
$info_1$
$info_2$
:
$info_N$
The first line gives the number of participants in the party, $N$ ($5 \leq N \leq 200$). In the following $N$ lines, information on the languages available to the $i$th participant is given. The $info_i$ is given in the following format.
$k$ $l_1$ $l_2$ ... $l_k$
$k$ ($1 \leq k \leq 200$) is the number of languages this participant can use. The $l_i$ is the string (two lowercase letters) that represents the languages that this participant can use. However, there is no overlap in the languages available to the same participant (if $i \ne j$, then $l_i \ne l_j$).
Output
Output the number of ways the participants can be lined up for a successful message game on a single line.
Sample Input and Output
Sample Input 1
5
2 ja en
2 ja en
2 ja en
2 ja en
2 ja en
Sample Output 1
120
Sample Input 2
6
1 ja
3 ja en ch
2 en fr
2 ve fr
3 ch ve po
1 po
Sample Output 2
8

Submitted solutions:

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

#define rep(i,n) for(int i=0;i<(n);i++)
#define rng(i,l,r) for(int i=(l);i<(r);i++)
#define rrep(i,n) for(int i=(n)-1;i>=0;i--)
#define rrng(i,l,r) for(int i=(r)-1;i>=(l);i--)
#define int long long
#define fi first
#define se second
#define pb push_back
#define all(x) (x).begin(),(x).end()

signed main(){
	int N;cin>>N;
	vector<int> K(N);
	vector<vector<string>> vs(N);
	vector<vector<int>> g(N,vector<int>(N));
	rep(i,N){
		cin>>K[i];
		vs[i].resize(K[i]);
		for(auto&&e:vs[i])cin>>e;
	}
	
	rep(i,N)rep(j,N){
		if(i==j)continue;
		set<string> st(all(vs[i]));
		for(auto&&e:vs[j])if(st.count(e))g[i][j]=1;
	}
	
	
	vector<int> dsm(N);
	rep(i,N)dsm[i]=accumulate(all(g[i]),0LL);
	
	vector<vector<int>> cnt(N,vector<int>(N));
	rep(i,N)rep(j,N)rep(k,N){
		if(g[i][k]&&g[j][k])cnt[i][j]++;
	}
	
	
	int ans=0;
	rep(i,N)rep(j,N)rep(k,N){
		if(i==j||j==k||k==i)continue;
		if(g[i][k]&&g[j][k]){
			int a=dsm[i]-1-g[i][j],b=dsm[j]-1-g[i][j],c=cnt[i][j]-1;
			a-=c,b-=c;
			ans+=a*(b+c)+c*(b+c-1);
		}
	}
	
	cout<<ans<<"\n";
}
accuracy: 1
time_ms: 270
memory_kb: 4616
final_rank: 18

code_snippet: #include <iostream>
#include <set>
#include <map>
#include <vector>

#define REP(i,s,n) for(int i=(int)(s);i<(int)(n);i++)

using namespace std;
typedef long long ll;

int main(void){
    int n;
    cin >> n;
    vector<set<string>> langs(n);
    REP(i, 0, n) {
        int k;
        cin >> k;
        set<string> xs;
        REP(_, 0, k) {
            string tmp;
            cin >> tmp;
            xs.insert(tmp);
        }
        langs[i] = xs;
    }
    vector<vector<int>> g(n, vector<int>(n, 0));
    REP(i, 0, n) {
        REP(j, i + 1, n) {
            bool ok = false;
            for (auto x: langs[i]) {
                if (langs[j].count(x)) {
                    ok = true;
                    break;
                }
            }
            if (ok) g[i][j] = g[j][i] = 1;
        }
    }
    vector<int> deg(n);
    REP(i, 0, n) REP(j, 0, n) deg[i] += g[i][j];
    vector<ll> path2(n);
    REP(i, 0, n) {
        REP(j, 0, n) {
            if (g[i][j]) path2[i] += deg[j] - 1;
        }
    }
    // 包除原理の要領で、
    // v1 = v4 (-1), v1 = v5 (-1), v2 = v4 (-1), v2 = v5 (-1),
    // v1 = v4 and v2 = v5 (+1), v1 = v5 and v2 = v4 (+1)
    // のパターンを数える
    ll t0 = 0;
    ll t1 = 0;
    ll t2 = 0;
    ll t3 = 0;
    ll t5 = 0;
    ll t6 = 0;
    REP(i, 0, n) {
        t0 += path2[i] * path2[i];
        REP(j, 0, n) {
            if (g[i][j]) t3 += (deg[j] - 1) * (deg[j] - 1);
        }
        t6 += path2[i];
    }
    REP(i, 0, n) REP(j, 0, n) if (g[i][j]) {
        REP(k, 0, n) {
            if (g[i][k] && g[j][k]) {
                t1 += deg[k] - 1;
                t5 += 1;
            }
        }
    }
    REP(i, 0, n) REP(j, i + 1, n) {
        ll s = 0;
        REP(k, 0, n) s += g[i][k] && g[j][k];
        t2 += s * s * 2;
    }
    cout << t0 - t1 * 2 - t2 - t3 + t5 + t6 << "\n";
}
accuracy: 1
time_ms: 30
memory_kb: 5044
final_rank: 12

code_snippet: #include <iostream>
#include <set>
#include <map>
#include <vector>

#define REP(i,s,n) for(int i=(int)(s);i<(int)(n);i++)

using namespace std;
typedef long long ll;

vector<string> reg;
map<string, int> inv;

int put(const string &s) {
    if (inv.count(s)) {
        return inv[s];
    }
    int idx = reg.size();
    inv[s] = idx;
    reg.push_back(s);
    return idx;
}

int main(void){
    int n;
    cin >> n;
    vector<set<int>> langs(n);
    REP(i, 0, n) {
        int k;
        cin >> k;
        set<int> xs;
        REP(_, 0, k) {
            string tmp;
            cin >> tmp;
            int idx = put(tmp);
            xs.insert(idx);
        }
        langs[i] = xs;
    }
    vector<vector<int>> g(n, vector<int>(n, 0));
    REP(i, 0, n) {
        REP(j, i + 1, n) {
            bool ok = false;
            for (auto x: langs[i]) {
                if (langs[j].count(x)) {
                    ok = true;
                    break;
                }
            }
            if (ok) g[i][j] = g[j][i] = 1;
        }
    }
    vector<int> deg(n);
    REP(i, 0, n) REP(j, 0, n) deg[i] += g[i][j];
    vector<ll> path2(n);
    REP(i, 0, n) {
        REP(j, 0, n) {
            if (g[i][j]) path2[i] += deg[j] - 1;
        }
    }
    // 包除原理の要領で、
    // v1 = v4 (-1), v1 = v5 (-1), v2 = v4 (-1), v2 = v5 (-1),
    // v1 = v4 and v2 = v5 (+1), v1 = v5 and v2 = v4 (+1)
    // のパターンを数える
    ll t0 = 0;
    ll t1 = 0;
    ll t2 = 0;
    ll t3 = 0;
    ll t5 = 0;
    ll t6 = 0;
    REP(i, 0, n) {
        t0 += path2[i] * path2[i];
        REP(j, 0, n) {
            if (g[i][j]) t3 += (deg[j] - 1) * (deg[j] - 1);
        }
        t6 += path2[i];
    }
    REP(i, 0, n) REP(j, 0, n) if (g[i][j]) {
        REP(k, 0, n) {
            if (g[i][k] && g[j][k]) {
                t1 += deg[k] - 1;
                t5 += 1;
            }
        }
    }
    REP(i, 0, n) REP(j, i + 1, n) {
        ll s = 0;
        REP(k, 0, n) s += g[i][k] && g[j][k];
        t2 += s * s * 2;
    }
    cout << t0 - t1 * 2 - t2 - t3 + t5 + t6 << "\n";
}
accuracy: 1
time_ms: 20
memory_kb: 4608
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;
//#include<atcoder/all>
//using namespace atcoder;
//using mint = modint998244353;
#define int long long
signed main() {
  int n;
  cin >> n;
  vector<vector<vector<bool>>> ok(n,vector<vector<bool>>(26,vector<bool>(26)));
  for(int i = 0; i < n; i++) {
    int m;
    cin >> m;
    while(m--) {
      string s;
      cin >> s;
      ok[i][s[0]-'a'][s[1]-'a'] = true;
    }
  }
  vector<vector<bool>> f(n,vector<bool>(n,false));
  for(int i = 0; i < n; i++) {
    for(int j = i+1; j < n; j++) {
      for(int k = 0; k < 26; k++) {
        for(int l = 0; l < 26; l++) if(ok[i][k][l] && ok[j][k][l]) {
          f[i][j] = true;
          f[j][i] = true;
          break;
        }
        if(f[i][j]) break;
      }
    }
  }
  vector<bitset<200>> b(n);
  for(int i = 0; i < n; i++) {
    for(int j = 0; j < n; j++) if(f[i][j]) b[i].set(j,1);
  }
  int ans = 0;
  for(int i = 0; i < n; i++) {
    vector<int> c(n,0);
    for(int j = 0; j < n; j++) {
      if(i == j) continue;
      for(int k = 0; k < n; k++) if(i != k && f[j][k]) c[j]++;
    }
    for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) {
      if(i == j || j == k || k == i) continue;
      if(!f[i][j] || !f[i][k]) continue;
      int x = c[j], y = c[k];
      if(f[j][k]) x--,y--;
      ans+=x*y;
      bitset<200> z = (b[j]&b[k]);
      int co = z.count();
      ans-=co-1;
      
    }
  }
  cout << ans << endl;
}
accuracy: 1
time_ms: 100
memory_kb: 3760
final_rank: 15

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

int main() {
    // input
    int n; cin >> n;
    map<string, vector<int>> Map;
    for (int i = 0; i < n; i++) {
        int k; cin >> k;
        for (int j = 0; j < k; j++) {
            string v; cin >> v;
            Map[v].push_back(i);
        }
    }

    // get connect
    vector<vector<bool>> connect(n, vector<bool>(n, false));
    vector<vector<int>> common(n, vector<int>(n, 0));
    vector<int> deg(n, 0);
    for (auto [a, b] : Map) {
        for (int i = 0; i < b.size(); i++) {
            for (int j = i + 1; j < b.size(); j++) {
                connect[b[i]][b[j]] = true;
                connect[b[j]][b[i]] = true;
            }
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (connect[i][j] == true) {
                deg[i] += 1;
            }
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            for (int k = 0; k < n; k++) {
                if (connect[i][k] == true && connect[j][k] == true) {
                    common[i][j] += 1;
                }
            }
        }
    }

    // search
    ll ans = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            for (int k = 0; k < n; k++) {
                if (connect[i][j] == false) continue;
                if (connect[i][k] == false) continue;
                if (j == k) continue;
                int ways_j = deg[j] - 1 - (connect[j][k] == true ? 1 : 0);
                int ways_k = deg[k] - 1 - (connect[k][j] == true ? 1 : 0);
                int ways = ways_j * ways_k;
                ways -= (common[j][k] - 1);
                // cerr << i << " " << j << " " << k << " " << ways_j << " " << ways_k << " " << ways << endl;
                ans += ways;
            }
        }
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3816
final_rank: 6

code_snippet: #include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
#include <set>
using ll = long long;
using namespace std;

int main(){
	int N;cin >> N;
	vector<set<string>> ss(N);
	for (int i = 0;i < N;i++) {
		int k;cin >> k;
		while (k--) {
			string t;cin >> t;
			ss[i].insert(t);
		}
	}
	vector<vector<bool>> A(N, vector<bool>(N, false));
	vector<vector<int>> C(N, vector<int>(N, 0));
	vector<ll> D(N);
	for (int i = 0;i < N;i++) for (int j = 0;j < N;j++) {
		if (i == j) continue;
		bool flg = false;
		for (auto x : ss[i]) if (ss[j].find(x) != ss[j].end()) flg = true;
		if (!flg) continue;
	
		A[i][j] = true;
		D[i]++;
	}
	vector<ll> S(N, 0);
	for (int a = 0;a < N;a++) for (int b = 0;b < N;b++) for (int c = 0;c < N;c++) {
		if (a == b || b == c || a == c) continue;
		if (A[a][b] && A[b][c]) S[a]++;
		if (A[a][c] and A[b][c]) {
			C[a][b]++;
		}
	}
	ll res = 0;
	int nvv = 0;
	for (int a = 0;a < N;a++) for (int b = 0;b < N;b++) for (int c = 0;c < N;c++) {
		if (a == b || b == c || a == c) continue;
		if (!A[a][b] or !A[b][c]) continue;
		ll X = S[c];
		X -= D[b] - 1;
		if (A[a][c]) X -= D[a] - 1;
		
		
		//e = b
		X -= C[c][b] - (A[c][a]&&A[b][a] ? 1 : 0);
		X -= C[c][a] - (A[c][b]&&A[a][b] ? 1 : 0);
		int nvs = 0;
		
		
		res += X;
		nvv += nvs;
		
	}
	cout << res << endl;
	
	
	
}
accuracy: 1
time_ms: 270
memory_kb: 5376
final_rank: 19

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

using namespace std;

#define rep(i, l, n) for(int i = int(l); i < int(n); i++)
#define ll long long
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()

template<class T> bool chmin(T &a, T b) {if(a > b) {a = b; return true;} return false;}
template<class T> bool chmax(T &a, T b) {if(a < b) {a = b; return true;} return false;}
template<class T> using spq = priority_queue<T, vector<T>, greater<T>>;

// bool -> Yes/No
string answer(bool b) {return b ? "Yes" : "No";}

void fix(int k) {cout << fixed << setprecision(k);}

const int inf = 2e9;
const long long INF = 2e18;
const long double eps = 1e-12;
const long double pi = acos(-1);
int dx[] = {0, -1, 0, 1, -1, -1, 1, 1}, dy[] = {1, 0, -1, 0, 1, -1, -1, 1};

void main_program() {
    int n; cin >> n;
    int con[n][n];
    rep(i, 0, n) rep(j, 0, n) con[i][j] = 0;
    vector<int> lang[676];
    rep(i, 0, n) {
        int k; cin >> k;
        while(k--) {
            string s; cin >> s;
            int b = (s[0] - 'a') * 26 + (s[1] - 'a');
            lang[b].emplace_back(i);
        }
    }
    rep(i, 0, 676) {
        rep(j, 0, lang[i].size()) rep(k, j + 1, lang[i].size()) {
            con[lang[i][j]][lang[i][k]] = 1;
            con[lang[i][k]][lang[i][j]] = 1;
        }
    }
    int cnt[n];
    int dup[n][n];
    rep(i, 0, n) {
        cnt[i] = 0;
        rep(j, 0, n) if(con[i][j]) cnt[i]++;
    }
    rep(i, 0, n) rep(j, 0, n) {
        dup[i][j] = 0;
        rep(k, 0, n) dup[i][j] += con[i][k] * con[j][k];
    }
    ll ans = 0;
    // 適当に３人選ぶ
    rep(a, 0, n) rep(b, 0, n) rep(c, 0, n) {
        if(a == b || b == c || c == a) continue;
        if(!con[a][b] || !con[b][c]) continue;
        // aの左に並ぶ人を選ぶ -> d
        // eの右に並ぶ人を選ぶ -> e
        // con[a][d] = 1
        // con[c][e] = 1 && d != e
        int t = con[a][c];
        ans += (ll)(cnt[a] - 1 - t) * (ll)(cnt[c] - 1 - t) - (dup[a][c] - 1);
    }
    cout << ans << "\n";
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int T = 1;
    //cin >> T;
    while(T--) {
        main_program();
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3840
final_rank: 2

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

int main(){
	long long n;
	cin >> n;
	long long m = 26ll * 26ll;
	vector<vector<long long>> a(n);
	for(long long i = 0ll;i < n;i++){
		long long c;
		cin >> c;
		a[i].resize(c);
		for(long long j = 0ll;j < c;j++){
			string s;
			cin >> s;
			long long it = (s[0ll] - 'a') * 26ll + (s[1ll] - 'a');
			a[i][j] = it;
		}
	}
	vector<vector<long long>> g(n,vector<long long>(n,false));
	vector<vector<long long>> cou(n,vector<long long>(n,0ll));
	for(long long i = 0ll;i < n;i++){
		for(long long j = i + 1ll;j < n;j++){
			[&]{
				for(long long k : a[i]){
					for(long long l : a[j]){
						if(k == l){
							g[i][j] = true;
							g[j][i] = true;
						}
					}
				}
			}();
		}
	}
	for(long long i = 0ll;i < n;i++){
		for(long long j = 0ll;j < n;j++){
			if(i == j) continue;
			for(long long k = 0ll;k < n;k++){
				if(g[i][k] && g[j][k]){
					cou[i][j]++;
				}
			}
		}
	}
	vector<long long> v(n,0ll);
	for(long long i = 0ll;i < n;i++){
		for(long long j = 0ll;j < n;j++){
			if(g[i][j]) v[i]++;
		}
	}
	long long ans = 0ll;
	for(long long i = 0ll;i < n;i++){
		for(long long j = 0ll;j < n;j++){
			if(i == j) continue;
			if(!g[i][j]) continue;
			for(long long k = 0ll;k < n;k++){
				if(i == k || j == k) continue;
				if(!g[j][k]) continue;
				pair<long long,long long> it = {v[i] - 1ll - (g[i][k] ? 1ll : 0ll),v[k] - 1ll - (g[i][k] ? 1ll : 0ll)};
				pair<long long,long long> x = {it.first - (cou[i][k] - 1ll),it.second - (cou[i][k] - 1ll)};
				long long p = x.first * it.second + (it.first - x.first) * (it.second - 1ll);
				ans += p;
			}
		}
	}
	cout << ans << endl;
}
accuracy: 1
time_ms: 160
memory_kb: 4160
final_rank: 16

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
using ll = long long;
bool chmin(ll &a,ll b){
  if(a>b){
    a=b;
    return true;
  }
  return false;
}
int main(){
  ll n;
  cin>>n;
  vector<vector<ll>> g(n,vector<ll>(n));
  ll ans=0;
  map<string,vector<ll>> m;
  for(int i=0;i<n;i++){
    ll k;
    cin>>k;
    for(int j=0;j<k;j++){
      string s;
      cin>>s;
      m[s].push_back(i);
    }
  }
  for(auto e:m){
    for(int i=0;i<e.se.size();i++){
      for(int j=i+1;j<e.se.size();j++){
        g[e.se[i]][e.se[j]]=g[e.se[j]][e.se[i]]=1;
      }
    }
  }
  for(int i=0;i<n;i++){
    for(int j=0;j<n;j++){
      if(i==j) continue;
      ll x=0,y=0,z=0;
      for(int k=0;k<n;k++){
        if(i==k||j==k) continue;
        if(g[i][k]) x++;
        if(g[j][k]) y++;
        if(g[i][k]&&g[j][k]) z++;
      }
      ans+=z*((x-1)*(y-1)-(z-1));
    }
  }
  cout<<ans<<endl;
}
accuracy: 1
time_ms: 20
memory_kb: 4032
final_rank: 4

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

const int M{26 * 26};

int main() {
    int N;
    std::cin >> N;
    std::vector<std::bitset<M>> L(N);
    for (int i{} ; i < N ; i++) {
        int k;
        std::cin >> k;
        while (k--) {
            char a, b;
            std::cin >> a >> b;
            L[i][(a - 'a') * 26 + (b - 'a')] = true;
        }
    }
    std::vector G(N, std::vector<bool>(N));
    for (int i{} ; i < N ; i++) {
        for (int j{i + 1} ; j < N ; j++) {
            if (std::bitset<M>(L[i] & L[j]).count()) {
                G[i][j] = G[j][i] = true;
            }
        }
    }
    std::vector<int> cnt(N);
    for (int i{} ; i < N ; i++) {
        cnt[i] = (int)std::count(G[i].begin(), G[i].end(), true);
    }
    std::vector both(N, std::vector<int>(N)); 
    for (int i{} ; i < N ; i++) {
        for (int j{} ; j < N ; j++) {
            if (i == j) continue;
            for (int k{} ; k < N ; k++) {
                if (i == k or j == k) continue;
                if (G[i][k] and G[j][k]) both[i][j]++;
            }
        }
    }
    long long ans{};
    for (int i{} ; i < N ; i++) {
        for (int j{} ; j < N ; j++) {
            if (i == j) continue;
            if (!G[i][j]) continue;
            for (int k{} ; k < N ; k++) {
                if (i == k or j == k) continue;
                if (!G[j][k]) continue;
                if (G[i][k]) {
                    ans += (cnt[i] - 2) * (cnt[k] - 2) - (both[i][k] - 1); 
                }
                else {
                    ans += (cnt[i] - 1) * (cnt[k] - 1) - (both[i][k] - 1);
                }
            }
        }
    }
    std::cout << ans << '\n';
}
accuracy: 1
time_ms: 40
memory_kb: 3688
final_rank: 5

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

int main() {
    int n;
    std::cin >> n;
    std::vector graph(n, std::vector<bool>(n));
    std::vector<std::set<std::string>> info(n);
    for (int i = 0; i < n; i++) {
        int k;
        std::cin >> k;
        for (int j = 0; j < k; j++) {
            std::string s;
            std::cin >> s;
            info[i].insert(s);
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            for (auto s: info[i]) {
                if (info[j].find(s) != info[j].end()) {
                    graph[i][j] = true;
                    graph[j][i] = true;
                    break;
                }
            }
        }
    }
    std::vector<int> outdeg(n);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (graph[i][j]) {
                outdeg[i]++;
            }
        }
    }
    std::vector intersection(n, std::vector<int>(n));
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            for (int k = 0; k < n; k++) {
                if (graph[i][k] && graph[j][k]) {
                    intersection[i][j]++;
                    intersection[j][i]++;
                }
            }
        }
    }
    std::vector<int> cur;
    std::vector<bool> used(n);
    cur.reserve(3);
    long long ans = 0;
    auto dfs = [&](auto self, int pos, int u) -> void {
        cur.push_back(u);
        used[u] = true;
        if (pos == 4) {
            int now = 1;
            int left = cur.front();
            int right = cur.back();
            if (graph[left][right]) {
                now *= (outdeg[left] - 2) * (outdeg[right] - 2);
            } else {
                now *= (outdeg[left] - 1) * (outdeg[right] - 1);
            }
            now -= intersection[left][right] - 1;
            ans += now;
        } else {
            for (int v = 0; v < n; v++) {
                if (used[v]) continue;
                if (graph[u][v]) {
                    self(self, pos + 1, v);
                }
            }
        }
        cur.pop_back();
        used[u] = false;
    };
    for (int i = 0; i < n; i++) dfs(dfs, 2, i);
    std::cout << ans << std::endl;
}
accuracy: 1
time_ms: 50
memory_kb: 5000
final_rank: 14

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

#ifdef LOCAL
#include <debug_print.hpp>
#define debug(...) debug_print::multi_print(#__VA_ARGS__, __VA_ARGS__)
#else
#define debug(...) (static_cast<void>(0))
#endif

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(20);
    int N;
    cin >> N;
    vector<vector<string>> A(N);
    for(int i = 0; i < N; i++){
        int k; cin >> k;
        A[i].resize(k);
        for(int j = 0; j < k; j++) cin >> A[i][j];
    }

    // mp := 言語 -> 人の集合
    map<string, vector<int>> mp;
    for(int i = 0; i < N; i++){
        for(auto l: A[i]) mp[l].emplace_back(i);
    }
    debug(mp);

    // B[i] := 人 i と会話できる人の集合
    vector B(N, vector<int>(N));
    for(auto [key, val]: mp){
        for(unsigned i = 0; i < val.size(); i++){
            for(unsigned j = i + 1; j < val.size(); j++){
                B[val[i]][val[j]] = B[val[j]][val[i]] = 1;
            }
        }
    }
    debug(B);

    // 2 人目と 4 人目を全探索
    ll ans = 0;
    for(int i = 0; i < N; i++){
        for(int j = 0; j < N; j++){
            if(i == j) continue;
            // S: i と j ともに会話できる人
            // T: i と会話できるが, j と会話できない人
            // U: i と会話できないが, j と会話できる人
            ll S = 0, T = 0, U = 0;
            for(int k = 0; k < N; k++){
                if(i == k || j == k) continue;
                if(B[i][k] && B[j][k]) S++;
                if(B[i][k] && !B[j][k]) T++;
                if(!B[i][k] && B[j][k]) U++;
            }
            ans += S * (T * U + T * (S - 1) + (S - 1) * U + (S - 1) * (S - 2));
        }
    }

    cout << ans << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 4356
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
bool ok[202][202];
int n;
long long sum(int a, int b){
    long long s=0, t=0, u=0;
    for(int i=0;i<n;i++){
        if(i!=b && ok[i][a]){
            if(ok[i][b]) s++;
            else t++;
        } else if(i!=a && ok[i][b]){
            u++;
        }
    }
    return 2*s*( (s-1)*(s-2) + (s-1)*(t+u) + t*u);
}
int main(){
    int m;
    string l;
    vector<string> vec[202];
    set<string> se[202];
    cin >> n;
    for(int i=0;i<n;i++){
        cin >> m;
        for(int j=0;j<m;j++){
            cin >> l;
            vec[i].push_back(l);
            se[i].insert(l);
        }
    }
    memset(ok, false, sizeof(ok));
    for(int i=0;i<n-1;i++){
        for(int j=0;j<vec[i].size();j++){
            for(int k=i+1;k<n;k++){
                if(ok[i][k]) continue;
                if(se[k].count(vec[i][j])){
                    ok[i][k] = true;
                    ok[k][i] = true;
                }
            }
        }
    }
    long long ans=0;
    for(int i=0;i<n-1;i++){
        for(int j=i+1;j<n;j++){
            long long s=0, t=0, u=0;
            for(int k=0;k<n;k++){
                if(k!=j && ok[k][i]){
                    if(ok[k][j]) s++;
                    else t++;
                } else if(k!=i && ok[k][j]) u++;
            }
            ans += 2*s*( (s-1)*(s-2) + (s-1)*(t+u) + t*u);
        }
    }
    cout << ans << endl;
    return(0);
}
accuracy: 1
time_ms: 20
memory_kb: 5204
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
bool ok[202][202];
int n;
long long sum(int a, int b){
    long long s=0, t=0, u=0;
    for(int i=0;i<n;i++){
        if(i!=b && ok[i][a]){
            if(ok[i][b]) s++;
            else t++;
        } else if(i!=a && ok[i][b]){
            u++;
        }
    }
    return 2*s*( (s-1)*(s-2) + (s-1)*(t+u) + t*u);
}
int main(){
    int m;
    string l;
    vector<string> vec[202];
    set<string> se[202];
    cin >> n;
    for(int i=0;i<n;i++){
        cin >> m;
        for(int j=0;j<m;j++){
            cin >> l;
            vec[i].push_back(l);
            se[i].insert(l);
        }
    }
    memset(ok, false, sizeof(ok));
    for(int i=0;i<n-1;i++){
        for(int j=0;j<vec[i].size();j++){
            for(int k=i+1;k<n;k++){
                if(ok[i][k]) continue;
                if(se[k].count(vec[i][j])){
                    ok[i][k] = true;
                    ok[k][i] = true;
                }
            }
        }
    }
    long long ans = 0;
    for(int i=0;i<n-1;i++){
        for(int j=i+1;j<n;j++){
            ans += sum(i, j);
        }
    }
    cout << ans << endl;
    return(0);
}
accuracy: 1
time_ms: 30
memory_kb: 5108
final_rank: 13

code_snippet: #include"bits/stdc++.h"
#include<random>
using namespace std;
typedef long long int llint;
typedef pair<int, int> pint;
typedef pair<llint, llint> pllint;
typedef vector<int> vint;
typedef vector<llint> vllint;
typedef vector<pint> vpint;
typedef vector<string> vstring;
typedef vector<pair<llint, llint>> vpllint;
typedef vector<vector<int>> vvint;
typedef vector<vector<llint>> vvllint;
typedef vector<vector<pint>> vvpint;
typedef vector<bool> vbool;
typedef vector<vbool> vvbool;
typedef vector<vpllint> vvpllint;
#define rep(i,n) for(int i=0;i<n;i++)
#define drep(i,n) for(int i=n-1;0<=i;i--)
#define yes(ans) if(ans)cout<<"yes"<<endl;else cout<<"no"<<endl;
#define Yes(ans) if(ans)cout<<"Yes"<<endl;else cout<<"No"<<endl;
#define YES(ans) if(ans)cout<<"YES"<<endl;else cout<<"NO"<<endl;
#define POSSIBLE(ans) if(ans)cout<<"POSSIBLE"<<endl;else cout<<"IMPOSSIBLE"<<endl;
#define Pi 3.1415926535897932384626
#define mod llint(1e9+7)
#define mod9 998244353
#define Inf 2147483647
#define llInf 9223372036854775807
#define all(x) x.begin(),x.end()
#define isin(i,n) (0<=i&&i<n)

int main() {
	int n;
	cin >> n;
	vector<set<int>>g(n);
	{
		vector<set<string>> lan(n);
		rep(i, n) {
			int m;
			cin >> m;
			string s;
			rep(j, m) {
				cin >> s;
				lan[i].insert(s);
			}
		}
		rep(i, n) {
			rep(j, i) {
				for (auto s : lan[i]) {
					if (lan[j].find(s) != lan[j].end()) {
						g[i].insert(j);
						g[j].insert(i);
						break;
					}
				}
			}
		}
	}
	llint ans = 0;
	rep(i, n)rep(j, n) {
		if (i == j)continue;
		int C = 0;
		for (auto k : g[i]) if (g[j].find(k) != g[j].end())C++;
		int A = g[i].size(), B = g[j].size();
		if (g[i].find(j) != g[i].end()) {
			A--; B--;
		}
		A -= C; B -= C;
		ans += (llint)C * (C - 1) * (C - 2);
		ans += (llint)C * (C - 1) * (A + B);
		ans += (llint)C * A * B;
	}
	cout << ans << endl;
	return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 6644
final_rank: 20

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

#define ll long long
#define vi vector<int>
#define all(v2) v2.begin(),v2.end()
#define fi first
#define se second
#define P pair<int,int>
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)

int mod=1e9+7;
int inf=INT_MAX;

int main(){
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);

    int n; cin>>n;

    vector<string> in[n];
    for(int i=0;i<n;i++){
        int k; cin>>k;
        for(int j=0;j<k;j++){
            string l; cin>>l;
            in[i].push_back(l);
        }
    }

    vector<vector<bool>> v(n,vector<bool>(n,0));
    for(int i=0;i<n-1;i++){
        set<string> s;
        for(auto a:in[i]){
            s.insert(a);
        }
        for(int j=i+1;j<n;j++){
            for(auto b:in[j]){
                if(s.find(b)!=s.end()){
                    v[i][j]=1;
                    v[j][i]=1;
                    break;
                }
            }
        }
    }

    ll ans=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(i==j) continue;

            int le=0,mi=0,ri=0;
            for(int k=0;k<n;k++){
                if(k==i || k==j) continue;

                if(v[k][i]){
                    if(v[k][j]) mi++;
                    else le++;
                }
                else if(v[k][j]){
                    ri++;
                }
            }

            ans+=mi*((mi-1)*(mi-2+le+ri)+le*ri);
        }
    }

    cout<<ans<<"\n";

    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 4244
final_rank: 7

code_snippet: #include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <utility>
#include <tuple>
#include <cstdint>
#include <cstdio>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <cctype>
#include <climits>
#include <functional>
#include <cassert>
#include <numeric>
#define rep(i, n) for(int i = 0; i < (n); i++)
#define per(i, n) for(int i = (n) - 1; i >= 0; i--)
using ll = long long;
#define vi vector<int>
#define vvi vector<vi>
#define vl vector<ll>
#define pii pair<int, int>
#define pll pair<ll, ll>
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define mod 1000000007
using namespace std;
template<class T, class U>
bool chmax(T &a, const U &b){ return a < b ? (a = b, 1) : 0; }
template<class T, class U>
bool chmin(T &a, const U &b){ return a > b ? (a = b, 1) : 0; }
int main(){
  int n;
  cin >> n;
  vector<set<int>> lang(n);
  rep(i, n){
    int k; cin >> k;
    rep(j, k){
      string s; cin >> s;
      lang[i].insert(s[0]*128 + s[1]);
    }
  }
  vector<bitset<200>> p(n);
  vi num(n);
  rep(i, n){
    rep(j, n) if(i != j){
      for(const int s : lang[i]){
        if(lang[j].count(s)){
          p[i][j] = 1;
          break;
        }
      }
    }
    num[i] = p[i].count();
  }
  ll ans = 0;
  rep(i, n) rep(j, n) if(i != j){
    const int a = num[i] - p[i][j];
    const int b = (p[i] & p[j]).count();
    const int c = num[j] - p[j][i];
    const int val = (a-1) * (c-1) - (b-1);
    ans += val * b;
  }
  cout << ans << "\n";
}
accuracy: 1
time_ms: 10
memory_kb: 4080
final_rank: 1

code_snippet: #include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <utility>
#include <tuple>
#include <cstdint>
#include <cstdio>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <cctype>
#include <climits>
#include <functional>
#include <cassert>
#include <numeric>
#define rep(i, n) for(int i = 0; i < (n); i++)
#define per(i, n) for(int i = (n) - 1; i >= 0; i--)
using ll = long long;
#define vi vector<int>
#define vvi vector<vi>
#define vl vector<ll>
#define pii pair<int, int>
#define pll pair<ll, ll>
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define mod 1000000007
using namespace std;
template<class T, class U>
bool chmax(T &a, const U &b){ return a < b ? (a = b, 1) : 0; }
template<class T, class U>
bool chmin(T &a, const U &b){ return a > b ? (a = b, 1) : 0; }
int main(){
  int n;
  cin >> n;
  vector<set<string>> lang(n);
  rep(i, n){
    int k; cin >> k;
    rep(j, k){
      string s; cin >> s;
      lang[i].insert(s);
    }
  }
  vector<bitset<200>> p(n);
  rep(i, n){
    for(const auto &s : lang[i]){
      rep(j, n) if(i != j && !p[i][j]){
        if(lang[j].count(s)) p[i][j] = 1;
      }
    }
  }
  ll ans = 0;
  rep(i, n) rep(j, n) if(i != j){
    const int a = p[i].count() - p[i][j];
    const int b = (p[i] & p[j]).count();
    const int c = p[j].count() - p[j][i];
    ll val = (a-1) * (c-1) - (b-1);
    ans += val * b;
  }
  cout << ans << "\n";
}
accuracy: 1
time_ms: 20
memory_kb: 4860
final_rank: 10

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

using std::vector;
using std::array;
using std::pair;
using std::tuple;

using ll = long long;

constexpr int MaxN = 200;
bool common[MaxN][MaxN];
bool common2[MaxN][MaxN][MaxN];
int count[MaxN];
int count2[MaxN][MaxN];

int main() {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int N;
    std::cin >> N;    
    std::map<std::string, vector<int>> lang;
    for (int i = 0; i < N; ++i) {
        int k;
        std::cin >> k;
        while (k--) {
            std::string s;
            std::cin >> s;
            lang[s].push_back(i);
        }
    }
    for (const auto& p : lang) {
        for (const int x : p.second) {
            for (const int y : p.second) {
                common[x][y] = true;
            }
        }
    }
    for (int i = 0; i < N; ++i) {
        common[i][i] = false;
        for (int j = 0; j < N; ++j) {
            count[i] += common[i][j];
        }
    }
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) {
            for (int k = 0; k < N; ++k) {
                common2[i][j][k] = common[i][k] and common[j][k];
                count2[i][j] += common2[i][j][k];
            }
        }
    }
    ll ans = 0;
    for (int a = 0; a < N; ++a) {
        for (int b = 0; b < N; ++b) {
            for (int c = 0; c < N; ++c) {
                if (common[a][b] and common[b][c] and a != c) {
                    ans += (count[a] - common[a][c] - 1) * (count[c] - common[a][c] - 1);
                    ans -= count2[a][c] - 1;
                }
            }
        }
    }
    std::cout << ans << '\n';
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 11592
final_rank: 17

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

int main(){
    int n, m;
    cin >> n;
    vector<vector<string>> a(n);
    vector<vector<bool>> T(n, vector<bool>(n));
    for(int i = 0; i < n; i++){
        cin >> m;
        a[i].resize(m);
        for(int j = 0; j < m; j++){
            cin >> a[i][j];
            for(int k = 0; k < i; k++){
                if(T[i][k])continue;
                if(binary_search(a[k].begin(), a[k].end(), a[i][j]))T[i][k] = T[k][i] = true;
            }
        }
        sort(a[i].begin(), a[i].end());
    }
    ll ans = 0;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < i; j++){
            ll A, B, C;
            A = B = C = 0;
            for(int k = 0; k < n; k++){
                if(k == i || k == j)continue;
                if(T[i][k] && T[j][k])C++;
                else if(T[i][k])A++;
                else if(T[j][k])B++;
            }
            //A -> i -> C -> j -> B
            ans += A * C * B;
            //C -> i -> C -> j -> B
            ans += C * (C - 1) * B;
            //A -> i -> C -> j -> C
            ans += A * C * (C - 1);
            //C -> i -> C -> j -> C
            ans += C * (C - 1) * (C - 2);
        }
    }
    cout << 2 * ans << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 3852
final_rank: 3