#include #include #include #include #include #include #include // TODO: tweak parameters M and L const int M = 1000000; const int L = 50; const int N = M/L; int main(){ int n; std::cin >> n; std::unordered_map simplify; std::vector original; std::vector, int>> As(n); for (int i = 0; i < n; ++i){ As[i].second = i+1; int k; std::cin >> k; As[i].first.resize(k); for (int &x : As[i].first){ std::cin >> x; if (!simplify.count(x)){ simplify[x] = original.size(); original.push_back(x); } x = simplify[x]; } } int K = original.size(); std::sort(As.begin(), As.end(), [](std::pair, int> &p1, std::pair, int> &p2){ return p1.first.size() == p2.first.size() ? p1.second < p2.second : p1.first.size() > p2.first.size(); }); // Exhaust sets of size >=L in time O(MN/64) std::vector> bs(K); for (int i = 0; i < n; ++i){ std::bitset prevs; for (int j : As[i].first){ if ((prevs & bs[j]).any()){ int i2 = 0; while (!prevs[i2] || !bs[j][i2]) ++i2; for (int j2 : As[i].first) if (bs[j2][i2]){ std::cout << original[j] << ' ' << original[j2] << ' ' << As[i].second << ' ' << As[i2].second << std::endl; return 0; } } prevs |= bs[j]; if (As[i].first.size() >= L) bs[j][i] = 1; } } // Exhaust sets of size pairs; for (int i = 0; i < n; ++i) if (As[i].first.size() < L){ sort(As[i].first.begin(), As[i].first.end()); for (int ji = 0; ji < As[i].first.size(); ++ji){ int j = As[i].first[ji]; for (int ji2 = ji+1; ji2 < As[i].first.size(); ++ji2){ int j2 = As[i].first[ji2]; long long pr = j * ((long long) M) + j2; if (pairs.count(pr)){ std::cout << original[j] << ' ' << original[j2] << ' ' << As[i].second << ' ' << As[pairs[pr]].second << std::endl; return 0; } pairs[pr] = i; } } } std::cout << "impossible" << std::endl; return 0; }