//  [cpp]
#include <bits/stdc++.h>
#define ll long long int
#define ld long double
#define ull unsigned long long int
#define forn(i,n)for(ll i=0;i<(n);i++)
#define forn_rev(i,n)for(ll i=(n)-1;i>=0;i--)
#define for1n(i,n) for(ll i=1;i<=(n);i++)
#define ARRAY_SIZE(a) sizeof(a)/sizeof(*a)
#define MOD 1000000007
#define MAXN 10005

using namespace std;

vector<vector<ll>> dp(MAXN,vector<ll>(MAXN,-1));

ll solve(ll i,ll left,ll M,vector<pair<ll,ll>> &arr){
    if(dp[i][left]!=-1) return dp[i][left];
    if(i==M){
        if(!left) return 1;
        return 0;
    }
    ll temp=0;
    for(ll j=arr[i].first;j<=arr[i].second && j<=left;j++){
        temp+=solve(i+1,left-j,M,arr);
    }
    return dp[i][left]=temp;

}


int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);cout.tie(NULL);
    ll T=1;
    //cin>>T;
    while(T--)
    {
        ll N,K;
        cin>>N>>K;
        vector<ll> arr[N];
        forn(i,K){
            ll d;
            cin>>d;
            forn(j,d){
                ll ind;
                cin>>ind;
                arr[ind-1].push_back(i);
            }
        }
        ll ans=0;
        forn(i,N) if(arr[i].size()==0) ans++;
        cout<<ans;










    }



    return 0;
}


/*


struct data{

    ll count,index;

};

vector<ll> arr(10000);
vector<data> tmax(4*MAXN);



auto combine(data a,data b){
    //ultra based combine function for easier understanding
    data res=0;
    if(a>0) res.count++;
    if(b>0) res.count++
    return res;
}



void build(ll v,ll tl,ll tr)
{
    if(tl==tr)
    {

        tmax[v]=arr[tl];
        //leaf nodes
    }
    else
    {
        //store in array. Thus childs are 2*v and 2*v+1
        ll tm=(tl+tr)/2;//mid point
        build(2*v,tl,tm);//recurse to left sub tree
        build(2*v+1,tm+1,tr);//recurse to right tree
        tmax[v]=combine(tmax[2*v],tmax[2*v+1]);
    }
}

auto getmax(ll v,ll tl,ll tr,ll l,ll r)
{
    if(r<tl || l>tr)
        return -1;//check if outside range
    if(l<=tl && tr<=r)
        return tmax[v];//in range then return that value

    ll tm=(tl+tr)/2;
    //recurse to left and right subtree
    ll left=getmax(2*v,tl,tm,l,r),right=getmax(2*v+1,tm+1,tr,l,r);
    return combine(left,right);
}

ll update(ll v,ll tl,ll tr,ll l,ll tr,ll val){
    if(l>r) return;
    if(l==tl && tr==r){
        if(tmax[v]>=0)
            tmax[v]+=val;//update tree leaves here
        else return -1;

    }
    else{
        ll tm=(tl+tr)/2;
        if(tl>=m)
        ll right=update(2*v+1,tm+1,tr,val);//recurse to right subtree
        if(right==-1) return -1;
        update(2*v,tl,tm,val);//recurse to left subtree

        tmax[v]=combine(tmax[2*v],tmax[2*v+1]);//combine

    }

}
void pointupdate(ll v,ll tl,ll tr,ll pos,ll val){

    if(tl==tr){
        tmax[v]=make_data(val);//update tree leaves here

    }
    else{
        ll tm=(tl+tr)/2;
        if(pos<=tm) update(2*v,tl,tm,val);//recurse to left subtree
        else update(2*v+1,tm+1,tr,val);//recurse to right subtree

        tmax[v]=combine(tmax[2*v],tmax[2*v+1]);//combine

    }

}


*/





/*


struct data{

    ll count,index;

};

vector<ll> arr(10000);
vector<data> tmax(4*MAXN);



auto combine(data a,data b){
    //ultra based combine function for easier understanding
    data res=0;
    if(a>0) res.count++;
    if(b>0) res.count++
    return res;
}



void build(ll v,ll tl,ll tr)
{
    if(tl==tr)
    {

        tmax[v]=arr[tl];
        //leaf nodes
    }
    else
    {
        //store in array. Thus childs are 2*v and 2*v+1
        ll tm=(tl+tr)/2;//mid point
        build(2*v,tl,tm);//recurse to left sub tree
        build(2*v+1,tm+1,tr);//recurse to right tree
        tmax[v]=combine(tmax[2*v],tmax[2*v+1]);
    }
}

auto getmax(ll v,ll tl,ll tr,ll l,ll r)
{
    if(r<tl || l>tr)
        return -1;//check if outside range
    if(l<=tl && tr<=r)
        return tmax[v];//in range then return that value

    ll tm=(tl+tr)/2;
    //recurse to left and right subtree
    ll left=getmax(2*v,tl,tm,l,r),right=getmax(2*v+1,tm+1,tr,l,r);
    return combine(left,right);
}

ll update(ll v,ll tl,ll tr,ll l,ll tr,ll val){
    if(l>r) return;
    if(l==tl && tr==r){
        if(tmax[v]>=0)
            tmax[v]+=val;//update tree leaves here
        else return -1;

    }
    else{
        ll tm=(tl+tr)/2;
        if(tl>=m)
        ll right=update(2*v+1,tm+1,tr,val);//recurse to right subtree
        if(right==-1) return -1;
        update(2*v,tl,tm,val);//recurse to left subtree

        tmax[v]=combine(tmax[2*v],tmax[2*v+1]);//combine

    }

}
void pointupdate(ll v,ll tl,ll tr,ll pos,ll val){

    if(tl==tr){
        tmax[v]=make_data(val);//update tree leaves here

    }
    else{
        ll tm=(tl+tr)/2;
        if(pos<=tm) update(2*v,tl,tm,val);//recurse to left subtree
        else update(2*v+1,tm+1,tr,val);//recurse to right subtree

        tmax[v]=combine(tmax[2*v],tmax[2*v+1]);//combine

    }

}


*/