#include <bits/stdc++.h>
using namespace std;
template <class T>
bool ckmin(T& a, const T& b) {
  return a > b ? a = b, true : false;
}
template <class T>
bool ckmax(T& a, const T& b) {
  return a < b ? a = b, true : false;
}
template <typename T>
struct IsC {
  template <typename C>
  static char test(typename C::const_iterator*);
  template <typename C>
  static int test(...);
  static const bool value = sizeof(test<T>(0)) == sizeof(char);
};
template <>
struct IsC<string> {
  static const bool value = false;
};
template <typename C>
typename enable_if<IsC<C>::value, ostream&>::type operator<<(ostream&,
                                                             const C&);
template <typename T1, typename T2>
ostream& operator<<(ostream&, const pair<T1, T2>&);
template <typename... T>
using TS = tuple_size<tuple<T...>>;
template <size_t idx, typename... T>
typename enable_if<TS<T...>::value == idx + 1, ostream&>::type operator<<(
    ostream& o, const tuple<T...>& t) {
  return o << ", " << get<idx>(t) << ')';
}
template <size_t idx, typename... T>
typename enable_if<0 < idx && idx + 1 < TS<T...>::value, ostream&>::type
operator<<(ostream& o, const tuple<T...>& t) {
  return operator<<<idx + 1>(o << ", " << get<idx>(t), t);
}
template <size_t idx = 0, typename... T>
typename enable_if<1 < TS<T...>::value && !idx, ostream&>::type operator<<(
    ostream& o, const tuple<T...>& t) {
  return operator<<<idx + 1>(o << '(' << get<idx>(t), t);
}
template <typename T>
ostream& operator<<(ostream& o, const tuple<T>& t) {
  return o << get<0>(t);
}
template <typename T1, typename T2>
ostream& operator<<(ostream& o, const pair<T1, T2>& p) {
  return o << make_tuple(p.first, p.second);
}
template <typename C>
typename enable_if<IsC<C>::value, ostream&>::type operator<<(ostream& o,
                                                             const C& c) {
  o << '[';
  for (auto it = c.cbegin(); it != c.cend(); ++it)
    o << *it << (next(it) != c.cend() ? ", " : "");
  return o << ']';
}
template <typename T>
void tprint(vector<vector<T>>& v, size_t width = 0, ostream& o = cerr) {
  if (!0) return;
  for (const auto& vv : v) {
    for (const auto& i : vv) o << setw(width) << i;
    o << '\n';
  }
}
void solve() {
  string s;
  cin >> s;
  int n = (int)(s).size();
  long long res = 1e18;
  long long cntLow = 0;
  long long cntHigh = 0;
  for (auto i = (0); (i) < ((n)); ++(i)) {
    cntLow += !!islower(s[i]);
    cntHigh += !!isupper(s[i]);
  }
  if (0)
    std::cerr << " ["
              << "cntLow, cntHigh"
                 ": "
              << make_tuple(cntLow, cntHigh) << "] " << '\n';
  long long lCnt = 0, hCnt = 0;
  ckmin(res, lCnt + (cntHigh - hCnt));
  for (char c : s) {
    if (islower(c))
      lCnt++;
    else
      hCnt++;
    ckmin(res, lCnt + (cntHigh - hCnt));
  }
  ckmin(res, lCnt + (cntHigh - hCnt));
  cout << res << '\n';
}
int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  int tc = 1;
  for (auto i = (1); (i) < (tc + 1); ++(i)) {
    solve();
  }
}
