Problem:
Score : 400 points

Problem Statement

On a planet far, far away, M languages are spoken. They are conveniently numbered 1 through M.

For CODE FESTIVAL 20XX held on this planet, N participants gathered from all over the planet.

The i-th (1≦i≦N) participant can speak K_i languages numbered L_{i,1}, L_{i,2}, ..., L_{i,{}K_i}.

Two participants A and B can communicate with each other if and only if one of the following conditions is satisfied:

There exists a language that both A and B can speak.

There exists a participant X that both A and B can communicate with.

Determine whether all N participants can communicate with all other participants.

Constraints

2≦N≦10^5

1≦M≦10^5

1≦K_i≦M

(The sum of all K_i)≦10^5

1≦L_{i,j}≦M

L_{i,1}, L_{i,2}, ..., L_{i,{}K_i} are pairwise distinct.

Partial Score

200 points will be awarded for passing the test set satisfying the following: N≦1000, M≦1000 and (The sum of all K_i)≦1000.

Additional 200 points will be awarded for passing the test set without additional constraints.

Input

The input is given from Standard Input in the following format:

N M
K_1 L_{1,1} L_{1,2} ... L_{1,{}K_1}
K_2 L_{2,1} L_{2,2} ... L_{2,{}K_2}
:
K_N L_{N,1} L_{N,2} ... L_{N,{}K_N}

Output

If all N participants can communicate with all other participants, print YES. Otherwise, print NO.

Sample Input 1

4 6
3 1 2 3
2 4 2
2 4 6
1 6

Sample Output 1

YES

Any two participants can communicate with each other, as follows:

Participants 1 and 2: both can speak language 2.

Participants 2 and 3: both can speak language 4.

Participants 1 and 3: both can communicate with participant 2.

Participants 3 and 4: both can speak language 6.

Participants 2 and 4: both can communicate with participant 3.

Participants 1 and 4: both can communicate with participant 2.

Note that there can be languages spoken by no participant.

Sample Input 2

4 4
2 1 2
2 1 2
1 3
2 4 3

Sample Output 2

NO

For example, participants 1 and 3 cannot communicate with each other.

Solution in Java (OpenJDK 11.0.6) (judge verdict: Accepted)


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Scanner;
import java.util.concurrent.ArrayBlockingQueue;

public class Main {

     static Scanner scanner;

     public static void main(String[] args) {
         scanner = new Scanner(System.in);

         int N=gi();
         int M=gi();
         Map<Integer,List<Integer>> map=new HashMap<Integer,List<Integer>>();
         Map<Integer,List<Integer>> map2=new HashMap<Integer,List<Integer>>();
         boolean[] f=new boolean[N];
         boolean[] fl=new boolean[M];
         for (int i=1; i<=N;i++) {
        	 int k=gi();
        	 List<Integer> ls=new ArrayList<Integer>();
        	 for (int j=0; j<k;j++) {
        		 int l=gi();
        		 if(map.containsKey(l)) {
        			 List<Integer> li=map.get(l);
        			 li.add(i);
        		 } else {
        			 List<Integer> li=new ArrayList<Integer>();
        			 li.add(i);
        			 map.put(l, li);
        		 }
        		 ls.add(l);
        	 }
        	 map2.put(i,ls);
         }

         Queue<Integer> q=new ArrayBlockingQueue<Integer>(N);
         q.add(1);
         f[0]=true;
         while(!q.isEmpty()) {
        	 int v=q.poll();
        	 List<Integer> lv =map2.get(v);
        	 for (int i=0; i<lv.size();i++) {
        		 int ll=lv.get(i);
        		 if(fl[ll-1]) continue;
        		 fl[ll-1]=true;
        		 List<Integer> nv=map.get(ll);
        		 for(int j=0; j<nv.size();j++) {
        			 int n=nv.get(j);
        			 if(f[n-1]==false) {
        				 q.add(n);
        				 f[n-1]=true;
        			 }
        		 }
        	 }
         }
         boolean ff=true;
         for (int i=0; i<N;i++) {
        	 if(f[i]==false) {
        		 ff=false;
        	 }
         }

         if(ff) {
             System.out.println("YES");
         }else {
        	 System.out.println("NO");
         }
     }

     // 文字列として入力を取得
     public static String gs() {
          return scanner.next();
     }

     // intとして入力を取得
     public static int gi() {
          return Integer.parseInt(scanner.next());
     }

     // longとして入力を取得
     public static long gl() {
          return Long.parseLong(scanner.next());
     }

     // doubleとして入力を取得
     public static double gd() {
          return Double.parseDouble(scanner.next());
     }
}