using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace A
{
    partial class Program
    {
        public class Cdn
        {
            public int Idx { get; set; }
            public long X { get; set; }
            public long Y { get; set; }
        }

        long n;
        List<Cdn> cs = new List<Cdn>();
        HashSet<long> xCheckeds = new HashSet<long>();
        HashSet<long> yCheckeds = new HashSet<long>();
        Dictionary<long, List<Cdn>> xGroups;
        Dictionary<long, List<Cdn>> yGroups;
        public IEnumerable<string> Solve()
        {
            n = Num;
            for (int i = 0; i < n; i++)
            {
                cs.Add(new Cdn() { Idx = i, X = Num, Y = Num });
            }

            xGroups = cs.GroupBy(x => x.X).ToDictionary(x => x.Key, x => x.ToList());
            yGroups = cs.GroupBy(x => x.Y).ToDictionary(x => x.Key, x => x.ToList());

            long total = 0;

            for (int i = 0; i < n; i++)
            {
                var x = cs[i].X;
                var y = cs[i].Y;

                if (xCheckeds.Contains(x) || yCheckeds.Contains(y))
                    continue;

                var xs = new HashSet<long>();
                var ys = new HashSet<long>();
                Check(i, ref xs, ref ys);
                total += (long)xs.Count * (long)ys.Count;
            }

            var res = total - n;
            yield return res.ToString();
        }

        void Check(int i, ref HashSet<long> xs, ref HashSet<long> ys)
        {
            HashSet<long> axs = new HashSet<long>();
            HashSet<long> ays = new HashSet<long>();
            HashSet<long> bxs = new HashSet<long>();
            HashSet<long> bys = new HashSet<long>();
            axs.Add(cs[i].X);
            ays.Add(cs[i].Y);
            xs.Add(cs[i].X);
            ys.Add(cs[i].Y);

            while (axs.Count > 0 || ays.Count > 0)
            {
                bxs.Clear();
                bys.Clear();

                var nys = axs.SelectMany(x => xGroups[x].Select(xt => xt.Y)).Where(x => !yCheckeds.Contains(x));
                var nxs = ays.SelectMany(x => yGroups[x].Select(xt => xt.X)).Where(x => !xCheckeds.Contains(x));

                foreach (var y in nys)
                {
                    bys.Add(y);
                    yCheckeds.Add(y);
                    if (!ys.Contains(y))
                        ys.Add(y);
                }

                foreach (var x in nxs)
                {
                    bxs.Add(x);
                    xCheckeds.Add(x);
                    if (!xs.Contains(x))
                        xs.Add(x);
                }

                var temp = axs;
                axs = bxs;
                bxs = temp;
                temp = ays;
                ays = bys;
                bys = temp;
            }
        }
    }

    class StartingPoint
    {
        static void Main(string[] args)
        {
            if (args?.Any() == true)
            {
                var assembly = Assembly.GetExecutingAssembly();
                var resourceName = "AtCoder.Resources.In.txt";
                var stream = assembly.GetManifestResourceStream(resourceName);
                var streamReader = new StreamReader(stream, Encoding.UTF8);
                var str = streamReader.ReadToEnd();
                var textReader = new StringReader(str);
                Console.SetIn(textReader);
            }

            try
            {
                foreach (var s in new Program().Solve())
                {
                    Console.WriteLine(s);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                if (args?.Any() != true)
                    throw e;
            }

            if (args?.Any() == true)
                Console.ReadLine();
        }
    }

    partial class Program
    {
        long[] Nums(long count) => Enumerable.Range(0, (int)count).Select(_ => Num).ToArray();
        long Num => long.Parse(Str);
        double NumD => (double)Num;

        StringBuilder sb = new StringBuilder();

        string Str => GetStr();
        string GetStr()
        {
            sb.Clear();

            int r = 0;
            bool? b = null;
            do
            {
                r = Console.Read();
                b = IsBreak(r);
            } while (b == true);

            if (b == null)
                throw new Exception("input error: unexpected end of stream");

            do
            {
                sb.Append((char)r);
                r = Console.Read();
                b = IsBreak(r);
            } while (b == false);

            return sb.ToString();
        }

        bool? IsBreak(int c)
        {
            switch (c)
            {
                case -1:
                    return null;
                case (int)' ':
                case (int)'\n':
                case (int)'\r':
                    return true;
                default:
                    return false;
            }
        }
    }
}

Measured memory_bytes: 62456