Problem:
Score : 200 points

Problem Statement

Katsusando loves omelette rice.

Besides, he loves crème brûlée, tenderloin steak and so on, and believes that these foods are all loved by everyone.

To prove that hypothesis, he conducted a survey on M kinds of foods and asked N people whether they like these foods or not.

The i-th person answered that he/she only likes the A_{i1}-th, A_{i2}-th, ..., A_{iK_i}-th food.

Find the number of the foods liked by all the N people.

Constraints

All values in input are integers.

1 \leq N, M \leq 30

1 \leq K_i \leq M

1 \leq A_{ij} \leq M

For each i (1 \leq i \leq N), A_{i1}, A_{i2}, ..., A_{iK_i} are distinct.

Constraints

Input is given from Standard Input in the following format:

N M
K_1 A_{11} A_{12} ... A_{1K_1}
K_2 A_{21} A_{22} ... A_{2K_2}
:
K_N A_{N1} A_{N2} ... A_{NK_N}

Output

Print the number of the foods liked by all the N people.

Sample Input 1

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

Sample Output 1

1

As only the third food is liked by all the three people, 1 should be printed.

Sample Input 2

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

Sample Output 2

0

Katsusando's hypothesis turned out to be wrong.

Sample Input 3

1 30
3 5 10 30

Sample Output 3

3

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;

public class VC0407M_02
{

    public static void Main()
    {
        int i1 = 0, i2 = 0;
        InLine(ref i1, ref i2);
        int[] like = new int[i2];
        for(int i = 0;i < i1;i++)
        {
            int[] m = InLineArg<int>();
            for(int n = 0;n < m[0];n++)
            {
                like[m[n + 1] - 1]++;
            }
        }

        int iresult = 0;
        foreach (var i in like)
        {
            if (i == i1) iresult++;
        }
        Out(iresult);
    }

    /* Template */
    private static object[] nullobj = null;

    //文字コード変換
    public static int ConvertInt(char c)
    {
        return c;
    }

    //入力:1入力配列
    public static A[] InArgs<A>(int count)
    {
        A[] var = default(A[]);
        InArgs(count, ref var, ref nullobj, ref nullobj);
        return var;
    }

    //入力:1入力配列
    public static void InArgs<A>(int count, ref A[] var)
    {
        InArgs(count, ref var, ref nullobj, ref nullobj);
    }

    //入力:2入力配列
    public static void InArgs<A, B>(int count, ref A[] var1, ref B[] var2)
    {
        InArgs(count, ref var1, ref var2, ref nullobj);
    }

    //入力:3入力配列
    public static void InArgs<A, B, C>(int count, ref A[] var1, ref B[] var2, ref C[] var3)
    {
        A a = default(A);
        B b = default(B);
        C c = default(C);
        for (int i = 0; i < count; i++)
        {
            InLine(ref a, ref b, ref c);
            var1[i] = a;
            if (var2 != null) var2[i] = b;
            if (var3 != null) var3[i] = c;
        }
    }

    //入力:1入力
    public static A InLine<A>()
    {
        A var = default(A);
        InLine(ref var);
        return var;
    }

    //入力:1入力
    public static void InLine<A>(ref A var)
    {
        InLine(ref var, ref nullobj, ref nullobj);
    }

    //入力:2入力
    public static void InLine<A, B>(ref A var1, ref B var2)
    {
        InLine(ref var1, ref var2, ref nullobj);
    }

    //入力:3入力
    public static void InLine<A, B, C>(ref A var1, ref B var2, ref C var3)
    {
        object[] o = new object[] { var1, var2, var3 };
        Type[] t = new Type[] { typeof(A), typeof(B), typeof(C) };
        if (var3 == null)
        {
            if (var2 == null) o = new object[] { var1 };
            else o = new object[] { var1, var2 };
        }

        var line = Console.ReadLine();
        string[] s;
        if (o.Length == 1) s = new string[1] { line };
        else s = line.Split(' ');
        for (int i = 0; i < s.Length; i++)
        {
            if (typeof(int) == t[i]) o[i] = int.Parse(s[i]);
            else if (typeof(long) == t[i]) o[i] = long.Parse(s[i]);
            else if (typeof(double) == t[i]) o[i] = double.Parse(s[i]);
            else o[i] = s[i];
        }
        var1 = (A)o[0];
        if (var2 != null) var2 = (B)o[1];
        if (var3 != null) var3 = (C)o[2];
    }

    //入力:1行配列
    public static A[] InLineArg<A>()
    {
        A[] var = default(A[]);
        InLineArg(ref var);
        return var;
    }

    //入力:1行配列
    public static void InLineArg<A>(ref A[] arg)
    {
        object obj = null;
        Type t = typeof(A);
        string[] line = Console.ReadLine().Split(' ');
        if (typeof(int) == t) obj = line.Select(int.Parse).ToArray();
        else if (typeof(long) == t) obj = line.Select(long.Parse).ToArray();
        else if (typeof(double) == t) obj = line.Select(double.Parse).ToArray();
        else obj = line;
        arg = (A[])obj;
    }

    //文字列結合
    public static string JoinString(object[] obj, string sep)
    {
        return string.Join(sep, obj.Select(i => i.ToString()).ToArray());
    }

    //出力
    public static void Out(object o)
    {
        Console.WriteLine(o);
    }

    //出力:Yes
    public static void OutYes()
    {
        Console.WriteLine("Yes");
    }

    //出力:No
    public static void OutNo()
    {
        Console.WriteLine("No");
    }

    //出力:YES
    public static void OutYES()
    {
        Console.WriteLine("YES");
    }

    //出力:NO
    public static void OutNO()
    {
        Console.WriteLine("NO");
    }

    //辞書生成
    private static Dictionary<A, B> PutDict<A, B>(A[] key, B[] value)
    {
        if (key.Length != value.Length) return null;
        var dic = new Dictionary<A, B>();
        for (int i = 0; i < key.Length; i++)
        {
            if (!dic.ContainsKey(key[i])) dic.Add(key[i], value[i]);
            else dic[key[i]] = value[i];
        }
        return dic;
    }

    //公約数
    public static int[] CommonDivisor(int num)
    {
        return CommonDivisor((long)num).Select(i => (int)i).ToArray();
    }

    public static long[] CommonDivisor(long num)
    {
        long l = 2, n = num;
        long[] result = new long[0];

        while (l * l <= num)
        {
            if (n % l == 0)
            {
                n /= l;
                Array.Resize(ref result, result.Length + 1);
                result[result.Length - 1] = l;
            }
            else l++;
        }
        if (n != 1)
        {
            Array.Resize(ref result, result.Length + 1);
            result[result.Length - 1] = n;
        }
        return result;
    }

    //大小比較
    public static bool Compare(bool equal, long a, long x)
    {
        return Compare(equal, a, x, long.MaxValue, true);
    }

    public static bool Compare(long x, long b, bool equal)
    {
        return Compare(true, long.MinValue, x, b, equal);
    }

    public static bool Compare(bool lequal, long a, long x, long b, bool requal)
    {
        if (a <= x && x <= b)
        {
            if (!lequal && x == a) return false;
            else if (!requal && x == b) return false;
            else return true;
        }
        return false;
    }

    //割り切る
    public static bool IsDivisible(long a, long b)
    {
        return a % b == 0;
    }

    //互いに素
    public static bool IsRelativelyPrime(long a, long b)
    {
        bool result = false;
        if (a > 1 && b > 1)
            result = CommonDivisor(a).Intersect(CommonDivisor(b)).ToArray().Length == 0;
        return result;
    }

    //素数判定
    public static bool IsPrimeNumber(int num)
    {
        if (num < 2) return false;
        else if (num == 2) return true;
        else if (num % 2 == 0) return false;

        double sqrtNum = Math.Sqrt(num);
        for (int i = 3; i <= sqrtNum; i += 2)
        {
            if (num % i == 0) return false;
        }
        return true;
    }

    //最大公約数
    public static int GCD(int a, int b)
    {
        return (int)GCD((long)a, b);
    }

    public static long GCD(long a, long b)
    {
        long[] acd = CommonDivisor(a).ToArray(), bcd = CommonDivisor(b).ToArray();
        Dictionary<long, int> dic1 = new Dictionary<long, int>(), dic2 = new Dictionary<long, int>();
        int count = 0;
        long n = 0, result = 1;
        for (int i = 0; i < acd.Length; i++)
        {
            if (n == acd[i]) count++;
            else
            {
                if (n != 0) dic1.Add(n, count);
                n = acd[i];
                count = 1;
            }
        }
        dic1.Add(n, count);
        n = 0;
        count = 0;
        for (int i = 0; i < bcd.Length; i++)
        {
            if (n == bcd[i]) count++;
            else
            {
                if (dic1.ContainsKey(n)) dic2[n] = Math.Max(count, dic1[n]);
                n = bcd[i];
                count = 1;
            }
        }
        if (dic1.ContainsKey(n)) dic2[n] = Math.Max(count, dic1[n]);
        foreach (long l in dic2.Keys)
        {
            result *= (long)Math.Pow(l, dic2[l]);
            Console.WriteLine($"{l}, {dic2[l]}");
        }
        return result;
    }

    //最小公倍数
    public static long LCM(long a, long b)
    {
        long[] acd = CommonDivisor(a).ToArray(), bcd = CommonDivisor(b).ToArray();
        var dic = new Dictionary<long, int>();
        int count = 0;
        long n = 0, result = 1;
        for (int i = 0; i < acd.Length; i++)
        {
            if (n == acd[i]) count++;
            else
            {
                if (n != 0) dic.Add(n, count);
                n = acd[i];
                count = 1;
            }
        }
        dic.Add(n, count);
        n = 0;
        count = 0;
        for (int i = 0; i < bcd.Length; i++)
        {
            if (n == bcd[i]) count++;
            else
            {
                if (dic.ContainsKey(n)) dic[n] = Math.Max(count, dic[n]);
                else if (n != 0) dic.Add(n, count);
                n = bcd[i];
                count = 1;
            }
        }
        if (dic.ContainsKey(n)) dic[n] = Math.Max(count, dic[n]);
        else dic.Add(n, count);
        foreach (long l in dic.Keys)
            result *= (long)Math.Pow(l, dic[l]);
        return result;
    }

    //組合せ数(nCr)
    public static double Combination(int n, int r)
    {
        if (n / 2 < r) r = n - r;
        return TotalPower(n, r + 1) / TotalPower(n - r);
    }

    //組合せ数総和(Σ(k=1,n,nCk))
    public static double CombinationSum(int n)
    {
        return Math.Pow(2, n);
    }

    //重複組合せ数(nHr)
    public static double RepetitionCombination(int n, int r)
    {
        return Combination(n + r - 1, r);
    }

    //重複組合せ数総和(Σ(k=1,n,nHk))
    public static double RepetitionCombinationSum(int n)
    {
        double result = 0;
        for (int i = 1; i <= n; i++)
        {
            result += RepetitionCombination(n, i);
        }
        return result;
    }

    //順列数(nPr)
    public static double Permutation(int n, int r)
    {
        return TotalPower(n, r + 1);
    }

    //順列数総和(Σ(k=1,n,nPk))
    public static double PermutationSum(int n)
    {
        double result = 0;
        for (int i = 1; i <= n; i++)
        {
            result += Permutation(n, i);
        }
        return result;
    }

    //円順列数
    public static double CircularPermutation(int n)
    {
        return TotalPower(n - 1);
    }

    //円順列数総和
    public static double CircularPermutationSum(int n)
    {
        double result = 0;
        for (int i = 1; i <= n; i++)
        {
            result += CircularPermutation(i);
        }
        return result;
    }



    //数珠順列数
    public static double NecklacePermutation(int n)
    {
        return CircularPermutation(n - 1) / 2;
    }

    //数珠順列数総和
    public static double NecklacePermutationSum(int n)
    {
        double result = 0;
        for (int i = 1; i <= n; i++)
        {
            result += NecklacePermutation(i);
        }
        return result;
    }

    //重複順列数(nΠr)
    public static double RepetitionPermutation(int n, int r)
    {
        return Math.Pow(n, r);
    }

    //重複順列数総和(Σ(k=1,n,nΠk))
    public static double RepetitionPermutationSum(int n)
    {
        double result = 0;
        for (int i = 1; i <= n; i++)
        {
            result += RepetitionPermutation(n, i);
        }
        return result;
    }

    //総乗
    public static double TotalPower(int max)
    {
        return TotalPower(max, 1);
    }

    public static double TotalPower(int max, int min)
    {
        double result = 1;
        for (int i = min; i <= max; i++) result *= i;
        return result;
    }

    public static double TotalPower(int[] ints)
    {
        double result = 1;
        foreach (int i in ints) result *= i;
        return result;
    }

    //総和
    public static double TotalSum(int max)
    {
        return TotalSum(max, 1);
    }

    public static double TotalSum(int max, int min)
    {
        double result = 1;
        for (int i = min; i <= max; i++) result += i;
        return result;
    }

    public static double TotalSum(int[] ints)
    {
        double result = 1;
        foreach (int i in ints) result += i;
        return result;
    }
}