#include using namespace std; const int TOTAL_BITS = 64; const int SET_BITS = 10; const int BASE = 1000037; const int MOD1 = (int)1e9 + 7; const int MOD2 = 998244353; template struct ModInt { int x; ModInt(int x = 0) : x(x + (x < 0) * MOD - (x >= MOD) * MOD) {} ModInt operator+(ModInt o) { return x + o.x; } ModInt operator-(ModInt o) { return x - o.x; } ModInt operator*(ModInt o) { return 1LL * x * o.x % MOD; } bool operator==(ModInt o) { return x == o.x; } }; using Hash = pair, ModInt>; int main() { ios::sync_with_stdio(false); cin.tie(0); random_device rd; mt19937 rng(rd()); int n, m; cin >> n >> m; vector value(m + 1, 0); for(int i = 1; i <= m; i++) { vector unused; for(int i = 0; i < TOTAL_BITS; i++) { unused.push_back(i); } shuffle(unused.begin(), unused.end(), rng); for(int bit = 0; bit < SET_BITS; bit++) { value[i] |= (1ULL << unused[bit]); } } vector length(n + 1, 0); vector bloom_value(n + 1, 0); vector> activities(n + 1); vector> people_with_activity(m + 1); vector hashes(n + 1, {0, 0}); for(int i = 1; i <= n; i++) { cin >> length[i]; for(int j = 1; j <= length[i]; j++) { int activity; cin >> activity; activities[i].push_back(activity); people_with_activity[activity].push_back(i); bloom_value[i] |= value[activity]; } sort(activities[i].begin(), activities[i].end()); ModInt h1 = 0; ModInt h2 = 0; for (int x : activities[i]) { h1 = h1 + x; h1 = h1 * BASE; h2 = h2 + x; h2 = h2 * BASE; } hashes[i] = {h1, h2}; } map, bool> same_set; auto Same = [&](int a, int b) -> bool { return hashes[a].first == hashes[b].first && hashes[a].second == hashes[b].second; if (a > b) swap(a, b); if (bloom_value[a] != bloom_value[b]) return false; if (length[a] != length[b]) return false; auto it = same_set.find({a, b}); if (it != same_set.end()) return it->second; for (int i = 0; i < length[a]; ++i) { if (activities[a][i] != activities[b][i]) return same_set[{a, b}] = false; } return same_set[{a, b}] = true; }; map, bool> included_map; auto Included = [&](int a, int b) { if ((bloom_value[a] & bloom_value[b]) != bloom_value[a]) { return false; } auto it = included_map.find({a, b}); if (it != included_map.end()) return it->second; int i = 0, j = 0; bool ret = true; while (i < (int)activities[a].size()) { while (j < (int)activities[b].size()) { if (activities[a][i] == activities[b][j]) { break; } ++j; } if (j == (int)activities[b].size()) { ret = false; break; } ++i; } return included_map[{a, b}] = ret; }; auto Solve = [&](vector pers) -> pair { sort(pers.begin(), pers.end(), [&](int a, int b) { return length[a] < length[b]; }); for (int i = 1; i < (int)pers.size(); ++i) { int curr = pers[i], last = pers[i - 1]; if (length[curr] == length[last]) { if (Same(curr, last)) { continue; } return {curr, last}; } if (!Included(last, curr)) { return {curr, last}; } } return {-1, -1}; }; pair ans = {-1, -1}; for(int activity = 1; activity <= m; activity++) { auto curr = Solve(people_with_activity[activity]); if (curr != make_pair(-1, -1)) { ans = curr; break; } } if (ans != make_pair(-1, -1)) { cout << "YES\n"; cout << ans.first << ' ' << ans.second << '\n'; } else { cout << "NO\n"; } return 0; }