#include <bits/stdc++.h>
// #include "matrix.h"

using namespace std;

typedef vector<char> vc;
typedef long long ll;
typedef tuple<int, int, ll, ll> edge;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;

void plb() {
  cout << "-------------------------------------------\n";
}
void printVb(vector<bool> v) {
    for(const auto &n : v) {
        cout << n << ", ";
    }
    cout << "\n";
}
void printVc(vector<char> v) {
    for(const auto &n : v) {
        cout << n << ", ";
    }
    cout << "\n";
}
void printVi(vector<int> v) {
    for(const auto &n : v) {
        cout << n << ", ";
    }
    cout << "\n";
}
void printVl(vector<long> v) {
    for(const auto &n : v) {
        cout << n << ", ";
    }
    cout << "\n";
}
void printVii(vector<pair<int, int>> v) {
    for(const auto &p : v) {
        cout << "(" << p.first << ", " << p.second << "), ";
    }
    cout << "\n";
}
// void printMap(unordered_map<int, short> map) {
//   for(auto const& [key, val] : map) {
//     printf("(%d, %d), ", key, val);
//   }
//   cout << "\n";
// }
// void printPQ(priority_queue<int, vector<int>, greater<int> > pq) {
//   while(!pq.empty()) {
//     cout << pq.top() << ", ";
//     pq.pop();
//   }
//   cout << "\n";
// }
// int min3(int a, int b, int c) {
//   return min(a, min(b, c));
// }
// int max3(int a, int b, int c) {
//   return max(a, max(b, c));
// }

// void printii(int a, int b) {
//   cout << "a = " << a << ", b = " << b << "\n";
// }
// void printAdjList(vector<vector<int>> adjList) {
//   for(int i = 0; i < adjList.size(); ++i) {
//     printVi(adjList[i]);
//   }
// }

// vector<int> o1{-1, 1};
// vector<int> o2{-1, 1};
// vector<ii> o3{{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
// vector<ii> o4{{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}};

// // void ff(Matrix<int> &m, int i, int j, int oldValue, int newValue) {
// //   if (i < 0 || i >= m.rows() || j < 0 || j >= m.cols()) return; // invalid  
// //   if (m[i][j] != oldValue) return; // cant walk here
  
// //   m[i][j] = newValue; // visit
// //   for(auto p1 : o3) {
// //     ff(m, i + p1.first, j + p1.second, oldValue, newValue);
// //   }
// //   return;
// // }

// void bfs(vector<vector<int>> adjList) {
//   vector<bool> visited; visited.assign(adjList.size(), false);
//   vector<int> dist; dist.assign(adjList.size(), -1);
//   deque<int> dq;

//   dq.push_back(0); visited[0] = true; dist[0] = 0;
//   while(!dq.empty()) {
//     int cur = dq.front(); dq.pop_front();
    
//     for(int nbr : adjList[cur]) {
//       if (!visited[nbr]) {
//         dist[nbr] = dist[cur] + 1;
//         visited[nbr] = true;
//         dq.push_back(nbr);
//       }
//     }
//   }
// }

// // An AVL tree node 
// struct node 
// { 
//     int key; 
//     struct node *left; 
//     struct node *right; 
//     int height; 
//     int size; // size of the tree rooted with this node 
// }; 
  
// // A utility function to get maximum of two integers 
// int max(int a, int b); 
  
// // A utility function to get height of the tree rooted with N 
// int height(struct node *N) 
// { 
//     if (N == NULL) 
//         return 0; 
//     return N->height; 
// } 
  
// // A utility function to size of the tree of rooted with N 
// int size(struct node *N) 
// { 
//     if (N == NULL) 
//         return 0; 
//     return N->size; 
// } 
  
// // A utility function to get maximum of two integers 
// int max(int a, int b) 
// { 
//     return (a > b)? a : b; 
// }


int main() {
  int N, M; cin >> N >> M;
  vi arr(N, 0);
  vector<bool> accepted(N, false);
  for(int i = 0; i < M; ++i) {
    int id; cin >> id;
    --id;
    string s; cin >> s;
    if (s == "WA" && !accepted[id]) {
      ++arr[id];
    } else {
      accepted[id] = true;
    }
  }
  int totalAC = 0;
  int totalP = 0;
  for(int i = 0; i < N; ++i) {
    if (accepted[i]) {
      ++totalAC;
      totalP += arr[i];
    }
  }
  printf("%d %d\n", totalAC, totalP);
}

Measured memory_bytes: 640