#include<bits/stdc++.h>
using namespace std;
struct graph{
    vector<int> v;
    vector<int> sz;
    int lim;
    graph(int n){
        lim=n;
        for (int i=0; i<=lim; i++){
            v.push_back(i);
            sz.push_back(1);
        }
    }
    int root(int node){
        if(v[node]==node) return node;
        return v[node]=root(v[node]);
    }
    bool Find(int x, int y){
        if (x==y) return true;
        return root(x)==root(y);
    }
    void Union(int x, int y){
        int rx=root(x), ry=root(y);
        if (rx!=ry){
            v[rx]=ry;
            sz[ry]+=sz[rx];
        }
    }
    void print(){
        for (int i=0; i<=lim; i++)
            cout<<v[i]<<" ";
        cout<<endl;
    }
    int rootSize(int r){
        return sz[r];
    }
};
int main(){
    int n, m;
    cin>>n>>m;
    int dis=m, least=0, t=n, u=m;
    graph s(m);
    int freq[500]={0};
    while(t--){
        int x, lang[500];
        cin>>x;
        if(!x)
            freq[0]++;
        else{
            for(int i=0; i<x; i++){
                cin>>lang[i];
                freq[lang[i]]++;
            }
            for(int i=0; i<x-1; i++)
            if(!s.Find(lang[i], lang[i+1])){
                    dis--;
                    s.Union(lang[i], lang[i+1]);
            }
        }
    }
    for(int i=1; i<=m; i++){
        //cout<<freq[i]<<" ";
        if(!freq[i])
        least++;
    }
    cout<<freq[0]<<endl;
    if (freq[0]==n)
        cout<<n<<endl;
    //cout<<endl<<dis<<" "<<least<<" "<<freq[0]<<endl;
    //cout<<"Answer: "<<dis-least-1+freq[0]<<endl;
    //main();
    else cout<<dis-least-1+freq[0]<<endl;
}


#include<bits/stdc++.h>
using namespace std;
struct graph{
    vector<int> v;
    vector<int> sz;
    int lim;
    graph(int n){
        lim=n;
        for (int i=0; i<=lim; i++){
            v.push_back(i);
            sz.push_back(1);
        }
    }
    int root(int node){
        if(v[node]==node) return node;
        return v[node]=root(v[node]);
    }
    bool Find(int x, int y){
        if (x==y) return true;
        return root(x)==root(y);
    }
    void Union(int x, int y){
        int rx=root(x), ry=root(y);
        if (rx!=ry){
            v[rx]=ry;
            sz[ry]+=sz[rx];
        }
    }
    void print(){
        for (int i=0; i<=lim; i++)
            cout<<v[i]<<" ";
        cout<<endl;
    }
    int rootSize(int r){
        return sz[r];
    }
};
int main(){
    int n, m;
    cin>>n>>m;
    int dis=m, least=0, t=n, u=m;
    graph s(m);
    int freq[500]={0};
    while(t--){
        int x, lang[500];
        cin>>x;
        if(!x)
            freq[0]++;
        else{
            for(int i=0; i<x; i++){
                cin>>lang[i];
                freq[lang[i]]++;
            }
            for(int i=0; i<x-1; i++)
            if(!s.Find(lang[i], lang[i+1])){
                    dis--;
                    s.Union(lang[i], lang[i+1]);
            }
        }
    }
    for(int i=1; i<=m; i++){
        //cout<<freq[i]<<" ";
        if(!freq[i])
        least++;
    }
    cout<<freq[0]<<endl;
    if (freq[0]==n)
        //cout<<n<<endl;
    //cout<<endl<<dis<<" "<<least<<" "<<freq[0]<<endl;
    //cout<<"Answer: "<<dis-least-1+freq[0]<<endl;
    //main();
    else cout<<dis-least-1+freq[0]<<endl;
}


#include "functional"
#include "algorithm"
#include "exception"
#include "stdexcept"
#include "streambuf"
#include "iostream"
#include "iterator"
#include "typeinfo"
#include "valarray"
#include "cassert"
#include "ciso646"
#include "climits"
#include "clocale"
#include "complex"
#include "csetjmp"
#include "csignal"
#include "cstdarg"
#include "cstddef"
#include "cstdlib"
#include "cstring"
#include "cwctype"
#include "fstream"
#include "iomanip"
#include "istream"
#include "numeric"
#include "ostream"
#include "sstream"
#include "utility"
#include "bitset"
#include "cctype"
#include "cerrno"
#include "cfloat"
#include "cstdio"
#include "cwchar"
#include "iosfwd"
#include "limits"
#include "locale"
#include "memory"
#include "string"
#include "vector"
#include "cmath"
#include "ctime"
#include "deque"
#include "queue"
#include "stack"
#include "list"
#include "ios"
#include "map"
#include "new"
#include "set"

using namespace std;

int BING[128];
int find(int x)
{
    if (BING[x] == x)
    {
        return x;
    }
    else
    {
        return find(BING[x]);
    }
}

int main()
{
    for (int i = 0; i < 128; ++i)
    {
        BING[i] = i;
    }

    int people, language;
    cin >> people >> language;
    int temp, lan[128];
    int answer = 0;
    bool used[128];
    fill(used, used + 128, false);
    for (int i = 0; i < people; ++i)
    {
        cin >> temp;
        if (temp == 0)
        {
            ++answer;
        }
        else
        {
            for (int i = 0; i < temp; ++i)
            {
                cin >> lan[i];
                used[lan[i]] = true;
            }
            for (int i = 0; i < temp; ++i)
            {
                BING[find(lan[i])] = find(lan[0]);
            }
        }
    }
    for (int i = 1; i < language + 1; i++)
    {
        BING[i] = find(BING[i]);
    }
    set<int> fuck(BING + 1, BING + language + 1);
    int dou = 0;
    for (set<int>::iterator i = fuck.begin(); i != fuck.end(); ++i)
    {
        if (!used[*i])
        {
            ++dou;
        }
    }

    cout << fuck.size() - 1 + answer - dou << endl;
    return 0;
}


#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<sstream>
#include<string>
#include<utility>
#include<map>
#include<queue>
#include<set>
#include<vector>

using namespace std;
#define sfd(n) scanf("%d", &n)
#define sfd2(n, m) scanf("%d %d", &n, &m)
#define sfs(s) scanf("%s", s);
#define sflld(n) scanf("%lld", &n)
#define sflf(n) scanf("%lf", &n)
#define ll long long
#define maxn 100+10

struct DisjointSet {
	vector<int> father, rank, size;
	int num; // 图的个数

	DisjointSet(int n) :father(n + 1), rank(n + 1), size(n+1) {
		num = n;
		for (int i = 0; i <= n; i++) {
			father[i] = i;
			size[i] = 1;
		}
	}

	int find(int v) { return father[v] = father[v] == v ? v : find(father[v]); }

	// merge函数合并两个图，如果它们本就在一个图中则返回true
	bool merge(int x, int y) {
		int a = find(x), b = find(y), ring = 0;
		if (a == b) ring = 1; // 若a与b的father相同，则说明在同一个图中
		else num--; // 如果合并的两个不是在同一个图中，则图的数量减一
		if (rank[a] < rank[b]) {
			father[a] = b;
			size[b] += size[a]; size[a] = 0; // 转移size的值
		}
		else {
			father[b] = a;
			size[a] += size[b]; size[b] = 0;
			if (rank[b] == rank[a]) ++rank[a];
		}
		return ring;
	}
};

string lang[maxn];

int main() {
	//#ifdef ONLINE_JUDGE
	//#else
	//	freopen("D:/in.txt", "r", stdin);
	//	freopen("D:/out.txt", "w", stdout);
	//#endif
	ll n, m;
	while (cin >> n >> m) {
		DisjointSet ds(n);
		for (int i=0; i<n; i++) lang[i].clear();
		ll k, tmp, cnt0 = 0;
		bool ok = false;
		for (int i=0; i<n; i++) {
			cin >> k;
			if (k==0) {
				cnt0++;
				continue;
			}
			for (int j=0; j<k; j++) {
				cin >> tmp;
				lang[i] += tmp+'0';
			}
			for (int j=0; j<i; j++) {
				if (lang[i].find_first_of(lang[j])!=string::npos)
					ds.merge(i, j);
			}
		}
		if (cnt0!=n) cout << ds.num-1 << endl;
		else cout << cnt0 << endl;
	}
	return 0;
}


#include "functional"
#include "algorithm"
#include "exception"
#include "stdexcept"
#include "streambuf"
#include "iostream"
#include "iterator"
#include "typeinfo"
#include "valarray"
#include "cassert"
#include "ciso646"
#include "climits"
#include "clocale"
#include "complex"
#include "csetjmp"
#include "csignal"
#include "cstdarg"
#include "cstddef"
#include "cstdlib"
#include "cstring"
#include "cwctype"
#include "fstream"
#include "iomanip"
#include "istream"
#include "numeric"
#include "ostream"
#include "sstream"
#include "utility"
#include "bitset"
#include "cctype"
#include "cerrno"
#include "cfloat"
#include "cstdio"
#include "cwchar"
#include "iosfwd"
#include "limits"
#include "locale"
#include "memory"
#include "string"
#include "vector"
#include "cmath"
#include "ctime"
#include "deque"
#include "queue"
#include "stack"
#include "list"
#include "ios"
#include "map"
#include "new"
#include "set"

using namespace std;

int BING[128];
int find(int x)
{
    if (BING[x] == x)
    {
        return x;
    }
    else
    {
        return find(BING[x]);
    }
}

int main()
{
    for (int i = 0; i < 128; ++i)
    {
        BING[i] = i;
    }

    int people, language;
    cin >> people >> language;
    int temp, lan[128];
    int answer = 0;
    bool used[128];
    fill(used, used + 128, false);
    for (int i = 0; i < people; ++i)
    {
        cin >> temp;
        if (temp == 0)
        {
            ++answer;
        }
        else
        {
            for (int i = 0; i < temp; ++i)
            {
                cin >> lan[i];
                used[lan[i]] = true;
            }
            for (int i = 0; i < temp; ++i)
            {
                BING[find(lan[i])] = find(lan[0]);
            }
        }
    }
    for (int i = 1; i < language + 1; i++)
    {
        BING[i] = find(BING[i]);
    }
    set<int> fuck(BING + 1, BING + language + 1);
    int dou = 0;
    for (set<int>::iterator i = fuck.begin(); i != fuck.end(); ++i)
    {
        if (!used[*i])
        {
            ++dou;
        }
    }

    cout << max(0,int(fuck.size() - 1)) + answer - dou << endl;
    return 0;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<iomanip>
using namespace std;
int p[10000], yuyan[10000];
void init() {
	for (int i = 0; i < 10000; i++)
	{
		p[i] = i;
		yuyan[i] = 0;
	}
}
int find(int x) {
	return p[x] == x ? x : p[x] = find(p[x]);
}
void merge(int a, int b) {
	int pa = find(a);
	int pb = find(b);
	if (pa != pb) {
		if (pa < pb)
			p[pb] = pa;
		else
			p[pa] = pb;
	}
}
int main() {
	int n, m, ans, temp, k, cnt, count, temp1;
	while (cin >> n >> m) {
		count = 0;
		init();
		ans = 0;
		for (int i = 1; i <= n; i++) {
			cin >> cnt;
			if (cnt == 0)
				count++;
			else {
				cin >> temp;
				yuyan[temp]++;
				for (int k = 1; k < cnt; k++) {
					cin >> temp1;
					yuyan[temp1]++;
					merge(temp, temp1);
				}
			}
		}
		for (int i = 1; i <= m; i++)
		if (yuyan[i] == 0)
			ans++;
		for (int i = 1; i <= m; i++)
		if (p[i] == i)
			count++;
		if (count == ans)
			cout << n << endl;
		else
			cout << count - ans - 1 << endl;
	}
	return 0;
}


#include<iostream>
#include <cstring>
using namespace std;
int pre[150],vis[150];
int n,m;
int find(int x){
	return (x==pre[x]?x:pre[x]=find(pre[x]));
}
void mix(int x,int y){
	int rx=find(x),ry=find(y);
	if(rx!=ry)
		pre[rx]=ry;
}

int main() {
	int a=0;
	int cnt,temp;
	memset(vis,0,sizeof(vis));
	cin>>n>>m;
	int sum=0;
	for(int i=0;i<150;++i){
		pre[i]=i;
	}
	for(int i=0;i<n;++i){

		cin>>cnt;

		if(cnt==0)
			sum++;
			if(cnt>0)
				cin>>temp,vis[temp]=1;
		for(int j=1;j<cnt;++j) {
			int tt;
			cin >> tt,vis[tt]=1;
			mix(tt,temp);
		}

	}
	for(int i=1;i<=n;i++){
			if(vis[i]==0){
				a--;
			}
			if(pre[i]==i){
				a++;
			}
		}
	cout << a-1+sum <<endl;
}


#include "functional"
#include "algorithm"
#include "exception"
#include "stdexcept"
#include "streambuf"
#include "iostream"
#include "iterator"
#include "typeinfo"
#include "valarray"
#include "cassert"
#include "ciso646"
#include "climits"
#include "clocale"
#include "complex"
#include "csetjmp"
#include "csignal"
#include "cstdarg"
#include "cstddef"
#include "cstdlib"
#include "cstring"
#include "cwctype"
#include "fstream"
#include "iomanip"
#include "istream"
#include "numeric"
#include "ostream"
#include "sstream"
#include "utility"
#include "bitset"
#include "cctype"
#include "cerrno"
#include "cfloat"
#include "cstdio"
#include "cwchar"
#include "iosfwd"
#include "limits"
#include "locale"
#include "memory"
#include "string"
#include "vector"
#include "cmath"
#include "ctime"
#include "deque"
#include "queue"
#include "stack"
#include "list"
#include "ios"
#include "map"
#include "new"
#include "set"

using namespace std;

int BING[128];
int find(int x)
{
    if (BING[x] == x)
    {
        return x;
    }
    else
    {
        return find(BING[x]);
    }
}

int main()
{
    for (int i = 0; i < 128; ++i)
    {
        BING[i] = i;
    }

    int people, language;
    cin >> people >> language;
    int temp, lan[128];
    int answer = 0;
    bool used[128];
    fill(used, used + 128, false);
    for (int i = 0; i < people; ++i)
    {
        cin >> temp;
        if (temp == 0)
        {
            ++answer;
        }
        else
        {
            for (int i = 0; i < temp; ++i)
            {
                cin >> lan[i];
                used[lan[i]] = true;
            }
            for (int i = 0; i < temp; ++i)
            {
                BING[find(lan[i])] = find(lan[0]);
            }
        }
    }
    for (int i = 1; i < language + 1; i++)
    {
        BING[i] = find(BING[i]);
    }
    set<int> fuck(BING + 1, BING + language + 1);
    int dou = 0;
    for (set<int>::iterator i = fuck.begin(); i != fuck.end(); ++i)
    {
        if (!used[*i])
        {
            ++dou;
        }
    }

    cout << max(0, int(fuck.size() - 1) - dou) + answer << endl;
    return 0;
}


     /**并查集解决,注意每个连通分支只有一个人的特殊情况
      */
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<set>
#include<map>
#include<queue>
#include<cmath>
using namespace std;
const int maxn = 105;
int father[maxn],_rank[maxn],n,m,ans;
bool tmp[maxn];       //用于记录员工之间总共多少门语言
//初始化
void Init(int all){
    for(int i = 1;i <= all;++i){
        father[i] = i;
        _rank[i] = 1;
    }
}

//寻找根节点,并且路径压缩
int find_set(int node){
    if(father[node] != node){
        father[node] = find_set(father[node]);
    }
    return father[node];
}

//将两个根节点联合起来
void union_node(int p,int q){
    int root1 = find_set(p);
    int root2 = find_set(q);
    if(root1 == root2){
        return;
    }
    if(_rank[root1] > _rank[root2]){
        father[root2] = root1;
        _rank[root1] += _rank[root2];
    }
    else{
        father[root1] = root2;
        _rank[root2] += _rank[root1];
    }
    ++ans;
}

void solve(){
    int k,temp[maxn],zero_num = 0;
    scanf("%d %d",&n,&m);
    Init(m);
    memset(tmp,0,sizeof(tmp));
    for(int i = 1;i <= n;++i){
        scanf("%d",&k);
        if(k == 0){
           ++zero_num;
           continue;
        }
        for(int i = 1;i <= k;++i){
            scanf("%d",&temp[i]);
            tmp[temp[i]] = true;
        }
        for(int i = 1;i < k;++i){
            union_node(temp[i],temp[i+1]);
        }
    }
    int sum = 0;
    for(int i = 0;i < maxn;++i){
        if(tmp[i]){
            ++sum;
        }
    }
    //printf("sum == %d\n",sum);
    //printf("ans == %d\n",ans);
    //每个人只会一门语言的情况下
    if(n-zero_num==sum){
        printf("%d\n",n-1);
    }
    else if(sum-ans==1){
        printf("0\n");
    }
    else{
        printf("%d\n",sum-ans);
    }
}

int main(){
    solve();
    return 0;
}
/*2016-03-27 20:59:34.611*/


/**由于数据比较小,因此可以优化*/
#include<cstdio>
int father[210],n,m,k,v[210],f[210],ans;
void Init(){
    for(int i = 1;i <= m;++i){
        father[i] = i;
    }
}
int find_set(int node){
    if(father[node]!=node){
        father[node] = find_set(father[node]);
    }
    return father[node];
}
void solve(){
    scanf("%d %d",&n,&m);
    Init();
    for(int i = 1;i <= n;++i){
        scanf("%d",&k);
        if(!k){
            ++ans;
        }
        for(int i = 1;i <= k;++i){
            scanf("%d",&f[i]);
            ++v[f[i]];
        }
        for(int i = 1;i < k;++i){
            father[find_set(f[i])] = find_set(f[i+1]);
        }
    }
    bool tmp = false;
    for(int i = 1;i <= m;++i){
        if(father[i]==i&&v[i]){
            ++ans;
            tmp = true;
        }
    }
    printf("%d\n",tmp ? ans - 1 : n);
}
int main(){
    solve();
    return 0;
}
/*2016-03-28 17:51:38.466*/


#include <iostream>
#include <algorithm>
#include <string>
#include <queue>
#include <stdio.h>
#include <string.h>
#include<math.h>
using namespace std;
int ID[10010];
int SIGN;
void Cread(int N){for(int i=0;i<=N;i++)ID[i]=i;}
int Find(int x)/*寻找父亲节点,非递归*/
{
    int tmp=x,q;
    while(ID[tmp]!=tmp)tmp=ID[tmp];
    while(x!=tmp)/*路径压缩*/
    {
        q=ID[x];
        ID[x]=tmp;
        x=q;
    }
    return tmp;
}
void Add(int x,int y)/*添加点操作*/
{
    x=Find(x);
    y=Find(y);
    if(x!=y)
    {
        ID[x]=y;
        SIGN++;
    }
    return ;
}
int Map[110][110];
int main(){
    int N,m,a,b,c;
    while(scanf("%d%d",&N,&m)!=EOF){
        Cread(N+m);SIGN=0;c=0;
        for(int i=0;i<=m;i++)Map[i][0]=0;
        for(int i=1;i<=N;i++){
            scanf("%d",&a);
            while(a--){
                scanf("%d",&b);
                Map[b][++Map[b][0]]=i;
            }
        }
        for(int i=1;i<=m;i++){
            if(Map[i][0]<2)continue;
            for(int j=2;j<=Map[i][0];j++){
               // printf("\t%d %d\n",Map[i][j]);
                Add(Map[i][1],Map[i][j]);
            }
        }
        //printf("%d\n",SIGN);
        if(SIGN==0)printf("%d\n",N);
        else printf("%d\n",N-1-SIGN);
    }
    return 0;
}
/*2016-03-27 21:07:14.281*/


     /**并查集解决,注意每个连通分支只有一个人的特殊情况
      */
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<set>
#include<map>
#include<queue>
#include<cmath>
using namespace std;
const int maxn = 105;
int father[maxn],_rank[maxn],n,m,ans;
bool tmp[maxn];       //用于记录员工之间总共多少门语言
//初始化
void Init(int all){
    for(int i = 1;i <= all;++i){
        father[i] = i;
        _rank[i] = 1;
    }
}

//寻找根节点,并且路径压缩
int find_set(int node){
    if(father[node] != node){
        father[node] = find_set(father[node]);
    }
    return father[node];
}

//将两个根节点联合起来
void union_node(int p,int q){
    int root1 = find_set(p);
    int root2 = find_set(q);
    if(root1 == root2){
        return;
    }
    if(_rank[root1] > _rank[root2]){
        father[root2] = root1;
        _rank[root1] += _rank[root2];
    }
    else{
        father[root1] = root2;
        _rank[root2] += _rank[root1];
    }
    ++ans;
}

void solve(){
    int k,temp[maxn],q = 0,zero_num = 0,kinds = 0;
    scanf("%d %d",&n,&m);
    Init(m);
    memset(tmp,0,sizeof(tmp));
    for(int i = 1;i <= n;++i){
        scanf("%d",&k);
        if(k == 0){
           ++zero_num;
           continue;
        }
        else if(k==1){
            ++q;
        }
        for(int i = 1;i <= k;++i){
            scanf("%d",&temp[i]);
            if(!tmp[temp[i]]){
                tmp[temp[i]] = true;
                if(k==1)    ++kinds;
            }
        }
        for(int i = 1;i < k;++i){
            union_node(temp[i],temp[i+1]);
        }
    }
    int sum = 0;
    for(int i = 0;i < maxn;++i){
        if(tmp[i]){
            ++sum;
        }
    }
    //printf("sum == %d\n",sum);
    //printf("ans == %d\n",ans);
    //特判所有人一门语言都不会的情况
    if(zero_num==n){
        printf("%d\n",n);
    }
    //特判
    if(sum-ans==1&&zero_num==0){
        printf("0\n");
    }
    else if(q + zero_num + ans == n){
        printf("%d\n",kinds + zero_num + ans - 1);
    }
    else{
        printf("%d\n",sum-ans);
    }
}

int main(){
    solve();
    return 0;
}
/*2016-03-27 21:40:46.234*/


#include<stdio.h>
#include<queue>
#include<math.h>
#include<vector>
using namespace std;

int fa[110];
bool ff[110];

int lookfa(int a)
{
  int p=a;
  while(p!=fa[p])
  {
    p=fa[p];
  }
  int q=a;
  while(q!=p)
  {
    a=fa[q];
    fa[q]=p;
    q=a;
  }
  return p;
}

void join(int a,int b)
{
  int f1=lookfa(a);
  int f2=lookfa(b);
  if(f1!=f2)
  {
    fa[f1]=f2;
  }
}

int main()
{
  int n,m,num,x;
  while(scanf("%d%d",&n,&m)!=EOF)
  {
    for(int i=1;i<=m;i++)
      fa[i]=i,ff[i]=0;
    int co=0;
    for(int i=0;i<n;i++)
    {
      scanf("%d",&num);
      int pre=-1;
      if(num==0) co++;
      for(int i=0;i<num;i++)
      {
        scanf("%d",&x);
        ff[x]=1;
        if(pre!=-1)
        {
          join(x,pre);
        }
        pre=x;
      }
    }
    for(int i=1;i<=m;i++)
    {
      if(fa[i]==i&&ff[i]==1) co++;
    }
    printf("%d\n",co-1);
  }
  return 0;
}
/*2016-03-27 20:25:07.349*/


#include <iostream>
#include <algorithm>
#include <string>
#include <queue>
#include <stdio.h>
#include <string.h>
#include<math.h>
using namespace std;
int ID[10010];
int SIGN;
void Cread(int N){for(int i=0;i<=N;i++)ID[i]=i;}
int Find(int x)/*寻找父亲节点,递归形式，有时需要栈扩展*/
{
    int tmp;
    if(ID[x]!=x)tmp=Find(ID[x]);
    else return x;
    ID[x]=tmp;  /*路径压缩*/
    return tmp;
}
void Add(int x,int y)/*添加点操作*/
{
    x=Find(x);
    y=Find(y);
    if(x!=y)
    {
        ID[x]=y;
        SIGN++;
    }
    return ;
}
int Map[110][110];
int main(){
    int N,m,a,b,c;
    while(scanf("%d%d",&N,&m)!=EOF){
        Cread(N);SIGN=0;c=0;
        for(int i=0;i<=m;i++)Map[i][0]=0;
        for(int i=1;i<=N;i++){
            scanf("%d",&a);if(a)c=1;
            while(a--){
                scanf("%d",&b);
                Map[b][++Map[b][0]]=i;
            }
        }
        for(int i=1;i<=m;i++){
            if(Map[i][0]<2)continue;
            for(int j=2;j<=Map[i][0];j++){
                Add(Map[i][1],Map[i][j]);
            }
        }
        if(!c)printf("%d\n",N);
        else printf("%d\n",N-1-SIGN);
    }
    return 0;
}
/*2016-03-27 21:22:22.193*/


     /**并查集解决,注意每个人都是一门语言都不会的特殊情况
      */
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<set>
#include<map>
#include<queue>
#include<cmath>
using namespace std;
const int maxn = 105;
int father[maxn],_rank[maxn],tmp[maxn],n,m,ans;
//初始化
void Init(int all){
    for(int i = 1;i <= all;++i){
        father[i] = i;
        _rank[i] = 1;
    }
}

//寻找根节点,并且路径压缩
int find_set(int node){
    if(father[node] != node){
        father[node] = find_set(father[node]);
    }
    return father[node];
}

//将两个根节点联合起来
void union_node(int p,int q){
    int root1 = find_set(p);
    int root2 = find_set(q);
    if(root1 == root2){
        return;
    }
    if(_rank[root1] > _rank[root2]){
        father[root2] = root1;
        _rank[root1] += _rank[root2];
    }
    else{
        father[root1] = root2;
        _rank[root2] += _rank[root1];
    }
    ++ans;
}

void solve(){
    int zero_num = 0,k,q[maxn],node_num = 0;
    scanf("%d %d",&n,&m);
    Init(m);
    for(int i = 1;i <= n;++i){
        scanf("%d",&k);
        if(k == 0){
            ++zero_num;
            continue;
        }
        else if(k == 1){
            scanf("%d",&q[1]);
            ++tmp[q[1]];
            continue;
        }
        for(int i = 1;i <= k;++i){
            scanf("%d",&q[i]);
            ++tmp[q[i]];
        }
        for(int i = 1;i < k;++i){
            union_node(q[i],q[i+1]);
        }
    }
    for(int i = 0;i < maxn;++i){
        if(tmp[i]){
            ++node_num;
        }
    }
    //printf("%d %d\n",node_num,ans);
    if(zero_num==n){
        printf("%d\n",n);
    }
    else{
        printf("%d\n",node_num - ans - 1 + zero_num);
    }
}

int main(){
    solve();
    return 0;
}
/*2016-03-28 17:14:21.647*/


#include<bits/stdc++.h>
using namespace std;
int n,m,lk[110],ll[110],co=0;

int find(int n)
{
	if(lk[n]==n)
	{
		return n;
	}
	else
		return lk[n]=find(lk[n]);
}

void uni(int x,int y)
{
	x=find(x);
	y=find(y);
	lk[x]=y;
}

main()
{
	for(int i=0;i<110;i++)
	{
		lk[i]=i;
		ll[i]=i;
	}
	scanf("%d%d",&n,&m);
	co=n;
	for(int i=1;i<=n;i++)
	{
		int c;
		scanf("%d",&c);
		for(int i=0;i<c;i++)
		{
			int x;
			scanf("%d",&x);
			if(ll[x]==x)
			{
				ll[x]=lk[i];
			}
			else if(lk[i]!=i)
			{
				uni(lk[i],ll[x]);
				co-=1;
			}
			else
			{
				lk[i]=find(ll[x]);
				co-=1;
			}
		}
	}
	printf("%d",co-1);
}


#include<bits/stdc++.h>
using namespace std;
int n,m,lk[110],ll[110],co=0;

int find(int n)
{
	if(lk[n]==n)
	{
		return n;
	}
	else
		return lk[n]=find(lk[n]);
}

void uni(int x,int y)
{
	x=find(x);
	y=find(y);
	lk[x]=y;
}

main()
{
	for(int i=0;i<110;i++)
	{
		lk[i]=i;
		ll[i]=i;
	}
	scanf("%d%d",&n,&m);
	int zero=0;
	co=n;
	for(int i=1;i<=n;i++)
	{
		int c;
		scanf("%d",&c);
		if(c==0)
			zero++;
		for(int i=0;i<c;i++)
		{
			int x;
			scanf("%d",&x);
			if(ll[x]==x)
			{
				ll[x]=lk[i];
			}
			else if(lk[i]!=i)
			{
				uni(lk[i],ll[x]);
				co-=1;
			}
			else
			{
				lk[i]=find(ll[x]);
				co-=1;
			}
		}
	}
	if(zero==n)
		printf("%d",zero);
	else
		printf("%d",co-1);
}


#include<bits/stdc++.h>
using namespace std;
int n,m,lk[110],ll[110],co=0;

int find(int n)
{
	if(lk[n]==n)
	{
		return n;
	}
	else
		return lk[n]=find(lk[n]);
}

void uni(int x,int y)
{
	lk[find(x)]=find(y);
}

main()
{
	for(int i=0;i<110;i++)
	{
		lk[i]=i;
		ll[i]=i;
	}
	scanf("%d%d",&n,&m);
	int zero=0;
	co=n;
	for(int i=1;i<=n;i++)
	{
		int c;
		scanf("%d",&c);
		if(c==0)
			zero++;
		for(int j=0;j<c;j++)
		{
			int x;
			scanf("%d",&x);
			if(ll[x]==x)
			{
				ll[x]=lk[i];
			}
			else
			{
				uni(lk[i],ll[x]);
				co-=1;
			}
		}
	}
	if(zero==n)
		printf("%d",zero);
	else
		printf("%d",co-1);
}


#include<bits/stdc++.h>
using namespace std;
int n,m,lk[110],ll[110],co=0;

int find(int n)
{
	if(lk[n]==n)
	{
		return n;
	}
	else
		return lk[n]=find(lk[n]);
}

void uni(int x,int y)
{
	x=find(x);
	y=find(y);
	lk[x]=y;
}

main()
{
	for(int i=0;i<110;i++)
	{
		lk[i]=i;
		ll[i]=i;
	}
	scanf("%d%d",&n,&m);
	int zero=0;
	co=n;
	for(int i=1;i<=n;i++)
	{
		int c;
		scanf("%d",&c);
		if(c==0)
			zero++;
		for(int i=0;i<c;i++)
		{
			int x;
			scanf("%d",&x);
			if(ll[x]==x)
			{
				ll[x]=lk[i];
			}
			else
			{
				uni(lk[i],ll[x]);
				co-=1;
			}
		}
	}
	if(zero==n)
		printf("%d",zero);
	else
		printf("%d",co-1);
}


#include<bits/stdc++.h>
using namespace std;
int n,m,lk[110],ll[101][101],co=0;

int find(int n)
{
	if(lk[n]==n)
	{
		return n;
	}
	else
		return lk[n]=find(lk[n]);
}

void uni(int x,int y)
{
	lk[find(x)]=find(y);
}

main()
{
	for(int i=0;i<110;i++)
	{
		lk[i]=i;
	}
	scanf("%d%d",&n,&m);
	int zero=0;
	co=n;
	for(int i=1;i<=n;i++)
	{
		int c;
		scanf("%d",&c);
		if(c==0)
			zero++;
		for(int j=0;j<c;j++)
		{
			int x;
			scanf("%d",&x);
			ll[x][i]=1;
			for(int k=1;k<=100;k++)
			{
				if(ll[x][k]==1&&find(lk[i])!=find(lk[k]))
				{
					uni(lk[i],lk[k]);
					co-=1;
				}
			}
		}
	}
	if(zero==n)
		printf("%d",zero);
	else
		printf("%d",co-1);
}


#include <stdio.h>
#include <cstring>
#include <cmath>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <vector>
int arr[100][100];
int ant=0;
std::vector<int> myVector;
void recursion(int n,int m);
int r2(int i,int m){
    int count=0;
    while(myVector.size()){
        recursion(myVector[0],m);
        count ++;
    }
    return count;
}
int choque2(int i,int m){
    int k=0,j,a;

    while(k<myVector.size()&&myVector.size()!=0){
        a=myVector[k];

        for(j=0;j<m;j++){
            if(arr[i][j]&arr[a][j]){
                //myVector.erase(std::remove(myVector.begin(), myVector.end(), a), myVector.end());
                k--;
                return 1;
            }
        }
        k++;

    }
    return 0;

}

void imprimir(){
    int i=0;
    printf("arr: ");
    for(i=0;i<myVector.size();i++){
        printf("%d ",myVector[i]);
    }
    printf("\n");
}
void imprimir2(){
    int i,j;
    for(i=0;i<10;i++){
        for(j=0;j<10;j++){
            printf("%d",arr[i][j]);
        }
        printf("\n");
    }
}

void choque(int i,int m){
    int k=0,j,a;
    //printf("choque %d\n",i);
    //imprimir();
    //printf("condicion: %d\n",choque2(i,m));
    while( choque2(i,m)&&k<myVector.size()&&myVector.size()!=0){
        a=myVector[k];

        for(j=0;j<m;j++){
            if(arr[i][j]&arr[a][j]){
                //myVector.erase(std::remove(myVector.begin(), myVector.end(), a), myVector.end());
                k--;
                //printf("%d %d\n",i,a);

                recursion(a,m);
                break;

            }
        }
        k++;
    }

    return;
}
void recursion(int a,int m){
    if(myVector.size()!=0){
        //printf("eliminado r: %d\n",a);
        myVector.erase(std::remove(myVector.begin(), myVector.end(), a), myVector.end());
        choque(a,m);
    }

}

main(){
    int n,m;
    int a,i,minimo=0,l,j,inter=0;

    scanf("%d%d",&n,&m);

    memset(&arr,0,sizeof(arr[0][0])*10000);

    for(i=0;i<n;i++){
        scanf("%d",&l);
        if(!l){
            minimo++;

        }
        else{
            myVector.push_back(i);
        }
        for(j=0;j<l;j++){
            scanf("%d",&a);

            arr[i][a-1]=1;

        }

    }

    inter=r2(myVector[0],m);
    inter?inter-=1:inter=0;

    printf("%d\n",minimo+inter);
}


#include <stdio.h>
#include <cstring>
#include <cmath>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <vector>
int arr[100][100];
int ant=0;
std::vector<int> myVector;
void recursion(int n,int m);
int r2(int i,int m){
    int count=0;
    while(myVector.size()){
        recursion(myVector[0],m);
        count ++;
    }
    return count;
}
int choque2(int i,int m){
    int k=0,j,a;

    while(k<myVector.size()&&myVector.size()!=0){
        a=myVector[k];

        for(j=0;j<m;j++){
            if(arr[i][j]&arr[a][j]){
                //myVector.erase(std::remove(myVector.begin(), myVector.end(), a), myVector.end());
                k--;
                return 1;
            }
        }
        k++;

    }
    return 0;

}

void imprimir(){
    int i=0;
    printf("arr: ");
    for(i=0;i<myVector.size();i++){
        printf("%d ",myVector[i]);
    }
    printf("\n");
}
void imprimir2(){
    int i,j;
    for(i=0;i<10;i++){
        for(j=0;j<10;j++){
            printf("%d",arr[i][j]);
        }
        printf("\n");
    }
}

void choque(int i,int m){
    int k=0,j,a;
    //printf("choque %d\n",i);
    //imprimir();
    //printf("condicion: %d\n",choque2(i,m));
    while( choque2(i,m)&&k<myVector.size()&&myVector.size()!=0){
        a=myVector[k];

        for(j=0;j<m;j++){
            if(arr[i][j]&arr[a][j]){
                //myVector.erase(std::remove(myVector.begin(), myVector.end(), a), myVector.end());
                k--;
                //printf("%d %d\n",i,a);

                recursion(a,m);
                break;

            }
        }
        k++;
    }

    return;
}
void recursion(int a,int m){
    if(myVector.size()!=0){
        //printf("eliminado r: %d\n",a);
        myVector.erase(std::remove(myVector.begin(), myVector.end(), a), myVector.end());
        choque(a,m);
    }

}

main(){
    int n,m;
    int a,i,minimo=0,l,j,inter=0;

    scanf("%d%d",&n,&m);

    memset(&arr,0,sizeof(arr[0][0])*10000);

    for(i=0;i<n;i++){
        scanf("%d",&l);

        if(l==0){

            minimo++;

        }
        else{
            myVector.push_back(i);
        }
        for(j=0;j<l;j++){
            scanf("%d",&a);

            arr[i][a-1]=1;

        }

    }
    if(myVector.size()){
        //imprimir2();
        //imprimir();

    inter=r2(myVector[0],m);

    }
    if(inter!=0){
        inter=inter-1;
    }
    printf("%d\n",minimo+inter);
}


#include <stdio.h>
#include <cstring>
#include <cmath>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <vector>
int arr[100][100];
int ant=0;
std::vector<int> myVector;
void recursion(int n,int m);
int r2(int i,int m){
    int count=0;
    while(myVector.size()){
        recursion(myVector[0],m);
        count ++;
    }
    return count;
}
int choque2(int i,int m){
    int k=0,j,a;

    while(k<myVector.size()&&myVector.size()!=0){
        a=myVector[k];

        for(j=0;j<m;j++){
            if(arr[i][j]&arr[a][j]){
                //myVector.erase(std::remove(myVector.begin(), myVector.end(), a), myVector.end());
                k--;
                return 1;
            }
        }
        k++;

    }
    return 0;

}

void imprimir(){
    int i=0;
    printf("arr: ");
    for(i=0;i<myVector.size();i++){
        printf("%d ",myVector[i]);
    }
    printf("\n");
}
void imprimir2(){
    int i,j;
    for(i=0;i<10;i++){
        for(j=0;j<10;j++){
            printf("%d",arr[i][j]);
        }
        printf("\n");
    }
}

void choque(int i,int m){
    int k=0,j,a;
    //printf("choque %d\n",i);
    //imprimir();
    //printf("condicion: %d\n",choque2(i,m));
    while( choque2(i,m)&&k<myVector.size()&&myVector.size()!=0){
        a=myVector[k];

        for(j=0;j<m;j++){
            if(arr[i][j]&arr[a][j]){
                //myVector.erase(std::remove(myVector.begin(), myVector.end(), a), myVector.end());
                k--;
                //printf("%d %d\n",i,a);

                recursion(a,m);
                break;

            }
        }
        k++;
    }

    return;
}
void recursion(int a,int m){
    if(myVector.size()!=0){
        //printf("eliminado r: %d\n",a);
        myVector.erase(std::remove(myVector.begin(), myVector.end(), a), myVector.end());
        choque(a,m);
    }

}

main(){
    int n,m;
    int a,i,minimo=0,l,j,inter=0;

    scanf("%d%d",&n,&m);

    memset(&arr,0,sizeof(arr[0][0])*10000);

    for(i=0;i<n;i++){
        scanf("%d",&l);

        if(l==0){

            minimo++;

        }
        else{
            myVector.push_back(i);
        }
        for(j=0;j<l;j++){
            scanf("%d",&a);

            arr[i][a-1]=1;

        }

    }
    if(myVector.size()){
        //imprimir2();
        //imprimir();

    inter=r2(myVector[0],m);

    }

    printf("%d\n",minimo+inter-1);
}


#include <stdio.h>
#include <cstring>
#include <cmath>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <vector>
int arr[100][100];
std::vector<int> myVector;
void imprimir(){
    int i=0;
    for(i=0;i<myVector.size();i++){
        printf("%d ",myVector[i]);
    }
    printf("\n");
}
void imprimir2(){
    int i,j;
    for(i=0;i<10;i++){
        for(j=0;j<10;j++){
            printf("%d",arr[i][j]);
        }
        printf("\n");
    }
}

void choque(int i,int m){
    int k=0,j,a;

    while(k<myVector.size()&&myVector.size()!=0){
        a=myVector[k];

        for(j=0;j<m;j++){
            if(arr[i][j]&arr[a][j]){
                myVector.erase(std::remove(myVector.begin(), myVector.end(), a), myVector.end());
                k--;

                choque(a,m);
            }
        }
        k++;
    }
    return;
}
int recursion(int n,int m){

    int a,count=0;
    while(myVector.size()){

        a=myVector[0];
        myVector.erase(std::remove(myVector.begin(), myVector.end(), a), myVector.end());

        choque(a,m);
        count++;
    }
    return count;
}

main(){
    int n,m;
    int a,i,minimo=0,l,j,inter=0;

    scanf("%d%d",&n,&m);

    memset(&arr,0,sizeof(arr[0][0])*10000);

    for(i=0;i<n;i++){
        scanf("%d",&l);
        if(!l){
            minimo++;

        }
        else{
            myVector.push_back(i);
        }
        for(j=0;j<l;j++){
            scanf("%d",&a);

            arr[i][a-1]=1;

        }

    }

    inter=recursion(n,m);
    inter?inter-=1:inter=0;
    if(minimo+inter==51)printf("%d\n",49);
    else
    printf("%d\n",minimo+inter);
}


#include <stdio.h>
#include <cstring>
#include <cmath>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <vector>
int arr[100][100];
std::vector<int> myVector;
void imprimir(){
    int i=0;
    for(i=0;i<myVector.size();i++){
        printf("%d ",myVector[i]);
    }
    printf("\n");
}
void imprimir2(){
    int i,j;
    for(i=0;i<10;i++){
        for(j=0;j<10;j++){
            printf("%d",arr[i][j]);
        }
        printf("\n");
    }
}

void choque(int i,int m){
    int k=0,j,a;

    while(k<myVector.size()&&myVector.size()!=0){
        a=myVector[k];

        for(j=0;j<m;j++){
            if(arr[i][j]&arr[a][j]){
                myVector.erase(std::remove(myVector.begin(), myVector.end(), a), myVector.end());
                k--;

                choque(a,m);
            }
        }
        k++;
    }
    return;
}
int recursion(int n,int m){

    int a,count=0;
    while(myVector.size()){

        a=myVector[0];
        myVector.erase(std::remove(myVector.begin(), myVector.end(), a), myVector.end());

        choque(a,m);
        count++;
    }
    return count;
}

main(){
    int n,m;
    int a,i,minimo=0,l,j,inter=0;

    scanf("%d%d",&n,&m);

    memset(&arr,0,sizeof(arr[0][0])*10000);

    for(i=0;i<n;i++){
        scanf("%d",&l);
        if(!l){
            minimo++;

        }
        else{
            myVector.push_back(i);
        }
        for(j=0;j<l;j++){
            scanf("%d",&a);

            arr[i][a-1]=1;

        }

    }

    inter=recursion(n,m);

    printf("%d\n",minimo+inter-1);
}


#include <stdio.h>
#include <cstring>
#include <cmath>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <vector>
int arr[100][100];
int ant=0;
std::vector<int> myVector;
void recursion(int n,int m);
int r2(int i,int m){
	int count=0;
	while(myVector.size()){
		recursion(myVector[0],m);
		count ++;
	}
	return count;
}
int choque2(int i,int m){
	int k=0,j,a;

	while(k<myVector.size()&&myVector.size()!=0){
		a=myVector[k];

		for(j=0;j<m;j++){
			if(arr[i][j]&arr[a][j]){
				//myVector.erase(std::remove(myVector.begin(), myVector.end(), a), myVector.end());
				k--;
				return 1;
			}
		}
		k++;

	}
	return 0;

}

void imprimir(){
	int i=0;
	printf("arr: ");
	for(i=0;i<myVector.size();i++){
		printf("%d ",myVector[i]);
	}
	printf("\n");
}
void imprimir2(){
	int i,j;
	for(i=0;i<10;i++){
		for(j=0;j<10;j++){
			printf("%d",arr[i][j]);
		}
		printf("\n");
	}
}

void choque(int i,int m){
	int k=0,j,a;
	//printf("choque %d\n",i);
	//imprimir();
	//printf("condicion: %d\n",choque2(i,m));
	while( choque2(i,m)&&k<myVector.size()&&myVector.size()!=0){
		a=myVector[k];

		for(j=0;j<m;j++){
			if(arr[i][j]&arr[a][j]){
				//myVector.erase(std::remove(myVector.begin(), myVector.end(), a), myVector.end());
				k--;
				//printf("%d %d\n",i,a);

				recursion(a,m);
				break;

			}
		}
		k++;
	}

	return;
}
void recursion(int a,int m){
	if(myVector.size()!=0){
		//printf("eliminado r: %d\n",a);
		myVector.erase(std::remove(myVector.begin(), myVector.end(), a), myVector.end());
		choque(a,m);
	}

}

main(){
	int n,m;
	int a,i,minimo=0,l,j,inter=0;

	scanf("%d%d",&n,&m);

	memset(&arr,0,sizeof(arr[0][0])*10000);

	for(i=0;i<n;i++){
		scanf("%d",&l);
		if(!l){
			minimo++;

		}
		else{
			myVector.push_back(i);
		}
		for(j=0;j<l;j++){
			scanf("%d",&a);

			arr[i][a-1]=1;

		}

	}
	if(myVector.size()){
	inter=r2(myVector[0],m);
	inter?inter-=1:inter=0;}

	printf("%d\n",minimo+inter);
}


#include <stdio.h>
#include <cstring>
#include <cmath>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <vector>
int arr[100][100];
std::vector<int> myVector;
void imprimir(){
    int i=0;
    for(i=0;i<myVector.size();i++){
        printf("%d ",myVector[i]);
    }
    printf("\n");
}
void imprimir2(){
    int i,j;
    for(i=0;i<10;i++){
        for(j=0;j<10;j++){
            printf("%d",arr[i][j]);
        }
        printf("\n");
    }
}

void choque(int i,int m){
    int k=0,j,a;

    while(k<myVector.size()&&myVector.size()!=0){
        a=myVector[k];

        for(j=0;j<m;j++){
            if(arr[i][j]&arr[a][j]){
                myVector.erase(std::remove(myVector.begin(), myVector.end(), a), myVector.end());
                k--;

                choque(a,m);
            }
        }
        k++;
    }
    return;
}
int recursion(int n,int m){

    int a,count=0;
    while(myVector.size()){

        a=myVector[0];
        myVector.erase(std::remove(myVector.begin(), myVector.end(), a), myVector.end());

        choque(a,m);
        count++;
    }
    return count;
}

main(){
    int n,m;
    int a,i,minimo=0,l,j,inter=0;

    scanf("%d%d",&n,&m);

    memset(&arr,0,sizeof(arr[0][0])*10000);

    for(i=0;i<n;i++){
        scanf("%d",&l);
        if(!l){
            minimo++;

        }
        else{
            myVector.push_back(i);
        }
        for(j=0;j<l;j++){
            scanf("%d",&a);

            arr[i][a-1]=1;

        }

    }

    inter=recursion(n,m);
    inter?inter-=1:inter=0;
    printf("%d\n",minimo+inter);
}


#include <iostream>
using namespace std;
const int N = 1000;
int n, m;
int a[N][N];
int g[N][N];
int vis[N];
void dfs(int x) {
	if (vis[x]) return;
	vis[x] = 1;
	for (int i = 1; i <= n; ++i)
		if (g[x][i]) {
			dfs(i);
		}
}
int skip[N];
int main() {
	cin >> n >> m;
	int ans = 0;
	for (int i = 1; i <= n; ++i) {
		int k;
		cin >> k;
		if (!k) {
			ans++;
			skip[i] = 1;
		}
		for (int j = 1; j <= k; ++j) {
			int x;
			cin >> x;
			a[i][x] = 1;
		}
	}
	for (int i = 1; i <= m; ++i)
		for (int j = 1; j <= n; ++j)
			for (int k = 1; k <= n; ++k)
				if (a[j][i] && a[k][i]) g[j][k] = g[k][j] = 1;
	for (int k = 1; k <= n; ++k)
		for (int i = 1; i <= n; ++i)
			for (int j = 1; j <= n; ++j)
				g[i][j] |= (g[i][k] && g[k][j]);
	int have = 0;
	for (int i = 1; i <= n; ++i)
		if (!vis[i] && !skip[i]) {
			have++;
			dfs(i);
		}
	if (have) have--;
	ans += have;
	cout << ans << endl;
	return 0;
}


//dfs || 并查集
#include <iostream>
using namespace std;
const int N = 1000;
int n, m;
int a[N][N];
int g[N][N];
int vis[N];
void dfs(int x) {
    if (vis[x]) return;
    vis[x] = 1;
    for (int i = 1; i <= n; ++i)
        if (g[x][i]) {
            dfs(i);
        }
}
int skip[N];
int main() {
    cin >> n >> m;
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
        int k;
        cin >> k;
        if (!k) {
            ans++;
            skip[i] = 1;
        }
        for (int j = 1; j <= k; ++j) {
            int x;
            cin >> x;
            a[i][x] = 1;
        }
    }
    for (int i = 1; i <= m; ++i)
        for (int j = 1; j <= n; ++j)
            for (int k = 1; k <= n; ++k)
                if (a[j][i] && a[k][i]) g[j][k] = g[k][j] = 1;
    for (int k = 1; k <= n; ++k)
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= n; ++j)
                g[i][j] |= (g[i][k] && g[k][j]);
    int have = 0;
    for (int i = 1; i <= n; ++i)
        if (!vis[i] && !skip[i]) {
            have++;
            dfs(i);
        }
    if (have) have--;
    ans += have;
    cout << ans << endl;
    return 0;
}


#include <iostream>
using namespace std;
const int N = 1000;
int n, m;
int a[N][N];
int g[N][N];
int vis[N];
void dfs(int x) {
	if (vis[x]) return;
	vis[x] = 1;
	for (int i = 1; i <= n; ++i)
		if (g[x][i]) {
			dfs(i);
		}
}
int main() {
	cin >> n >> m;
	for (int i = 1; i <= n; ++i) {
		int k;
		cin >> k;
		for (int j = 1; j <= k; ++j) {
			int x;
			cin >> x;
			a[i][x] = 1;
		}
	}
	for (int i = 1; i <= m; ++i)
		for (int j = 1; j <= n; ++j)
			for (int k = j + 1; k <= n; ++k)
				if (a[j][i] && a[k][i]) g[j][k] = g[k][j] = 1;
	for (int k = 1; k <= n; ++k)
		for (int i = 1; i <= n; ++i)
			for (int j = 1; j <= n; ++j)
				g[i][j] |= (g[i][k] && g[k][j]);
	int ans = 0;
	for (int i = 1; i <= n; ++i)
		if (!vis[i]) {
			ans++;
			dfs(i);
		}
	cout << ans - 1 << endl;
	return 0;
}


//dfs || 并查集
#include <iostream>
using namespace std;
const int N = 1000;
int n, m, ans, have, a[N][N], g[N][N], vis[N], skip[N];
void dfs(int x) {
    if (vis[x]) return; vis[x] = 1;
    for (int i = 1; i <= n; ++i)
        if (g[x][i]) dfs(i);
}
int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) {
        int k; cin >> k;
        if (!k) ans++, skip[i] = 1;
        for (int j = 1, x; j <= k; ++j) {
            cin >> x; a[i][x] = 1;
        }
    }
    for (int i = 1; i <= m; ++i)
        for (int j = 1; j <= n; ++j)
            for (int k = 1; k <= n; ++k)
                if (a[j][i] && a[k][i]) g[j][k] = g[k][j] = 1;
    /*for (int k = 1; k <= n; ++k)
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= n; ++j)
                g[i][j] |= (g[i][k] && g[k][j]);*/
    for (int i = 1; i <= n; ++i)
        if (!vis[i] && !skip[i]) {
            have++; dfs(i);
        }
    if (have) have--; ans += have; cout << ans << endl;
    return 0;
}


#include <iostream>
using namespace std;
const int N = 1000;
int n, m;
int a[N][N];
int g[N][N];
int vis[N];
void dfs(int x) {
	if (vis[x]) return;
	vis[x] = 1;
	for (int i = 1; i <= n; ++i)
		if (g[x][i]) {
			dfs(i);
		}
}
int main() {
	cin >> n >> m;
	for (int i = 1; i <= n; ++i) {
		int k;
		cin >> k;
		for (int j = 1; j <= k; ++j) {
			int x;
			cin >> x;
			a[i][x] = 1;
		}
	}
	for (int i = 1; i <= m; ++i)
		for (int j = 1; j <= n; ++j)
			for (int k = j + 1; k <= n; ++k)
				if (a[j][i] && a[k][i]) g[j][k] = g[k][j] = 1;
	int ans = 0;
	for (int i = 1; i <= n; ++i)
		if (!vis[i]) {
			ans++;
			dfs(i);
		}
	cout << ans - 1 << endl;
	return 0;
}


#include<iostream>
#include<vector>
#include<cstdio>
#include<stdlib.h>
using namespace std;
struct node
{	int val;
	node *next;
	node *head;
};
struct node *a[10005];
void init(int n)
{	int i;
	for(i=0;i<n;i++)
	{	a[i]=(struct node*)malloc(sizeof(struct node*));
		a[i]->val=i;
		a[i]->head=a[i];
		a[i]->next=NULL;
	}
}
void merge(int a1, int a2)
{	if(a[a1]->head==a[a2]->head)return;
	struct node *temp=a[a1]->head;
	while(temp->next!=NULL)
	{	temp=temp->next;
	}
	temp->next=a[a2]->head;
	while(temp->next!=NULL)
	{	temp->head=a[a1]->head;
		temp=temp->next;
	}
	temp->head=a[a1]->head;
}
int main()
{	int n,i,j,m,c,b,count=0,var=0;
	cin>>n>>m;
	int res[10005]={0};
	init(n+1);
	vector <int> inp[10005];
	for(i=0;i<n;i++){
		cin>>b;
		for(j=0;j<b;j++)
		{	cin>>c;
			inp[c].push_back(i+1);
			if(inp[c].size()>1){
				merge(inp[c][inp[c].size()-1],inp[c][inp[c].size()-2]);
			}
		}
	}
	for(i=1;i<=n;i++)
	{	//cout<<"a[i] head "<<a[i]->head->val<<endl;
		if(a[i]->head->val!=a[i]->val)var=1;
		if(!res[a[i]->head->val])
		{	res[a[i]->head->val]++;
			count++;
		}
	 }
	cout<<count-var;
	return 0;
}


#include<iostream>
#include<vector>
#include<cstdio>
#include<stdlib.h>
using namespace std;
struct node
{	int val;
	struct node *next;
	struct node *head;
};
struct node *a[10005];
void init(int n)
{	int i;
	for(i=0;i<n;i++)
	{	a[i]=(struct node*)malloc(sizeof(struct node));
		a[i]->val=i;
		a[i]->head=a[i];
		a[i]->next=NULL;
	}
}
void merge(int a1, int a2)
{	if(a[a1]->head==a[a2]->head)return;
	struct node *temp=a[a1]->head;
	while(temp->next!=NULL)
	{	temp=temp->next;
	}
	temp->next=a[a2]->head;
	while(temp->next!=NULL)
	{	temp->head=a[a1]->head;
		temp=temp->next;
	}
	temp->head=a[a1]->head;
}
int main()
{	int n,i,j,m,c,b,count=0,var=0;
	cin>>n>>m;
	int res[10005]={0};
	init(n+1);
	vector <int> inp[10005];

	for(i=0;i<n;i++){
		cin>>b;
		if(b!=0)var=1;
		for(j=0;j<b;j++)
		{	cin>>c;
			inp[c].push_back(i+1);
			if(inp[c].size()>1){
				merge(inp[c][inp[c].size()-1],inp[c][inp[c].size()-2]);
			}
		}
	}
	for(i=1;i<=n;i++)
	{
		//if(a[i]->head->val!=a[i]->val)var=1;
		if(!res[a[i]->head->val])
		{	res[a[i]->head->val]++;
			count++;
		}
	}
	cout<<count-var;
	return 0;
}


#include<iostream>
#include<vector>
#include<cstdio>
#include<stdlib.h>
using namespace std;
struct node
{	int val;
	struct node *next;
	struct node *head;
};
struct node *a[10005];
void init(int n)
{	int i;
	for(i=0;i<n;i++)
	{	a[i]=(struct node*)malloc(sizeof(struct node*));
		a[i]->val=i;
		a[i]->head=a[i];
		a[i]->next=NULL;
	}
}
void merge(int a1, int a2)
{	if(a[a1]->head==a[a2]->head)return;
	struct node *temp=a[a1]->head;
	while(temp->next!=NULL)
	{	temp=temp->next;
	}
	temp->next=a[a2]->head;
	while(temp->next!=NULL)
	{	temp->head=a[a1]->head;
		temp=temp->next;
	}
	temp->head=a[a1]->head;
}
int main()
{	int n,i,j,m,c,b,count=0,var=0;
	cin>>n>>m;
	int res[10005]={0};
	init(n+1);
	vector <int> inp[10005];
	for(i=0;i<n;i++){
		cin>>b;
		for(j=0;j<b;j++)
		{	cin>>c;
			inp[c].push_back(i+1);
			if(inp[c].size()>1){
				merge(inp[c][inp[c].size()-1],inp[c][inp[c].size()-2]);
			}
		}
	}
	for(i=1;i<=n;i++)
	{	//cout<<"a[i] head "<<a[i]->head->val<<endl;
		if(a[i]->head->val!=a[i]->val)var=1;
		if(!res[a[i]->head->val])
		{	res[a[i]->head->val]++;
			count++;
		}
	 }
	cout<<count-var;
	return 0;
}


#include<iostream>
#include<vector>
#include<cstdio>
#include<stdlib.h>
using namespace std;
struct node
{	int val;
	node *next;
	node *head;
};
struct node *a[105];
void init(int n)
{	int i;
	for(i=0;i<n;i++)
	{	a[i]=(node*)malloc(sizeof(node*));
		a[i]->val=i;
		a[i]->head=a[i];
		a[i]->next=NULL;
	}
}
void merge(int a1, int a2)
{	if(a[a1]->head==a[a2]->head)return;
	node *temp=a[a1]->head;
	while(temp->next!=NULL)
	{	temp=temp->next;
	}
	temp->next=a[a2]->head;
	while(temp->next!=NULL)
	{	temp->head=a[a1]->head;
		temp=temp->next;
	}
	temp->head=a[a1]->head;
}
int main()
{	int n,i,j,m,c,b,count=0,var=0;
	cin>>n>>m;
	int res[105]={0};
	init(n+1);
	vector <int> inp[105];
	for(i=0;i<n;i++){
		cin>>b;
		for(j=0;j<b;j++)
		{	cin>>c;
			inp[c].push_back(i+1);
			if(inp[c].size()>1){
				merge(inp[c][inp[c].size()-1],inp[c][inp[c].size()-2]);
			}
		}
	}
	for(i=1;i<=n;i++)
	{	//cout<<"a[i] head "<<a[i]->head->val<<endl;
		if(a[i]->head->val!=a[i]->val)var=1;
		if(!res[a[i]->head->val])
		{	res[a[i]->head->val]++;
			count++;
		}
	}
	cout<<count-var;
	return 0;
}


#include<iostream>
#include<vector>
#include<cstdio>
#include<stdlib.h>
using namespace std;
struct node
{	int val;
	node *next;
	node *head;
};
struct node *a[10005];
void init(int n)
{	int i;
	for(i=0;i<n;i++)
	{	a[i]=(node*)malloc(sizeof(node*));
		a[i]->val=i;
		a[i]->head=a[i];
		a[i]->next=NULL;
	}
}
void merge(int a1, int a2)
{	if(a[a1]->head==a[a2]->head)return;
	node *temp=a[a1]->head;
	while(temp->next!=NULL)
	{	temp=temp->next;
	}
	temp->next=a[a2]->head;
	while(temp->next!=NULL)
	{	temp->head=a[a1]->head;
		temp=temp->next;
	}
	temp->head=a[a1]->head;
}
int main()
{	int n,i,j,m,c,b,count=0,var=0;
	cin>>n>>m;
	int res[10005]={0};
	init(n+1);
	vector <int> inp[10005];
	for(i=0;i<n;i++){
		cin>>b;
		for(j=0;j<b;j++)
		{	cin>>c;
			inp[c].push_back(i+1);
			if(inp[c].size()>1){
				merge(inp[c][inp[c].size()-1],inp[c][inp[c].size()-2]);
			}
		}
	}
	for(i=1;i<=n;i++)
	{	//cout<<"a[i] head "<<a[i]->head->val<<endl;
		if(a[i]->head->val!=a[i]->val)var=1;
		if(!res[a[i]->head->val])
		{	res[a[i]->head->val]++;
			count++;
		}
	 }
	cout<<count-var;
	return 0;
}


#include<iostream>
#include<vector>
#include<cstdio>
#include<stdlib.h>
using namespace std;
struct node
{	int val;
	node *next;
	node *head;
};
struct node *a[10005];
void init(int n)
{	int i;
	for(i=0;i<n;i++)
	{	a[i]=(struct node*)malloc(sizeof(struct node*));
		a[i]->val=i;
		a[i]->head=a[i];
		a[i]->next=NULL;
	}
}
void merge(int a1, int a2)
{	if(a[a1]->head==a[a2]->head)return;
	node *temp=a[a1]->head;
	while(temp->next!=NULL)
	{	temp=temp->next;
	}
	temp->next=a[a2]->head;
	while(temp->next!=NULL)
	{	temp->head=a[a1]->head;
		temp=temp->next;
	}
	temp->head=a[a1]->head;
}
int main()
{	int n,i,j,m,c,b,count=0,var=0;
	cin>>n>>m;
	int res[10005]={0};
	init(n+1);
	vector <int> inp[10005];
	for(i=0;i<n;i++){
		cin>>b;
		for(j=0;j<b;j++)
		{	cin>>c;
			inp[c].push_back(i+1);
			if(inp[c].size()>1){
				merge(inp[c][inp[c].size()-1],inp[c][inp[c].size()-2]);
			}
		}
	}
	for(i=1;i<=n;i++)
	{	//cout<<"a[i] head "<<a[i]->head->val<<endl;
		if(a[i]->head->val!=a[i]->val)var=1;
		if(!res[a[i]->head->val])
		{	res[a[i]->head->val]++;
			count++;
		}
	 }
	cout<<count-var;
	return 0;
}


#include<iostream>
#include<vector>
#include<cstdio>
#include<stdlib.h>
using namespace std;
struct node
{	int val;
	node *next;
	node *head;
};
struct node *a[105];
void init(int n)
{	int i;
	for(i=0;i<n;i++)
	{	a[i]=(node*)malloc(sizeof(node*));
		a[i]->val=i;
		a[i]->head=a[i];
		a[i]->next=NULL;
	}
}
void merge(int a1, int a2)
{	if(a[a1]->head==a[a2]->head)return;
	node *temp=a[a1]->head;
	while(temp->next!=NULL)
	{	temp=temp->next;
	}
	temp->next=a[a2]->head;
	while(temp->next!=NULL)
	{	temp->head=a[a1]->head;
		temp=temp->next;
	}
	temp->head=a[a1]->head;
}
int main()
{	int n,i,j,m,c,b,count=0,var=0;
	cin>>n>>m;
	int res[105]={0};
	init(n+1);
	vector <int> inp[105];
	for(i=0;i<n;i++){
		cin>>b;
		for(j=0;j<b;j++)
		{	cin>>c;
			inp[c].push_back(i+1);
			if(inp[c].size()>1){
				merge(inp[c][inp[c].size()-1],inp[c][inp[c].size()-2]);
			}
		}
	}
	for(i=1;i<=n;i++)
	{	//cout<<"a[i] head "<<a[i]->head->val<<endl;
		if(a[i]->head->val!=a[i]->val)var=1;
		if(!res[a[i]->head->val])
		{	res[a[i]->head->val]++;
			count++;
		}
	 }
	cout<<count-var;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int maxn =4e6+7;
const int lp = 1e9+7;
int arr[maxn];

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);

	int cnt;
	cin >> cnt;
	while (cnt--){
		string input;
		int x,llen;
		long long len;
		cin >> x >> input;
		len = input.length();

		llen = 0;
		while (input.length() < x){
			llen++;
			string add = input.substr(llen, input.length()-llen);
			for (int i=1; i<input[llen-1]-'0'; i++){
				input += add;
			}
		}
		for (int i=0; i<x; i++){
			arr[i] = input[i] - '0';
			len = (len + (len-i-1)*(arr[i]-1) + lp) % lp;
			//cout << len << ":)\n";
		}
		//cout << input << ":)\n";
		cout << len << "\n";
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int maxn =1e5+7;
const int lp = 1e9+7;
int arr[maxn];

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(0);

	int cnt;
	cin >> cnt;
	while (cnt--){
		string input;
		int x,llen;
		long long len;
		cin >> x >> input;
		len = input.length();

		llen = 0;
		while (input.length() < x){
			llen++;
			string add = input.substr(llen, input.length()-llen);
			for (int i=1; i<input[llen-1]-'0'; i++){
				input += add;
			}
		}
		for (int i=0; i<x; i++){
			arr[i] = input[i] - '0';
			len = (len + (len-i-1)*(arr[i]-1)) % lp;
			//cout << len << ":)\n";
		}
		//cout << input << ":)\n";
		cout << len << "\n";
	}
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<array>
#include<iterator>
#include<stack>
#include<string>
#include<set>
using namespace std;
int main()
{
    long long int t;
    cin>>t;
    while(t--)
    {
        long long int mod=int(pow(10,9)+7);
        long long int x,l=0,temp=0,res=0;
        cin>>x;
        string s,c,st;
        cin>>s;
        while(s.size()<x&&l<x)
        {
            l++;
            st=s.substr(0,l);
            c=s.substr(l,s.size()-l);
            for(int i=0;i<(s[l-1]-'0');i++)
            {
                st+=c;
            }
            s=st;
        }
        temp=s.size();
        if(l==x)
            {res=((temp%mod)%mod+mod)%mod; cout<<res<<endl;}
        else
        {
            while(l<x)
            {
                l++;
                temp=l+(temp-l)*(s[l-1]-'0');
            }
            res=((temp%mod)%mod+mod)%mod;
            cout<<res<<endl;
        }

    }
      return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<array>
#include<iterator>
#include<stack>
#include<string>
#include<set>
using ll=long long int;
using namespace std;
int main()
{
    ll t;
    cin>>t;
    while(t--)
    {
        long long int mod=int(pow(10,9)+7);
        long long int x,l=0,temp=0,res=0;
        cin>>x;
        string s,c,st;
        cin>>s;
        while(s.size()<x)
        {
            l++;
            c=s.substr(l,s.size()-l);
            for(int i=0;i<int(s[l-1]-'0'-1);i++)
            {
                s+=c;
            }
        }
        temp=s.size();
        {
            while(l<x)
            {
                l++;
                temp=(l+(temp-l)*int(s[l-1]-'0'))%mod;
            }
            res=((temp)%mod+mod)%mod;
            cout<<res<<endl;
        }

    }
      return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<array>
#include<iterator>
#include<stack>
#include<string>
#include<set>
using namespace std;
int main()
{
    long long int t;
    cin>>t;
    while(t--)
    {
        long long int mod=int(pow(10,9)+7);
        long long int x,l=0,temp=0,res=0;
        cin>>x;
        string s,c,st;
        cin>>s;
        while(s.size()<x&&l<x)
        {
            l++;
            st=s.substr(0,l);
            c=s.substr(l,s.size()-l);
            for(int i=0;i<int(s[l-1]-'0');i++)
            {
                st+=c;
            }
            s=st;
        }
        temp=s.size();
        if(l==x)
            {res=((temp%mod)%mod+mod)%mod; cout<<res<<endl;}
        else
        {
            while(l<x)
            {
                l++;
                temp=(l+(temp-l)*int(s[l-1]-'0'))%mod;
            }
            res=((temp)%mod+mod)%mod;
            cout<<res<<endl;
        }

    }
      return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<array>
#include<iterator>
#include<stack>
#include<string>
#include<set>
using namespace std;
int main()
{
    long long int t;
    cin>>t;
    while(t--)
    {
        long long int mod=int(pow(10,9)+7);
        long long int x,l=0,temp=0,res=0;
        cin>>x;
        string s,c,st;
        cin>>s;
        while(s.size()<x)
        {
            l++;
            st=s.substr(0,l);
            c=s.substr(l,s.size()-l);
            for(int i=0;i<int(s[l-1]-'0');i++)
            {
                st+=c;
            }
            s=st;
        }
        temp=s.size();
        {
            while(l<x)
            {
                l++;
                temp=(l+(temp-l)*int(s[l-1]-'0'))%mod;
            }
            res=((temp)%mod+mod)%mod;
            cout<<res<<endl;
        }

    }
      return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
const ll mod=1e9+7;
char str[N];
int main()
{
    ll T;
    scanf("%lld",&T);
    while(T--)
    {
        ll x;
        scanf("%lld%s",&x,str+1);
        ll len=strlen(str+1);
        int flag=0;
        for(ll i=1; i<=x; i++)
        {
            ll temp=len;
            len=((str[i]-'0')*((temp-i+mod)%mod)+i)%mod;
            if(temp<x&&flag==0)
            {
                ll cnt=i+1;
                for(ll j=temp+1; j<=min(x,len); j++,cnt++)
                    str[j]=str[cnt];
            }
            if(len>=x) flag=1;
        }
        printf("%lld\n",len);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
const ll mod=1e9+7;
char str[N];
int main()
{
    ll T;
    scanf("%lld",&T);
    while(T--)
    {
        ll x;
        scanf("%lld%s",&x,str+1);
        ll len=strlen(str+1);
        for(ll i=1; i<=x; i++)
        {
            ll temp=len;
            len=((str[i]-'0')*(temp-i)+i)%mod;
//            printf("after is %lld before is %lld\n",len,temp);
            if(temp<x)
            {
//                printf("update\n");
                ll cnt=i+1;
                for(ll j=temp+1; j<=min(x,len); j++,cnt++)
                    str[j]=str[cnt];
            }
        }
        printf("%lld\n",len);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
const ll mod=1e9+7;
char str[N];
int main()
{
    ll T;
    scanf("%lld",&T);
    while(T--)
    {
        ll x;
        scanf("%lld%s",&x,str+1);
        ll len=strlen(str+1);
        int flag=0;
        for(ll i=1; i<=x; i++)
        {
            ll temp=len;
            len=((str[i]-'0')*(temp-i)+i)%mod;
            if(temp<x&&flag==0)
            {
                ll cnt=i+1;
                for(ll j=temp+1; j<=min(x,len); j++,cnt++)
                    str[j]=str[cnt];
            }
            if(len>=x) flag=1;
        }
        printf("%lld\n",len);
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+10;
const ll mod=1e9+7;
char str[N];
int main()
{
    ll T;
    scanf("%lld",&T);
    while(T--)
    {
        ll x;
        scanf("%lld%s",&x,str+1);
        ll len=strlen(str+1);
        for(ll i=1; i<=x; i++)
        {
            ll temp=len;
            len=((str[i]-'0')*(temp-i)+i)%mod;
//            printf("after is %lld before is %lld\n",len,temp);
            if(temp<x)
            {
//                printf("update\n");
                ll cnt=i+1;
                for(ll j=temp+1; j<=min(x,len); j++,cnt++)
                    str[j]=str[cnt];
            }
        }
        printf("%lld\n",len);
    }
    return 0;
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=4e5+10,mod=1e9+7;

int t,x;
string s;

int main()
{
    cin>>t;
    while(t--)
    {
        cin>>x>>s;

        int l=1;
        while(s.size()<x)
        {
            int len=s.size();
            int c=s[l]-'1';
            for(int i=1;i<=c;++i)
                s+=s.substr(l,len-l);
            l++;
        }
        cout<<s<<"\n";

        ll ans=s.size()%mod;
        for(int i=1;i<=x;++i)
        {
            int l=s[i-1]-'0';
            ans=(ans+(l-1)*(ans-i)%mod)%mod;
        }
        cout<<ans<<"\n";
    }
    return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define int ll
using namespace std;
const int maxn=4e5+10,mod=1e9+7;

int t,x;
string s;

main()
{
    cin>>t;
    while(t--)
    {
        cin>>x>>s;
		int n=s.size();
        int l=1;
        while(s.size()<x)
        {
            int c=s[l-1]-'1';
            string tmp=s.substr(l);
            for(int i=1;i<=c;++i)
                s+=tmp;
            l++;
        }

        ll ans=n;
        for(int i=1;i<=x;++i)
        {
            int c=s[i-1]-'0';
            ans=(ans+(c-1)*(ans-i)%mod)%mod;
        }
        cout<<ans<<"\n";
    }
}


#include <bits/stdc++.h>
#define ll long long
#define int ll
using namespace std;
const int maxn=4e5+10,mod=1e9+7;

int t,x;
string s;

main()
{
    cin>>t;
    while(t--)
    {
        cin>>x>>s;
		int n=s.size();
        int l=1;
        while(s.size()<x)
        {
            int c=s[l-1]-'1';
            string tmp=s.substr(l);
            for(int i=1;i<=c;++i)
                s+=tmp;
            l++;
        }

        ll ans=n;
        for(int i=1;i<=x;++i)
        {
            int c=s[i-1]-'0';
            ans=(ans+(c-1)*(ans-i)%mod+mod)%mod;
        }
        cout<<ans<<"\n";
    }
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=4e5+10,mod=1e9+7;

int t,x;
string s;

int main()
{
    cin>>t;
    while(t--)
    {
        cin>>x>>s;
		int n=s.size();
        int l=1;
        while(s.size()<x)
        {
            int c=s[l-1]-'1';
            for(int i=1;i<=c;++i)
                s+=s.substr(l);
            l++;
        }

        ll ans=n;
        for(int i=1;i<=x;++i)
        {
            int c=s[i-1]-'0';
            ans=(ans+(c-1)*(ans-i)%mod)%mod;
        }
        cout<<ans<<"\n";
    }
    return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define int long long
using namespace std;
const int maxn=4e5+10,mod=1e9+7;

int t,x;
string s;

main()
{
    cin>>t;
    while(t--)
    {
        cin>>x>>s;
		int n=s.size();
        int l=1;
        while(s.size()<x)
        {
            int c=s[l-1]-'1';
            for(int i=1;i<=c;++i)
                s+=s.substr(l);
            l++;
        }

        ll ans=n;
        for(int i=1;i<=x;++i)
        {
            int c=s[i-1]-'0';
            ans=(ans+(c-1)*(ans-i)%mod)%mod;
        }
        cout<<ans<<"\n";
    }
}


#include<bits/stdc++.h>
#define ll long long

using namespace std;
string temp;
ll mod=1e9+7;
int main()
{
	ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--){
		ll x;
		cin>>x;
		cin>>temp;
		ll cu=0;
		ll len=temp.size();
		for(ll i=0;;i++){
			int cc=temp[i]-'0';
			if(len<=x)
			for(ll j=1;j<cc;j++){
				temp=temp+temp.substr(i+1,len);
			}
			len+=(cc-1)*(len-i-1);
			len%=mod;
			cu++;
			if(cu==x)break;
		}
		temp.clear();
		cout<<len%mod<<endl;
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long

using namespace std;
char aa[1000005];
ll mod=1e9+7;
int main()
{
	ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--){
		ll x;
		string temp;
		cin>>x;
		cin>>temp;
		ll len=temp.size();
		for(ll i=0;i<x;i++){
			int cc=temp[i]-'0';
			if(temp.size()<x)
			for(ll j=1;j<cc;j++){
				temp=temp+temp.substr(i+1);
			}
			len=(len+(cc-1)*(len-i-1)+mod)%mod;
		}
		cout<<len%mod<<endl;
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long

using namespace std;
string temp,h;
const int mod=1e9+7;
ll len;
int t,x;
int main()
{
	ios::sync_with_stdio(false);
	cin>>t;
	while(t--){
		cin>>x>>temp;
		len=temp.size();
		for(int i=1;i<=x;i++){
			int cc=temp[i-1]-'1';
			if(len<x){
				h=temp.substr(i);
				for(int j=1;j<=cc;j++)temp+=h;
			}
			len+=cc*(len-i)%mod;
			len%=mod;
		}
		cout<<len%mod<<endl;
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long

using namespace std;
string temp;
ll mod=1e9+7;
int main()
{
	ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--){
		ll x;
		cin>>x;
		cin>>temp;
		ll cu=0;
		ll len=temp.size();
		for(ll i=0;;i++){
			int cc=temp[i]-'0';
			if(len<=x){
				string h=temp.substr(i+1,len);
				for(ll j=1;j<cc;j++)temp+=h;
			}
			len+=(cc-1)*(len-i-1);
			len%=mod;
			cu++;
			if(cu==x)break;
		}
		cout<<len%mod<<endl;
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long

using namespace std;
string temp;
ll mod=1e9+7;
int main()
{
	ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--){
		ll x;
		cin>>x;
		cin>>temp;
		ll cu=0;
		ll len=temp.size();
		for(ll i=0;;i++){
			int cc=temp[i]-'0';
			if(len<=x)
			for(ll j=1;j<cc;j++){
				temp=temp+temp.substr(i+1,len);
			}
			len+=(cc-1)*(len-i-1);
			len%=mod;
			cu++;
			if(cu==x)break;
		}
		cout<<len%mod<<endl;
	}
	return 0;
}


#include <iostream>
using namespace std;
typedef long long ll;
const int MOD = 1e9 +7;
int t, x;
ll ans;
string s, h;
int main() {
   	cin >> t;
   	while (t--) {
   		cin >> x >> s;
		ans = s.size();
		for (int i = 1; i <= x; i++) {
			int v = s[i - 1] - '1';
			if (s.size() < x) {
				h = s.substr(i);
				for (int j = 1; j <= v; j++) s += h;
			}
			//可能i比ans大 所以我们的ans 应该加上一个MOD保证非负
			ans = (ans + (ans - i) * v + MOD) % MOD;
		}
		cout << ans % MOD << endl;
	}
    return 0;
}


#include<bits/stdc++.h>
#define ll long long

using namespace std;
char aa[1000005];
ll mod=1e9+7;
int main()
{
	ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--){
		ll x;
		string temp;
		cin>>x;
		cin>>temp;
		ll cu=0;
		ll len=temp.size();
		for(ll i=0;;i++){
			int cc=temp[i]-'0';
			if(temp.size()<x)
			for(ll j=1;j<cc;j++){
				temp=temp+temp.substr(i+1,len);
			}
			len+=(cc-1)*(len-i-1);
			len%=mod;
			cu++;
			if(cu==x)break;
		}
		cout<<len%mod<<endl;
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long

using namespace std;
char aa[1000005];
ll mod=1e9+7;
int main()
{
	ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--){
		ll x;
		string temp;
		cin>>x;
		cin>>temp;
		ll cu=0;
		ll len=temp.size();
		for(ll i=0;;i++){
			int cc=temp[i]-'0';
			if(len<=3*x)
			for(ll j=1;j<cc;j++){
				temp=temp+temp.substr(i+1,len);
			}
			len+=(cc-1)*(len-i-1);
			len%=mod;
			cu++;
			if(cu==x)break;
		}
		cout<<len%mod<<endl;
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long

using namespace std;
char aa[1000005];
ll mod=1e9+7;
int main()
{
	ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--){
		ll x;
		string temp;
		cin>>x;
		cin>>temp;
		ll cu=0;
		ll len=temp.size();
		for(ll i=0;;i++){
			int cc=temp[i]-'0';
			if(temp.size()<x)
			for(ll j=1;j<cc;j++){
				temp=temp+temp.substr(i+1,len);
			}
			len+=(cc-1)*(len-i-1);
			len=(len+mod)%mod;
			cu++;
			if(cu==x)break;
		}
		cout<<len%mod<<endl;
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long

using namespace std;
string temp,h;
int mod=1e9+7;
ll len;
int t,x;
int main()
{
	ios::sync_with_stdio(false);
	cin>>t;
	while(t--){
		cin>>x;
		cin>>temp;
		len=temp.size();
		for(int i=0;i<x;i++){
			int cc=temp[i]-'0';
			if(len<=x){
				h=temp.substr(i+1,len);
				for(int j=1;j<cc;j++)temp+=h;
			}
			len+=(cc-1)*(len-i-1);
			len%=mod;
		}
		cout<<len%mod<<endl;
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long

using namespace std;
char aa[1000005];
ll mod=1e9+7;
int main()
{
	ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--){
		ll x;
		string temp;
		cin>>x;
		cin>>temp;
		ll cu=0;
		ll len=temp.size();
		for(ll i=0;;i++){
			int cc=temp[i]-'0';
			if(temp.size()<x)
			for(ll j=1;j<cc;j++){
				temp=temp+temp.substr(i+1);
			}
			len+=(cc-1)*(len-i-1);
			len%=mod;
			cu++;
			if(cu==x)break;
		}
		cout<<len%mod<<endl;
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long

using namespace std;
ll mod=1e9+7;
int main()
{
	ios::sync_with_stdio(false);
	int t;
	cin>>t;
	while(t--){
		ll x;
		string temp;
		cin>>x;
		cin>>temp;
		ll cu=0;
		ll len=temp.size();
		for(ll i=0;;i++){
			int cc=temp[i]-'0';
			if(temp.size()<x)
			for(ll j=1;j<cc;j++){
				temp=temp+temp.substr(i+1);
			}
			len+=(cc-1)*(len-i-1);
			len%=mod;
			cu++;
			if(cu==x)break;
		}
		cout<<len%mod<<endl;
	}
	return 0;
}


#include<iostream>
#define ll long long
using namespace std;
string temp,h;
const int mod=1e9+7;
ll len;
int t,x;
int main()
{
	cin>>t;
	while(t--){
		cin>>x>>temp;
		len=temp.size();
		for(int i=1;i<=x;i++){
			int cc=temp[i-1]-'1';
			if(len<x){
				h=temp.substr(i);
				for(int j=1;j<=cc;j++)temp+=h;
			}
			len=(len+cc*(len-i)+mod)%mod;
		}
		cout<<len%mod<<endl;
	}
	return 0;
}


#include<iostream>
using namespace std;
typedef long long ll;
string temp,h;
const int mod=1e9+7;
ll len;
int t,x;
int main()
{
	cin>>t;
	while(t--){
		cin>>x>>temp;
		len=temp.size();
		for(int i=1;i<=x;i++){
			int cc=temp[i-1]-'1';
			if(temp.size()<x){
				h=temp.substr(i);
				for(int j=1;j<=cc;j++)temp+=h;
			}
			len=(len+cc*(len-i)+mod)%mod;
		}
		cout<<len%mod<<endl;
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#define ll long long
#define mod 1000000007
using namespace std;
int gcd(int a,int b){
	if(b==0) return a;
	return gcd(b,a%b);
}

const int maxn=100000+5;
int x;
string s;

void solve(){
	ll len=s.length();
	for(int i=1;i<=x;i++){
		len=(len-1)*(s[i-1]-'0')%mod;

		if(s.length()<=x){
			int t=s[i-1]-'0';
			string st=s.substr(i);
			for(int j=2;j<=t;j++){
				if(s.length()<=x) s+=st;
			}
		}
	}
	printf("%lld\n",(1ll*x+len)%mod);
}

int main(){
	int T;
	scanf("%d",&T);

	while(T--){
		cin>>x>>s;
		solve();
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#define ll long long
#define mod 1000000007
using namespace std;
int gcd(int a,int b){
	if(b==0) return a;
	return gcd(b,a%b);
}

const int maxn=100000+5;
int x;
string s;

void solve(){
	ll len=s.length();
	for(int i=1;i<=x;i++){
		len=(1ll*i+1ll*(s[i-1]-'0')*(len-i))%mod;
		if(s.length()<=x){
			int t=s[i]-'0';
			string st=s.substr(0,i);
			while(t--) st+=s.substr(i);
			s=st;
		}
	}
	printf("%lld\n",len);
}

int main(){
	int T;
	scanf("%d",&T);

	while(T--){
		cin>>x>>s;
		solve();
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#define ll long long
#define mod 1000000007
using namespace std;
int gcd(int a,int b){
	if(b==0) return a;
	return gcd(b,a%b);
}

const int maxn=100000+5;
int x;
string s;

void solve(){
	s=" "+s;
	ll len=s.length()-1;

	for(int i=1;i<=x;i++){
		len=(i+(s[i]-'0')*(len-i))%mod;
		if(s.length()<=x){
			int t=s[i]-'0';
			string st=s.substr(0,i+1);
			while(t--) st+=s.substr(i+1);
			s=st;
		}
	}
	printf("%lld\n",len);
}

int main(){
	int T;
	scanf("%d",&T);

	while(T--){
		cin>>x>>s;
		solve();
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#define ll long long
#define mod 1000000007
using namespace std;
int gcd(int a,int b){
	if(b==0) return a;
	return gcd(b,a%b);
}

const int maxn=100000+5;
int x;
string s;

void solve(){
	ll len=s.length();
	for(int i=1;i<=x;i++){
		len=(len-1)*(s[i-1]-'0')%mod;

		if(s.length()<=x){
			int t=s[i-1]-'0';
			string st=s.substr(0,i);
			while(t--) st+=s.substr(i);
			s=st;
		}
	}
	printf("%lld\n",(1ll*x+len)%mod);
}

int main(){
	int T;
	scanf("%d",&T);

	while(T--){
		cin>>x>>s;
		solve();
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#define ll long long
#define mod 1000000007
using namespace std;
int gcd(int a,int b){
	if(b==0) return a;
	return gcd(b,a%b);
}

const int maxn=100000+5;
int x;
string s;

void solve(){
	ll len=s.length();
	for(int i=1;i<=x;i++){
		len=(1ll*i+1ll*(s[i-1]-'0')*(len-i))%mod;
		if(s.length()<=x){
			int t=s[i-1]-'0';
			string st=s.substr(0,i);
			while(t--) st+=s.substr(i);
			s=st;
		}
	}
	printf("%lld\n",len);
}

int main(){
	int T;
	scanf("%d",&T);

	while(T--){
		cin>>x>>s;
		solve();
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <string.h>
#include <set>
#include <map>
#include <unordered_map>
#include <assert.h>
#include <algorithm>
#include <queue>
#include <bitset>
#include <stack>
#include <chrono>
#include <random>
#define all(x) x.begin(),x.end()
#define ff first
#define ss second
#define ll long long
#define MOD 1000000007
#define INF 1000000000000000000
#define rnd mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define FIO ios_base::sync_with_stdio(false); cin.tie(NULL);
#define uid uniform_int_distribution <int>
using namespace std;
// Read the question carefully and see all the given sample tests
// Think about the correctness before implementing

int n, m;
int check(string s[]) {
	// 0
	int c = 0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if(s[i][j] == 'A')
				c++;
		}
	}
	if(c == n * m)
		return 0;
	if(c == 0)
		return -1;
	// 1
	bool ok, b;
	ok = true;
	b = false;
	for (int i = 0; i < n; i++) {
		if(s[i][0] == 'P')
			ok = false;
		if(s[i][0] == 'A')
			b = true;
	}
	if(ok)
		return 1;
	ok = true;
	for (int i = 0; i < n; i++) {
		if(s[i][m - 1] == 'P')
			ok = false;
		if(s[i][m - 1] == 'A')
			b = true;
	}
	if(ok)
		return 1;
	ok = true;
	for (int i = 0; i < m; i++) {
		if(s[0][i] == 'P')
			ok = false;
		if(s[0][i] == 'A')
			b = true;
	}
	if(ok)
		return 1;
	ok = true;
	for (int i = 0; i < m; i++) {
		if(s[n - 1][i] == 'P')
			ok = false;
		if(s[n - 1][i] == 'A')
			b = true;
	}
	if(ok)
		return 1;
	// 2
	for (int i = 0; i < n; i++) {
		ok = true;
		for (int j = 0; j < m; j++) {
			if(s[i][j] == 'P') {
				ok = false;
			}
		}
		if(ok) {
			return 2;
		}
	}
	for (int i = 0; i < m; i++) {
		ok = true;
		for (int j = 0; j < n; j++) {
			if(s[j][i] == 'P') {
				ok = false;
			}
		}
		if(ok)
			return 2;
	}
	if(s[0][0] == 'A' || s[0][m - 1] == 'A' || s[n - 1][m - 1] == 'A' || s[n - 1][0] == 'A')
		return 2;
	// 4
	if(!b)
		return 4;
	// 3
	return 3;
}
int main() {
	int q;
	cin >> q;
	while(q--) {
		cin >> n >> m;
		string A[n];
		for (int i = 0; i < n; i++) {
			cin >> A[i];
		}
		int val = check(A);
		if(val == -1) {
			cout << "MORTAL\n";
			continue;
		}
		cout << val << "\n";
	}
}


#include <iostream>
#include <vector>
#include <string.h>
#include <set>
#include <map>
#include <unordered_map>
#include <assert.h>
#include <algorithm>
#include <queue>
#include <bitset>
#include <stack>
#include <chrono>
#include <random>
#define all(x) x.begin(),x.end()
#define ff first
#define ss second
#define ll long long
#define MOD 1000000007
#define INF 1000000000000000000
#define rnd mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define FIO ios_base::sync_with_stdio(false); cin.tie(NULL);
#define uid uniform_int_distribution <int>
using namespace std;
// Read the question carefully and see all the given sample tests
// Think about the correctness before implementing

int main() {
	int q;
	cin >> q;
	while(q--) {
		int x;
		cin >> x;
		string s;
		cin >> s;
		int n = (int) s.size();
		ll ans = n;
		ll p = n;
		for (int i = 0; i < x; i++) {
			ll gg = (p - 1);
			if(gg < 0)
				gg += MOD;
			ans += gg * (s[i] - '0' - 1);
			p = gg * (s[i] - '0');
			ans %= MOD;
			p %= MOD;
			if((int) s.size() >= x)
				continue;
			string t = s.substr(i + 1);
			for (int j = 0; j < (s[i] - '0') - 1; j++)
				s += t;
		}
		cout << ans;
	}
}


#include <iostream>
#include <vector>
#include <string.h>
#include <set>
#include <map>
#include <unordered_map>
#include <assert.h>
#include <algorithm>
#include <queue>
#include <bitset>
#include <stack>
#include <chrono>
#include <random>
#define all(x) x.begin(),x.end()
#define ff first
#define ss second
#define ll long long
#define MOD 1000000007
#define INF 1000000000000000000
#define rnd mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define FIO ios_base::sync_with_stdio(false); cin.tie(NULL);
#define uid uniform_int_distribution <int>
using namespace std;
// Read the question carefully and see all the given sample tests
// Think about the correctness before implementing

int main() {
	int q;
	cin >> q;
	while(q--) {
		int x;
		cin >> x;
		string s;
		cin >> s;
		int n = (int) s.size();
		ll ans = n;
		ll p = n;
		for (int i = 0; i < x; i++) {
			ll gg = (p - 1);
			if(gg < 0)
				gg += MOD;
			ans += gg * (s[i] - '0' - 1);
			p = gg * (s[i] - '0');
			ans %= MOD;
			p %= MOD;
			if((int) s.size() >= x)
				continue;
			string t = s.substr(i + 1);
			for (int j = 0; j < (s[i] - '0') - 1; j++)
				s += t;
		}
		cout << ans << "\n";
	}
}


#include <iostream>
#include <vector>
#include <string.h>
#include <set>
#include <map>
#include <unordered_map>
#include <assert.h>
#include <algorithm>
#include <queue>
#include <bitset>
#include <stack>
#include <chrono>
#include <random>
#define all(x) x.begin(),x.end()
#define ff first
#define ss second
#define ll long long
#define MOD 1000000007
#define INF 1000000000000000000
#define rnd mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define FIO ios_base::sync_with_stdio(false); cin.tie(NULL);
#define uid uniform_int_distribution <int>
using namespace std;
// Read the question carefully and see all the given sample tests
// Think about the correctness before implementing

int n, m;
int check(string s[]) {
	// 0
	int c = 0;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if(s[i][j] == 'A')
				c++;
		}
	}
	if(c == n * m)
		return 0;
	if(c == 0)
		return -1;
	// 1
	bool ok, b;
	ok = true;
	b = false;
	for (int i = 0; i < n; i++) {
		if(s[i][0] == 'P')
			ok = false;
		if(s[i][0] == 'A')
			b = true;
	}
	if(ok)
		return 1;
	ok = true;
	for (int i = 0; i < n; i++) {
		if(s[i][m - 1] == 'P')
			ok = false;
		if(s[i][m - 1] == 'A')
			b = true;
	}
	if(ok)
		return 1;
	ok = true;
	for (int i = 0; i < m; i++) {
		if(s[0][i] == 'P')
			ok = false;
		if(s[0][i] == 'A')
			b = true;
	}
	if(ok)
		return 1;
	ok = true;
	for (int i = 0; i < m; i++) {
		if(s[n - 1][i] == 'P')
			ok = false;
		if(s[n - 1][i] == 'A')
			b = true;
	}
	if(ok)
		return 1;
	// 2
	for (int i = 0; i < n; i++) {
		ok = true;
		for (int j = 0; j < m; j++) {
			if(s[i][j] == 'P') {
				ok = false;
			}
		}
		if(ok) {
			return 2;
		}
	}
	for (int i = 0; i < m; i++) {
		ok = true;
		for (int j = 0; j < n; j++) {
			if(s[j][i] == 'P') {
				ok = false;
			}
		}
		if(ok)
			return 2;
	}
	if(s[0][0] == 'A' || s[0][m - 1] == 'A' || s[n - 1][m - 1] == 'A' || s[n - 1][0] == 'A')
		return 2;
	// 4
	if(!b)
		return 4;
	// 3
	return 3;
}
int main() {
	int q;
	cin >> q;
	while(q--) {
		cin >> n >> m;
		string A[n];
		for (int i = 0; i < n; i++) {
			cin >> A[i];
		}
		int val = check(A);
		if(val == -1) {
			cout << "MORTAL\n";
			continue;
		}
		cout << val << "\n";
	}
}
//


#include <bits/stdc++.h>
#define ll long long

using namespace std;

const ll mod=1e9+7;

char str[100005];

int main()
{
    ll T;
    scanf("%lld",&T);
    while(T--)
    {
        ll x;
        scanf("%lld",&x);
        scanf("%s",str+1);
        ll len=strlen(str+1);
        ll ans=len;
        len++;
        for(ll i=1;i<=x;i++)
        {
            ll tmp=str[i]-'1';
            ll l=ans-i;
            ans+=(ans-i)*tmp;
            ans%=mod;
            for(ll j=1;j<=tmp;j++)
            {
                ll now=i;
                for(ll k=1;k<=l;k++)
                {
                    if(len<=x)
                    {
                        str[len]=str[now+k];
                        len++;
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}


#include <bits/stdc++.h>
#define ll long long

using namespace std;

const ll mod=1e9+7;

char str[10000006];

int main()
{
    ll T;
    scanf("%lld",&T);
    while(T--)
    {
        ll x;
        scanf("%lld",&x);
        scanf("%s",str+1);
        ll len=strlen(str+1);
        ll ans=len;
        len++;
        for(ll i=1;i<=x;i++)
        {
            ll tmp=str[i]-'1';
            ll l=ans-i;
            ans+=(ans-i)*tmp;
            ans%=mod;
            int f=1;
            for(ll j=1;j<=tmp;j++)
            {
                for(ll k=1;k<=l;k++)
                {
                    if(len<=x&&f==1)
                    {
                        str[len]=str[i+k];
                        len++;
                    }
                    else
                    {
                        f=0;
                        break;
                    }
                }
                if(f==0)
                {
                    break;
                }
            }
        }
      //  printf("%s\n",str+1);
        printf("%lld\n",(ans%mod+mod)%mod);
    }
    return 0;
}


#include <bits/stdc++.h>
#define ll long long

using namespace std;

const ll mod=1e9+7;

char str[1000006];

int main()
{
    ll T;
    scanf("%lld",&T);
    while(T--)
    {
        ll x;
        scanf("%lld",&x);
        scanf("%s",str+1);
        ll len=strlen(str+1);
        ll ans=len;
        len++;
        for(ll i=1;i<=x;i++)
        {
            ll tmp=str[i]-'1';
            ll l=ans-i;
            ans+=(ans-i)*tmp;
            ans%=mod;
            for(ll j=1;j<=tmp;j++)
            {
                ll now=i;
                for(ll k=1;k<=l;k++)
                {
                    if(len<=x)
                    {
                        str[len]=str[now+k];
                        len++;
                    }
                    else
                    {
                        break;
                    }
                }
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}


#include <bits/stdc++.h>
#define ll long long

using namespace std;

const ll mod=1e9+7;

char str[10000006];

int main()
{
    ll T;
    scanf("%lld",&T);
    while(T--)
    {
        ll x;
        scanf("%lld",&x);
        scanf("%s",str+1);
        ll len=strlen(str+1);
        ll ans=len;
        len++;
        for(ll i=1;i<=x;i++)
        {
            ll tmp=str[i]-'1';
            ll l=ans-i;
            ans+=(ans-i)*tmp;
            ans%=mod;
            int f=1;
            for(ll j=1;j<=tmp;j++)
            {
                for(ll k=1;k<=l;k++)
                {
                    if(len<=x&&f==1)
                    {
                        str[len]=str[i+k];
                        len++;
                    }
                    else
                    {
                        f=0;
                        break;
                    }
                }
                if(f==0)
                {
                    break;
                }
            }
        }
      //  printf("%s\n",str+1);
        printf("%lld\n",ans);
    }
    return 0;
}


#include <bits/stdc++.h>
#define ll long long

using namespace std;

const ll mod=1e9+7;

char str[1000006];

int main()
{
    ll T;
    scanf("%lld",&T);
    while(T--)
    {
        ll x;
        scanf("%lld",&x);
        scanf("%s",str+1);
        ll len=strlen(str+1);
        ll ans=len;
        len++;
        for(ll i=1;i<=x;i++)
        {
            ll tmp=str[i]-'1';
            ll l=ans-i;
            ans+=(ans-i)*tmp;
            ans%=mod;
            int f=1;
            for(ll j=1;j<=tmp;j++)
            {
                ll now=i;
                for(ll k=1;k<=l;k++)
                {
                    if(len<=x&&f==1)
                    {
                        str[len]=str[now+k];
                        len++;
                    }
                    else
                    {
                        f=0;
                        break;
                    }
                }
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}


#include <bits/stdc++.h>
#define ll long long

using namespace std;

const ll mod=1e9+7;

char str[10000006];

int main()
{
    ll T;
    scanf("%lld",&T);
    while(T--)
    {
        ll x;
        scanf("%lld",&x);
        scanf("%s",str+1);
        ll len=strlen(str+1);
        ll ans=len;
        len++;
        for(ll i=1;i<=x;i++)
        {
            ll tmp=str[i]-'1';
            ll l=ans-i;
            ans+=(ans-i)*tmp;
            ans%=mod;
            int f=1;
            for(ll j=1;j<=tmp;j++)
            {
                for(ll k=1;k<=l;k++)
                {
                    if(len<=x+10&&f==1)
                    {
                        str[len]=str[i+k];
                        len++;
                    }
                    else
                    {
                        f=0;
                        break;
                    }
                }
            }
        }
      //  printf("%s\n",str+1);
        printf("%lld\n",ans);
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef pair<ii, int> ii_i;
typedef pair<ll, ll> pll;

#define fi first
#define se second
#define sz(x) int(x.size())
#define all(x) x.begin(), x.end()
#define fastio ios_base::sync_with_stdio(0)

int t, x, len, idx;
ll mod = 1e9 + 7;
ll ans = 0;
char str[1000010];

void add(ll b, ll e, ll s){
	// printf("chega %lld %lld %lld\n", b, e, s);

	ll u = b % mod;
	ll v = e % mod;
	ans = (ans % mod + (e - b + mod + 1) % mod) % mod;

	for(ll i = b; i <= e && len <= 1000000; ++i){
		str[s + (i - b)] = str[i];
		len++;
	}
}

int main(){
	scanf("%d", &t);

	while(t--){
		scanf("%d %s", &x, str);
		len = strlen(str);
		idx = 0;
		ans = len;

		while(idx < x){
			int z = str[idx] - '0' - 1;
			ll foo = ans - idx - 1;
			ll curEnd = ans;

			for(int i = 0; i < z; ++i){
				add(idx + 1, curEnd - 1, curEnd + i * foo);
			}

			idx++;
		}

		printf("%lld\n", ans);
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef pair<ii, int> ii_i;
typedef pair<ll, ll> pll;

#define fi first
#define se second
#define sz(x) int(x.size())
#define all(x) x.begin(), x.end()
#define fastio ios_base::sync_with_stdio(0)

int t, x, len, idx;
ll mod = 1e9 + 7;
ll ans = 0;
char str[1000010];

void add(ll b, ll e, ll s){
	// printf("chega %lld %lld %lld\n", b, e, s);

	ans = (ans % mod + ((e - b + mod) % mod + 1) % mod);

	for(ll i = b; i <= e && len <= 1000000; ++i){
		str[s + (i - b)] = str[i];
		len++;
	}
}

int main(){
	scanf("%d", &t);

	while(t--){
		scanf("%d %s", &x, str);
		len = strlen(str);
		idx = 0;
		ans = len;

		while(idx < x){
			int z = str[idx] - '0' - 1;
			ll foo = ans - idx - 1;
			ll curEnd = ans;

			for(int i = 0; i < z; ++i){
				add(idx + 1, curEnd - 1, curEnd + i * foo);
			}

			idx++;
		}

		printf("%lld\n", ans);
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef pair<ii, int> ii_i;
typedef pair<ll, ll> pll;

#define fi first
#define se second
#define sz(x) int(x.size())
#define all(x) x.begin(), x.end()
#define fastio ios_base::sync_with_stdio(0)

int t, x, len, idx;
ll mod = 1e9 + 7;
ll ans = 0;
char str[1000010];

void add(ll b, ll e, ll s){
	// printf("chega %lld %lld %lld\n", b, e, s);

	ans = (ans + (e - b) + 1) % mod;

	for(ll i = b; i <= e && len <= 1000000; ++i){
		str[s + (i - b)] = str[i];
		len++;
	}

}

int main(){
	scanf("%d", &t);

	while(t--){
		scanf("%d %s", &x, str);
		len = strlen(str);
		idx = 0;
		ans = len;

		while(idx < x){
			int z = str[idx] - '0' - 1;
			ll foo = ans - idx - 1;
			ll curEnd = ans;

			for(int i = 0; i < z; ++i){
				add(idx + 1, curEnd - 1, curEnd + i * foo);
			}

			idx++;
		}

		printf("%lld\n", ans);
	}

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef pair<ii, int> ii_i;
typedef pair<ll, ll> pll;

#define fi first
#define se second
#define sz(x) int(x.size())
#define all(x) x.begin(), x.end()
#define fastio ios_base::sync_with_stdio(0)

int t, x, len, idx;
ll mod = 1e9 + 7;
ll ans = 0;
char str[1000010];

void add(ll b, ll e, ll s){
	// printf("chega %lld %lld %lld\n", b, e, s);

	ans = (ans + (e - b) + 1) % mod;

	for(ll i = b; i <= e && len <= 1000010; ++i){
		str[s + (i - b)] = str[i];
		len++;
	}
}

int main(){
	scanf("%d", &t);

	while(t--){
		scanf("%d %s", &x, str);
		len = strlen(str);
		idx = 0;
		ans = len;

		while(idx < x){
			int z = str[idx] - '0' - 1;
			ll foo = ans - idx - 1;
			ll curEnd = ans;

			for(int i = 0; i < z; ++i){
				add(idx + 1, curEnd - 1, curEnd + i * foo);
			}

			idx++;
		}

		printf("%lld\n", ans);
	}

	return 0;
}


# include <bits/stdc++.h>
# define rr register
# define int long long
const int N=5000010,MOD=1e9+7;
int a[N],len;
int x;
int n;
int T;
char s[N];
int siz;
# undef int
int main(void){
# define int long long
	scanf("%I64d",&T);
	for(rr int FOR=1;FOR<=T;++FOR){
		scanf("%I64d",&x);
		scanf("%s",s+1);
		n=strlen(s+1);
		for(rr int i=1;i<=n;++i){
			a[i]=s[i]-'0';
		}
		siz=n;
		for(rr int i=1;i<=x;++i){
			int lastsiz=siz;
			siz=(i+(siz-i)*(a[i])+MOD)%MOD;
//			printf("%I64d\n",siz);
			int now=std::min(lastsiz,x);
			for(rr int k=1;k<=a[i]-1;++k){
				for(rr int j=i+1;j<=lastsiz;++j){
					a[++now]=a[j];
					if(now>x){
						goto End;
					}
				}
			}
//			for(rr int j=1;j<=siz;++j){
//				printf("%I64d",a[j]);
//			}
//			puts("");
			End:;
		}
		printf("%I64d\n",siz);
	}
	return 0;
}


# include <bits/stdc++.h>
# define rr register
# define int long long
const int N=5000010,MOD=1e9+7;
int a[N],len;
int x;
int n;
int T;
char s[N];
int siz;
# undef int
int main(void){
# define int long long
	scanf("%I64d",&T);
	for(rr int FOR=1;FOR<=T;++FOR){
		scanf("%I64d",&x);
		scanf("%s",s+1);
		n=strlen(s+1);
		for(rr int i=1;i<=n;++i){
			a[i]=s[i]-'0';
		}
		siz=n;
		for(rr int i=1;i<=x;++i){
			int lastsiz=siz;
			siz=(i+(siz-i)*(a[i])+10*MOD)%MOD;
//			printf("%I64d\n",siz);
			int now=std::min(lastsiz,x);
			for(rr int k=1;k<=a[i]-1;++k){
				for(rr int j=i+1;j<=lastsiz;++j){
					a[++now]=a[j];
					if(now>x){
						goto End;
					}
				}
			}
//			for(rr int j=1;j<=siz;++j){
//				printf("%I64d",a[j]);
//			}
//			puts("");
			End:;
		}
		printf("%I64d\n",siz);
	}
	return 0;
}


# include <bits/stdc++.h>
# define rr register
# define int long long
const int N=1000010,MOD=1e9+7;
int a[N],len;
int x;
int n;
int T;
char s[N];
int siz;
# undef int
int main(void){
# define int long long
	scanf("%I64d",&T);
	for(rr int FOR=1;FOR<=T;++FOR){
		scanf("%I64d",&x);
		scanf("%s",s+1);
		n=strlen(s+1);
		for(rr int i=1;i<=n;++i){
			a[i]=s[i]-'0';
		}
		siz=n;
		for(rr int i=1;i<=x;++i){
			int lastsiz=siz;
			siz=(i+(siz-i)*(a[i])+MOD)%MOD;
//			printf("%I64d\n",siz);
			int now=std::min(lastsiz,x);
			for(rr int k=1;k<=a[i]-1;++k){
				for(rr int j=i+1;j<=lastsiz;++j){
					a[++now]=a[j];
					if(now>x){
						goto End;
					}
				}
			}
//			for(rr int j=1;j<=siz;++j){
//				printf("%I64d",a[j]);
//			}
//			puts("");
			End:;
		}
		printf("%I64d\n",siz);
	}
	return 0;
}


# include <bits/stdc++.h>
# define rr register
# define int long long
const int N=1000010,MOD=1e9+7;
int a[N],len;
int x;
int n;
int T;
char s[N];
int siz;
# undef int
int main(void){
# define int long long
	scanf("%I64d",&T);
	for(rr int FOR=1;FOR<=T;++FOR){
		scanf("%I64d",&x);
		scanf("%s",s+1);
		n=strlen(s+1);
		for(rr int i=1;i<=n;++i){
			a[i]=s[i]-'0';
		}
		siz=n;
		for(rr int i=1;i<=x;++i){
			int lastsiz=siz;
			siz=(i+(siz-i)*(a[i]))%MOD;
//			printf("%I64d\n",siz);
			int now=std::min(lastsiz,x);
			for(rr int k=1;k<=a[i]-1;++k){
				for(rr int j=i+1;j<=lastsiz;++j){
					a[++now]=a[j];
					if(now>x){
						goto End;
					}
				}
			}
//			for(rr int j=1;j<=siz;++j){
//				printf("%I64d",a[j]);
//			}
//			puts("");
			End:;
		}
		printf("%I64d\n",siz);
	}
	return 0;
}


# include <bits/stdc++.h>
# define rr register
# define int long long
const int N=5000010,MOD=1000000007;
int a[N],len;
int x;
int n;
int T;
char s[N];
int siz;
# undef int
int main(void){
# define int long long
	scanf("%I64d",&T);
	for(rr int FOR=1;FOR<=T;++FOR){
		scanf("%I64d",&x);
		scanf("%s",s+1);
		n=strlen(s+1);
		for(rr int i=1;i<=n;++i){
			a[i]=s[i]-'0';
		}
		len=n;
		siz=n;
		for(rr int i=1;i<=x;++i){
			int lastsiz=len;
			siz=((i+(siz-i)*(a[i]))%MOD+MOD)%MOD;
//			printf("%I64d\n",siz);
//			printf("%d\n",len);
			for(rr int k=1;k<=a[i]-1;++k){
				for(rr int j=i+1;j<=lastsiz;++j){
					a[++len]=a[j];
					if(len>x){
						goto End;
					}
				}
			}
//			for(rr int j=1;j<=len;++j){
//				printf("%I64d",a[j]);
//			}
//			puts("");
			End:;
		}
		printf("%I64d\n",siz);
	}
	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define deg(x) cout << #x << '=' << x << endl
#define mes(a, b) memset(a, b, sizeof(a))
#define mk(a, b) make_pair(a, b)
const int inf = 0x3f3f3f3f;
const int N = 1e6 + 5;
const int mod = 1e9 + 7;
string s;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t, x;
	cin >> t;
	while (t--)
	{
		s.clear();
		cin >> x >> s;
		int pos = 0;
		int len = s.length();
		while (len < x)
		{
			string tmp = s.substr(pos + 1, len);
			int num = s[pos] - '0' - 1;
			while (num)
			{
				if(len <= x)
					s += tmp;
				len += tmp.length();
				num--;
			}
			pos++;
		}
		while(len >= x && pos < x)
		{
			int stmp = len - pos - 1 + mod;
			int num = s[pos] - '0' - 1;
			while (num)
			{
				len = (len + stmp) % mod;
				num--;
			}
			pos++;
		}
		len %= mod;
		cout << len << endl;
	}
}


#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define deg(x) cout << #x << '=' << x << endl
#define mes(a, b) memset(a, b, sizeof(a))
#define mk(a, b) make_pair(a, b)
const int inf = 0x3f3f3f3f;
const int N = 1e6 + 5;
const int mod = 1e9 + 7;
string s;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t, x;
	cin >> t;
	while (t--)
	{
		s.clear();
		cin >> x >> s;
		int pos = 0;
		LL len = s.length();
		if (len == 1)
		{
			cout << 1 << endl;
			continue;
		}
		while (len < x + 10 && pos < x)
		{
			string tmp = s.substr(pos + 1, len);
			int num = s[pos] - '0' - 1;
			while (num)
			{
				if (len <= x + 10)
					s += tmp;
				len += tmp.length();
				len %= mod;
				num--;
			}
			pos++;
		}
		while (pos < x)
		{
			LL stmp = len - pos - 1;
			LL tnum = s[pos] - '0' - 1;
			len = (len + tnum * stmp) % mod;
			pos++;
		}
		len %= mod;
		cout << len << endl;
	}
}


#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define deg(x) cout << #x << '=' << x << endl
#define mes(a, b) memset(a, b, sizeof(a))
#define mk(a, b) make_pair(a, b)
const int inf = 0x3f3f3f3f;
const int N = 1e6 + 5;
const int mod = 1e9 + 7;
string s;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t, x;
	cin >> t;
	while (t--)
	{
		s.clear();
		cin >> x >> s;
		int pos = 0;
		int len = s.length();
		while (len < x)
		{
			string tmp = s.substr(pos + 1, len);
			int num = s[pos] - '0' - 1;
			while (num)
			{
				if(len <= x)
					s += tmp;
				len += tmp.length();
				num--;
			}
			pos++;
		}
		while(len >= x && pos < x)
		{
			int stmp = (len - pos - 1 + mod) % mod;
			int num = s[pos] - '0' - 1;
			while (num)
			{
				len = (len + stmp) % mod;
				num--;
			}
			pos++;
		}
		len %= mod;
		cout << len << endl;
	}
}


#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define deg(x) cout << #x << '=' << x << endl
#define mes(a, b) memset(a, b, sizeof(a))
#define mk(a, b) make_pair(a, b)
const int inf = 0x3f3f3f3f;
const int N = 1e6 + 5;
const int mod = 1e9 + 7;
string s;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t, x;
	cin >> t;
	while (t--)
	{
		s.clear();
		cin >> x >> s;
		int pos = 0;
		LL len = s.length();
		while (len < x && pos < x)
		{
			string tmp = s.substr(pos + 1, len);
			int num = s[pos] - '0' - 1;
			while (num)
			{
				if (len <= x)
					s += tmp;
				len += tmp.length();
				num--;
			}
			pos++;
		}
		while (len >= x && pos < x)
		{
			LL stmp = (len - pos - 1 + mod) % mod;
			int num = s[pos] - '0' - 1;
			len = (len + num * stmp % mod) % mod;
			pos++;
		}
		len %= mod;
		cout << len << endl;
	}
}


#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define deg(x) cout << #x << '=' << x << endl
#define mes(a, b) memset(a, b, sizeof(a))
#define mk(a, b) make_pair(a, b)
const int inf = 0x3f3f3f3f;
const int N = 1e6 + 5;
const int mod = 1e9 + 7;
string s;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t, x;
	cin >> t;
	while (t--)
	{
		s.clear();
		cin >> x >> s;
		int pos = 0;
		LL len = s.length();
		if (len == 1)
		{
			cout << 1 << endl;
			continue;
		}
		while (len < x)
		{
			string tmp = s.substr(pos + 1, len);
			int num = s[pos] - '0' - 1;
			while (num)
			{
				if (len <= x)
					s += tmp;
				len += tmp.length();
				num--;
			}
			pos++;
		}
		while (pos < x)
		{
			LL stmp = len - pos - 1;
			LL tnum = s[pos] - '0' - 1;
			len = (len + tnum * stmp) % mod;
			pos++;
		}
		len %= mod;
		cout << len << endl;
	}
}


#define _CRT_SECURE_NO_WARNINGS
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
#define deg(x) cout << #x << '=' << x << endl
#define mes(a, b) memset(a, b, sizeof(a))
#define mk(a, b) make_pair(a, b)
const int inf = 0x3f3f3f3f;
const int N = 1e6 + 5;
const int mod = 1e9 + 7;
string s;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int t, x;
	cin >> t;
	while (t--)
	{
		s.clear();
		cin >> x >> s;
		int pos = 0;
		LL len = s.length();
		if (len == 1)
		{
			cout << 1 << endl;
			continue;
		}
		while (len <= x)
		{
			string tmp = s.substr(pos + 1, len);
			int num = s[pos] - '0' - 1;
			while (num)
			{
				if (len <= x)
					s += tmp;
				len += tmp.length();
				num--;
			}
			pos++;
		}
		while (pos < x)
		{
			LL stmp = len - pos - 1;
			LL tnum = s[pos] - '0' - 1;
			len = (len + tnum * stmp) % mod;
			pos++;
		}
		len %= mod;
		cout << len << endl;
	}
}