Problem:
Score : 300 points

Problem Statement

Takahashi participated in a contest on AtCoder.

The contest had N problems.

Takahashi made M submissions during the contest.

The i-th submission was made for the p_i-th problem and received the verdict S_i (AC or WA).

The number of Takahashi's correct answers is the number of problems on which he received an AC once or more.

The number of Takahashi's penalties is the sum of the following count for the problems on which he received an AC once or more: the number of WAs received before receiving an AC for the first time on that problem.

Find the numbers of Takahashi's correct answers and penalties.

Constraints

N, M, and p_i are integers.

1 \leq N \leq 10^5

0 \leq M \leq 10^5

1 \leq p_i \leq N

S_i is AC or WA.

Input

Input is given from Standard Input in the following format:

N M
p_1 S_1
:
p_M S_M

Output

Print the number of Takahashi's correct answers and the number of Takahashi's penalties.

Sample Input 1

2 5
1 WA
1 AC
2 WA
2 AC
2 WA

Sample Output 1

2 2

In his second submission, he received an AC on the first problem for the first time. Before this, he received one WA on this problem.

In his fourth submission, he received an AC on the second problem for the first time. Before this, he received one WA on this problem.

Thus, he has two correct answers and two penalties.

Sample Input 2

100000 3
7777 AC
7777 AC
7777 AC

Sample Output 2

1 0

Note that it is pointless to get an AC more than once on the same problem.

Sample Input 3

6 0

Sample Output 3

0 0

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Numerics;
using static System.Math;
using static System.Array;
using static AtCoder.IO_ShortCut;
using static AtCoder.Tool;
using static AtCoder.ModInt;
namespace AtCoder
{
    class AC
    {
        const int MOD = 1000000007;
        //const int MOD = 998244353;
        const int INF = int.MaxValue / 2;
        const long SINF = long.MaxValue / 2;
        const double EPS = 1e-8;
        static readonly int[] dI = { 0, 1, 0, -1, 1, -1, -1, 1 };
        static readonly int[] dJ = { 1, 0, -1, 0, 1, 1, -1, -1 };
        //static List<List<int>> G = new List<List<int>>();
        static List<List<Edge>> G = new List<List<Edge>>();
        //static List<Edge> E = new List<Edge>();
        static void Main(string[] args)
        {
            var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };Console.SetOut(sw);
            Solve();
            Console.Out.Flush();
        }
        static void Solve()
        {
            int N, M;
            Input(out N, out M);
            var wa = new long[N];
            var isAC = new bool[N];
            Initialize(ref isAC, false);
            for(var i = 0; i < M; i++)
            {
                int p;string s;
                Input(out p, out s);
                if (s == "AC")
                {
                    isAC[--p] = true;
                }
                else
                {
                    if (!isAC[--p])
                    {
                        wa[p]++;
                    }
                }
            }
            long[] ans = { 0, 0 };
            for(var i = 0; i < N; i++)
            {
                if (isAC[i])
                {
                    ans[0]++;
                    ans[1] += wa[i];
                }
            }
            OutL($"{ans[0]} {ans[1]}");
        }
        public struct Edge
        {
            public int from;

            public int to;
            public long dist;
            
            public Edge(int t, long c)
            {
                from = -1;
                to = t;
                dist = c;
            }
            public Edge(int f, int t, long c)
            {
                from = f;
                to = t;
                dist = c;
            }
        }
    }
    
    struct ModInt
    {
        public long value;
        private const int MOD = 1000000007;
        //private const int MOD = 998244353;

        public ModInt(long value) { this.value = value; }
        public static implicit operator ModInt(long a)
        {
            var ret = a % MOD;
            return new ModInt(ret < 0 ? (ret + MOD) : ret);
        }
        public static ModInt operator +(ModInt a, ModInt b) => (a.value + b.value);
        public static ModInt operator -(ModInt a, ModInt b) => (a.value - b.value);
        public static ModInt operator *(ModInt a, ModInt b) => (a.value * b.value);
        public static ModInt operator /(ModInt a, ModInt b) => a * Modpow(b, MOD - 2);
        public static ModInt operator <<(ModInt a, int n) => (a.value << n);
        public static ModInt operator >>(ModInt a, int n) => (a.value >> n);
        public static ModInt operator ++(ModInt a) => a.value + 1;
        public static ModInt operator --(ModInt a) => a.value - 1;
        public static ModInt Modpow(ModInt a, long n)
        {
            var k = a;
            ModInt ret = 1;
            while (n > 0)
            {
                if ((n & 1) != 0) ret *= k;
                k *= k;
                n >>= 1;
            }
            return ret;
        }
        private static readonly List<long> Factorials = new List<long>() { 1 };
        public static ModInt Fac(long n)
        {
            for (var i = Factorials.Count(); i <= n; i++)
            {
                Factorials.Add((Factorials[i - 1] * i) % MOD);
            }
            return Factorials[(int)n];
        }
        public static ModInt nCr(long n, long r)
        {
            return n < r ? 0 : Fac(n) / (Fac(r) * Fac(n - r));
        }
        public static explicit operator int(ModInt a) => (int)a.value;
    }
    static class IO_ShortCut
    {
        public static string[] _ReadSplit => Console.ReadLine().Split();
        public static int[] _ReadSplitInt => ConvertAll(Console.ReadLine().Split(), int.Parse);
        public static long[] _ReadSplitLong => ConvertAll(Console.ReadLine().Split(), long.Parse);
        public static double[] _ReadSplit_Double => ConvertAll(Console.ReadLine().Split(), double.Parse);
        public static string Str => Console.ReadLine();
        public static int Int => int.Parse(Console.ReadLine());
        public static long Long => long.Parse(Console.ReadLine());
        public static double Double => double.Parse(Console.ReadLine());
        public static T Conv<T>(string input)
        {
            if (typeof(T).Equals(typeof(ModInt)))
            {
                return (T)(dynamic)(long.Parse(input));
            }
            return (T)Convert.ChangeType(input, typeof(T));
        }
        public static void Input<T>(out T a) => a = Conv<T>(Console.ReadLine());
        public static void Input<T, U>(out T a, out U b)
        { var q = _ReadSplit;a = Conv<T>(q[0]);b = Conv<U>(q[1]); }
        public static void Input<T, U, V>(out T a, out U b, out V c)
        { var q = _ReadSplit;a = Conv<T>(q[0]);b = Conv<U>(q[1]);c = Conv<V>(q[2]); }
        public static void Input<T, U, V, W>(out T a, out U b, out V c, out W d)
        { var q = _ReadSplit; a = Conv<T>(q[0]); b = Conv<U>(q[1]); c = Conv<V>(q[2]);d = Conv<W>(q[3]); }

        public static void OutL(object s) => Console.WriteLine(s);
        public static void Out_Sep<T>(IEnumerable<T> s) => Console.WriteLine(string.Join(" ", s));
        public static void Out_Sep<T>(IEnumerable<T> s, string sep) => Console.WriteLine(string.Join($"{sep}", s));
        public static void Out_Sep(params object[] s) => Console.WriteLine(string.Join(" ", s));
        public static void Out_One(object s) => Console.Write($"{s} ");
        public static void Out_One(object s, string sep) => Console.Write($"{s}{sep}");
        public static void Endl() => Console.WriteLine();
    }
    public static class Tool
    {
        static public void Initialize<T>(ref T[] array, T initialvalue)
        {
            array = ConvertAll(array, x => initialvalue);
        }
        static public void Swap<T>(ref T a, ref T b)
        {
            T keep = a;
            a = b;
            b = keep;
        }
        static public void Display<T>(T[,] array2d, int n, int m)
        {
            for (var i = 0; i < n; i++)
            {
                for (var j = 0; j < m; j++)
                {
                    Console.Write($"{array2d[i, j]} ");
                }
                Console.WriteLine();
            }
        }
        static public long LPow(int a, int b) => (long)Pow(a, b);
        static public bool Bit(long x, int dig) => ((1L << dig) & x) != 0;
        static public int Sig(long a) => a == 0 ? 0 : (int)(a / Abs(a));
    }
}