/*
TASK: man
LANG: C++
SOL: Luck
*/
//Rumen Hristov Hristov

#include <stdio.h>
#include <algorithm>
#include <set>
#include <vector>
using namespace std;

#define MAX 16384

struct point
{
     int x,y; 
     int cnt;
     int g;
};

int n,m;
set<int> a[ MAX ];
point e[5002];
vector <point> used;
set <int> used2;
int groups;

void read()
{
    int i;
    
    scanf ("%d",&m);
    
    n = 0;
    
    for (i=1;i<=m;i++)
    {
        scanf ("%d%d",&e[i].x,&e[i].y);
        
        if ( e[i].x > n ) n = e[i].x;
        if ( e[i].y > n ) n = e[i].y;
    }
}

int solve()
{
    int i,j;
    int x,y;
    int ans;
    
    ans = 0;
    
    for (i=1;i<=m;i++)
    {
        x = e[i].x;
        y = e[i].y;
        
        for (j=0;j<=n;j++)
        {
            if ( a[j].count(x) && a[j].count(y) )
            {
                break;
            }
        }
        
        if ( j == n+1 )
        {
            a[x].insert(y);
            a[y].insert(x);
            ans++;
        }
    }
    
    return ans;
}

void mke2(int q,int w)
{
    int i;
    int sz = used.size(); 
    point t;
    
    for (i=0;i<sz;i++)
    {
        if ( used[i].x == q && used[i].y == w )
        {
            break;
        }
    }
    
    if ( i == sz )
    {
        t.x = q;
        t.y = w;
        t.cnt = 1;
        t.g = groups;
                
        used.push_back(t);
    }
    else
    {
        used[i].cnt++;
    }
}

void mke (int q,int w,int r)
{
    if ( q > w ) swap (q,w);
    if ( w > r ) swap (w,r);
    if ( q > w ) swap (q,w);
    
    int sz,i;
    point t;
    int pom = 0;
    int gl = -1;
    int l1 = 0,l2 = 0,l3 = 0;
    
    sz = used.size();
            
    for (i=0;i<sz;i++)
    {
        if ( used[i].x == q && used[i].y == w  )
        {
            pom++;
            l1 = 1;
        }
        
        if ( used[i].x == q && used[i].y == r )
        {
            pom++;
            l2 = 1;
        }
        
        if ( used[i].x == w && used[i].y == r )
        {
            pom++;
            l3 = 1;
        }
    }
    
  //  printf ("%d %d %d \n",q,w,r);
    
    if ( pom == 3 )
    {
        return ;
    }
    
  //  printf ("b\n");
    
  //  if (!l1)
    mke2(q,w);
//    if (!l2)
    mke2(q,r);
 //   if (!l3)
    mke2(w,r);
    groups++;
}

int solve2()
{
    int i,j,k;
    
    int q,w;
    int sz;
    point t;
    groups = 1;

    for (i=1;i<=m;i++)
    {
        a[ e[i].x ] . insert ( e[i].y );
        a[ e[i].y ] . insert ( e[i].x );        
    }
    
    for (k=1;k<=m;k++)
    {
        q = e[k].x;
        w = e[k].y;
        
        if ( w > q ) swap (w,q);
        
        for (j=0;j<=n;j++)
        {
            if ( a[j].count(q) && a[j].count(w) )
            break;
        }
        
        if ( j != n + 1 )
        {
            mke (q,w,j);
        }
    }
    
    int ans = m;
    
    sz = used.size();
    
    for (i=0;i<sz;i++)
    {
    //    printf ("%d %d %d %d\n",used[i].x,used[i].y,used[i].cnt,used[i].g);
        
        if ( used[i].cnt == 1 )
        {
            if ( used2.count( used[i].g ) == 0 )
            {
                used2.insert( used[i].g );
                ans--;
            }
        }
    }
    
    return ans;
}

int main()
{
    read();
    
    if ( m >= 1500 )
    printf ("%d\n",solve());
    else
    printf ( "%d\n",min(solve2(),solve()) );
    
    return 0;
}
