#include <bits/stdc++.h>
using namespace std;
template <class T1>
void debug(T1 e) {
  cout << e << endl;
}
template <class T1, class T2>
void debug(T1 e1, T2 e2) {
  cout << e1 << "\t" << e2 << endl;
}
template <class T1, class T2, class T3>
void debug(T1 e1, T2 e2, T3 e3) {
  cout << e1 << "\t" << e2 << "\t" << e3 << endl;
}
template <typename T>
std::string to_string(T const& value) {
  stringstream sstr;
  sstr << value;
  return sstr.str();
}
template <class T>
T gcd(T a, T b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}
template <class T>
T lcm(T a, T b) {
  return (a * b) / gcd(a, b);
}
template <class T>
T power(T a, T b) {
  if (b == 0) return 1;
  T x = a;
  for (T i = 2; i <= b; i++) a = a * x;
  return a;
}
template <class T>
T BigMod(T a, T b, T c) {
  if (a == 0) return 0;
  if (b == 0) return 1;
  if (b % 2 == 0) {
    T x = BigMod(a, b / 2, c) % c;
    return (x * x) % c;
  } else
    return ((a % c) * BigMod(a, b - 1, c) % c) % c;
}
bool isVowel(char ch) {
  ch = tolower(ch);
  if (ch == 'a' | ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') return true;
  return false;
}
bool vis[200000 + 7];
char ck(char c) {
  if (isupper(c)) return tolower(c);
  return toupper(c);
}
int main() {
  string s1, s2;
  int i, cnt1, cnt2;
  while (cin >> s1 >> s2) {
    int l = s1.size();
    cnt1 = cnt2 = 0;
    map<char, int> mp, mp2;
    for (i = 0; i < l; i++) {
      mp[s1[i]]++;
      mp2[s1[i]]++;
    }
    int l2 = s2.size();
    for (i = 0; i <= l2; i++) vis[i] = 0;
    for (i = 0; i < l2; i++) {
      if (mp[s2[i]] > 0) {
        cnt1++;
        mp[s2[i]]--;
        vis[i] = true;
      }
    }
    for (i = 0; i < l2; i++) {
      if (vis[i] == false && (mp[ck(s2[i])] > 0)) {
        cnt2++;
        mp[ck(s2[i])]--;
      }
    }
    cout << cnt1 << " " << cnt2 << endl;
    ;
  }
  return 0;
}
