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 Go (1.6) (judge verdict: Accepted)

package main

import (
	"math/rand"
	"time"
	"os"
	"bufio"
	"fmt"
	"strconv"
	"strings"
)

var(
	inf = 10000000071000000
	sc = bufio.NewScanner(os.Stdin)
	stdin = bufio.NewReader(os.Stdin)
	mod = 1000000007
	mod9 = 1000000009
)

func init()  {
	rand.Seed(time.Now().UnixNano())
	buf := make([]byte, 0) //ここのサイズは何でもよさそう
	sc.Buffer(buf, 1000000009)
}


func main() {
	n := goint();m := goint()
	uni := &UnionFind{}
	uni.uniInit(n+m)
	for i:=0;i<n;i++{
		k := goint()
		for j:=0;j<k;j++{
			l := goint()
			uni.connect(i,l+n-1)
		}
	}
	num := uni.size(0)
	c := 0
	for i:=n;i<n+m;i++{
		if uni.root(0) != uni.root(i){
			c ++
		}
	}
	if num - (m - c) == n{
		fmt.Println("YES")
	} else {
		fmt.Println("NO")
	}
}

//Union-Find
type UnionFind struct {
	par []int
}

func (u *UnionFind) uniInit(n int)  {
	u.par = make([]int,n)
	for i:=0;i<n;i++{
		u.par[i] = -1
	}
}

//aがどのグループに属しているか
func (u *UnionFind) root (a int) int {
	if u.par[a] < 0{
		return a
	}
	u.par[a] = u.root(u.par[a])
	return u.par[a]
}

//自分のグループの頂点数
func (u *UnionFind) size (a int) int {
	return -u.par[u.root(a)]
}

//つなげる
func (u *UnionFind) connect(a,b int) bool {
	a = u.root(a)
	b = u.root(b)
	if a == b {
		return false
	}
	if u.size(a) < u.size(b) {a,b = b,a}
	u.par[a] += u.par[b]
	u.par[b] = a
	return true
}

//||||||||||||||||||||||||||入力|||||||||||||||||||||||||||||||||||||||\
//数字一文字入力
func nextInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

//文字列を一行入力
func nextLine() string {
	sc.Scan()
	return sc.Text()
}

//空白区切りの文字列の入力
func spaceLine() []string {
	sc.Scan()
	return strings.Split(sc.Text()," ")
}

//数字を一行入力
func intLine() []int {
	str := spaceLine()
	buf := make([]int,len(str))
	for i,s:=range str{
		buf[i],_ = strconv.Atoi(s)
	}
	return buf
}

//次のスペースか改行まで読み込む
func gostring() string {
	byte_ls := make([]byte,0)
	for  {
		b, _ := stdin.ReadByte()
		if b == 32 || b == 10 || b == 0{
			return string(byte_ls)
		} else if b == 13 {
			continue
		} else {
			byte_ls = append(byte_ls,b)
		}
	}
}

//上の関数のintバージョン
func goint() int {
	n,_ := strconv.Atoi(gostring())
	return n
}

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

func sum(a ...int) int {
	ans := 0
	for i:=0;i<len(a);i++{
		ans += a[i]
	}
	return ans
}

func min(a ...int) int {
	ans := a[0]
	for i:=1;i<len(a);i++{
		if ans > a[i]{
			ans = a[i]
		}
	}
	return ans
}

func abs(n int) int {
	if n >= 0{
		return n
	} else {
		return -n
	}
}

func max(a ...int) int {
	ans := a[0]
	for i:=1;i<len(a);i++{
		if ans < a[i]{
			ans = a[i]
		}
	}
	return ans
}