using System;
using System.Text;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using static System.Console;
using static System.Math;

namespace AtCoder
{
    class Program
    {
        static void Main(string[] args)
        {
            new Program().Solve(new ConsoleInput(Console.In, ' '));
#if DEBUG
            ReadLine();
#endif
        }

        struct Point
        {
            public int x;
            public int y;

            public Point(int x, int y)
            {
                this.x = x;
                this.y = y;
            }
        }

        void Solve(ConsoleInput cin)
        {
            int h = cin.ReadInt;
            int w = cin.ReadInt;

            bool[,] field = new bool[h, w];
            List<Point> blacks = new List<Point>();

            for (int i = 0; i < h; i++)
            {
                string str = cin.Read;

                for (int j = 0; j < w; j++)
                {
                    field[i, j] = str[j] == '#';
                    if (field[i, j])
                    {
                        blacks.Add(new Point(i, j));
                    }
                }
            }

            bool[,] gone = new bool[h, w];
            long result = 0;

            for (int i = 0; i < blacks.Count(); i++)
            {
                Point b = blacks[i];

                if (gone[b.x, b.y])
                {
                    continue;
                }

                long level = 1;
                long whiteCount = 0;

                Queue<Point> queue = new Queue<Point>();
                queue.Enqueue(b);
                gone[b.x, b.y] = true;

                while (queue.Count() != 0)
                {
                    Point now = queue.Dequeue();

                    for (int j = 0; j < 4; j++)
                    {
                        int nextX = 0;
                        int nextY = 0;

                        switch (j)
                        {
                            case 0:
                                nextX = now.x - 1;
                                nextY = now.y;
                                break;
                            case 1:
                                nextX = now.x;
                                nextY = now.y - 1;
                                break;
                            case 2:
                                nextX = now.x + 1;
                                nextY = now.y;
                                break;
                            case 3:
                                nextX = now.x;
                                nextY = now.y + 1;
                                break;
                        }


                        if (nextX >= 0
                            && nextX < h
                            && nextY >= 0
                            && nextY < w
                            && field[nextX, nextY] != field[now.x, now.y]
                            && !gone[nextX, nextY])
                        {
                            gone[nextX, nextY] = true;

                            if (field[nextX, nextY])
                            {
                                level++;
                            }
                            else
                            {
                                whiteCount++;
                            }

                            queue.Enqueue(new Point(nextX, nextY));
                        }
                    }
                }

                result += level * whiteCount;
            }

            Console.WriteLine(result);
        }

        class ConsoleInput
        {
            private readonly System.IO.TextReader _stream;
            private char _separator = ' ';
            private Queue<string> inputStream;

            public ConsoleInput(System.IO.TextReader stream, char separator = ' ')
            {
                this._separator = separator;
                this._stream = stream;
                inputStream = new Queue<string>();
            }

            public string Read
            {
                get
                {
                    if (inputStream.Count != 0) return inputStream.Dequeue();
                    string[] tmp = _stream.ReadLine().Split(_separator);
                    for (int i = 0; i < tmp.Length; ++i)
                        inputStream.Enqueue(tmp[i]);
                    return inputStream.Dequeue();
                }
            }

            public string ReadLine { get { return _stream.ReadLine(); } }
            public int ReadInt { get { return int.Parse(Read); } }
            public long ReadLong { get { return long.Parse(Read); } }
            public double ReadDouble { get { return double.Parse(Read); } }
            public string[] ReadStrArray(long N) { var ret = new string[N]; for (long i = 0; i < N; ++i) ret[i] = Read; return ret; }
            public int[] ReadIntArray(long N) { var ret = new int[N]; for (long i = 0; i < N; ++i) ret[i] = ReadInt; return ret; }
            public long[] ReadLongArray(long N) { var ret = new long[N]; for (long i = 0; i < N; ++i) ret[i] = ReadLong; return ret; }
        }
    }
}


Measured memory_bytes: 17632