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++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>

using namespace std;

#define REP(i, N) for (int i = 0; i < (int)N; i++)
#define FOR(i, a, b) for (int i = a; i < (int)b; i++)
#define ALL(x) (x).begin(), (x).end()
#define INF (1 << 30)
#define LLINF (1LL << 62)
#define DEBUG(...) debug(__LINE__, ":" __VA_ARGS__)

constexpr int MOD = 1000000007;
using ll = long long;
using Pii = pair<int, int>;
using Pll = pair<ll, ll>;

string to_string(string s) { return s; }
template <class T>
string to_string(unordered_set<T> s);
template <class T>
string to_string(set<T> s);
template <class S, class T>
string to_string(unordered_map<S, T> m);
template <class S, class T>
string to_string(map<S, T> m);
template <class T>
string to_string(vector<T> v);

template <class S, class T>
string to_string(pair<S, T> p) {
  return "{" + to_string(p.first) + "," + to_string(p.second) + "}";
}
template <class S>
string to_string(unordered_set<S> s) {
  if (s.empty()) return "{}";
  string ret = "{";
  for (auto itr = s.begin(); itr != s.end(); ++itr)
    ret += to_string(*itr) + ",";
  ret += to_string(*s.end()) + "}";
  return ret;
}
template <class S>
string to_string(set<S> s) {
  if (s.empty()) return "{}";
  string ret = "{";
  for (auto itr = s.begin(); itr != s.end(); ++itr)
    ret += to_string(*itr) + ",";
  ret += to_string(*s.end()) + "}";
  return ret;
}
template <class S, class T>
string to_string(unordered_map<S, T> m) {
  if (m.empty()) return "{}";
  string ret = "{";
  for (auto itr = m.begin(); itr != m.end(); ++itr)
    ret += to_string(*itr) + ",";
  ret += to_string(*m.end()) + "}";
  return ret;
}
template <class S, class T>
string to_string(map<S, T> m) {
  if (m.empty()) return "{}";
  string ret = "{";
  for (auto itr = m.begin(); itr != m.end(); ++itr)
    ret += to_string(*itr) + ",";
  ret += to_string(*m.end()) + "}";
  return ret;
}
template <class T>
string to_string(vector<T> v) {
  if (v.empty()) return "{}";
  string ret = "{";
  for (auto itr = v.begin(); itr != v.end(); ++itr)
    ret += to_string(*itr) + ",";
  ret += to_string(*v.end()) + "}";
  return ret;
}

void debug() { cerr << endl; }
template <class Head, class... Tail>
void debug(Head head, Tail... tail) {
  cerr << to_string(head) << " ";
  debug(tail...);
}
void print() { cout << endl; }
template <class Head, class... Tail>
void print(Head head, Tail... tail) {
  cout << to_string(head) << " ";
  print(tail...);
}

struct IO {
#ifdef _WIN32
  inline char getchar_unlocked() { return getchar(); }
  inline void putchar_unlocked(char c) { putchar(c); }
#endif
  string separator = " ";
  template <class T>
  inline void read(T &x) {
    char c;
    do {
      c = getchar_unlocked();
    } while (c != '-' && c < '0' && '9' < c);
    bool minus = 0;
    if (c == '-') {
      minus = 1;
      c = getchar_unlocked();
    }
    x = 0;
    while ('0' <= c && c <= '9') {
      x *= 10;
      x += c - '0';
      c = getchar_unlocked();
    }
    if (minus) x = -x;
  }
  inline void read(string &x) {
    char c;
    x.clear();
    do {
      c = getchar_unlocked();
      x += c;
    } while (c != ' ' && c != '\n');
  }
  template <class T>
  inline void read(vector<T> &v) {
    for (auto &x : v) read(x);
  }
  template <class Head, class... Tail>
  inline void read(Head &head, Tail &... tail) {
    read(head);
    read(tail...);
  }
  template <class T>
  inline void write(T &x) {
    char buf[32];
    int p = 0;
    T t = x;
    if (t < 0) {
      x = -t;
      putchar_unlocked('-');
    }
    if (t == 0) putchar_unlocked('0');
    while (t > 0) {
      buf[p++] = (t % 10) + '0';
      t /= 10;
    }
    while (p) {
      putchar_unlocked(buf[--p]);
    }
  }
  inline void write(string &x) {
    for (char c : x) putchar_unlocked(c);
  }
  template <class T>
  inline void write(vector<T> &v) {
    for (auto itr = v.begin(); itr != v.begin(); ++itr) {
      write(separator);
      write(*itr);
    }
    write(*v.end());
  }
  template <class Head, class... Tail>
  inline void write(Head &head, Tail &... tail) {
    write(head);
    write(separator);
    write(tail...);
  }
  void set_separator(string s) { separator = s; }
} io;

template <int MOD = 1000000007>
struct Math {
  vector<long long> fact, factinv, inv;
  Math(int n = 100000) {
    fact.resize(n + 1);
    factinv.resize(n + 1);
    inv.resize(n + 1);
    fact[0] = fact[1] = 1;
    factinv[0] = factinv[1] = 1;
    inv[1] = 1;
    for (int i = 2; i <= n; ++i) {
      fact[i] = fact[i - 1] * i % MOD;
      inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
      factinv[i] = factinv[i - 1] * inv[i] % MOD;
    }
  }
  long long C(int n, int r) {
    if (n < r || n < 0 || r < 0) {
      return 0;
    } else {
      return fact[n] * (factinv[r] * factinv[n - r] % MOD) % MOD;
    }
  }
  long long P(int n, int r) {
    if (n < r || n < 0 || r < 0) {
      return 0;
    } else {
      return fact[n] * factinv[n - r] % MOD;
    }
  }
  long long H(int n, int r) { return C(n + r - 1, r); }
};

struct Prime {
  int n;
  vector<int> table;
  vector<int> primes;
  Prime(int _n = 100000) {
    n = _n + 1;
    table.resize(n, -1);
    table[0] = 0;
    table[1] = 1;
    for (int i = 2; i * i < n; ++i) {
      if (table[i] == -1) {
        for (int j = i * i; j < n; j += i) {
          table[j] = i;
        }
      }
    }
  }
  void enumerate_primes() {
    primes.clear();
    for (int i = 2; i < n; ++i) {
      if (table[i] == -1) primes.push_back(i);
    }
  }
  vector<pair<int, int>> prime_factor(int x) {
    map<int, int> mp;
    while (table[x] != -1) {
      mp[table[x]]++;
      x /= table[x];
    }
    if (x > 1) mp[x]++;
    vector<pair<int, int>> ret;
    for (auto p : mp) ret.push_back(p);
    return ret;
  }
};

int main() {
  int N, M;
  cin >> N >> M;
  vector<int> cnt(N);
  int correct = 0, pena = 0;
  REP(i, M) {
    int p;
    string S;
    cin >> p >> S;
    if (S == "WA") {
      if (cnt[p - 1] != -1) cnt[p - 1]++;
    } else {
      if (cnt[p - 1] != -1) {
        pena += cnt[p - 1];
        cnt[p - 1] = -1;
        correct++;
      }
    }
  }
  cout << correct << " " << pena;
  cout << endl;
  return 0;
}