OI XXI - bar

// https://szkopul.edu.pl/problemset/problem/7xybSzndMlQ8nWLZZsMTcM9C/site/?key=statement
// Bar sałatkowy

#include <algorithm>
#include <iostream>
#include <stack>
#include <string>
#include <vector>

// Use standard int, it's sufficient and faster
using std::max;
using std::min;
using std::vector;

const int SIZ = 1000000 + 5;

// Segment Tree for Range Maximum Query
int d[4 * SIZ];
void update(int v, int tl, int tr, int pos, int new_val) {
    if (tl == tr) {
        d[v] = new_val;
    } else {
        int tm = (tl + tr) / 2;
        if (pos <= tm) {
            update(2 * v, tl, tm, pos, new_val);
        } else {
            update(2 * v + 1, tm + 1, tr, pos, new_val);
        }
        d[v] = max(d[2 * v], d[2 * v + 1]);
    }
}

int query(int v, int tl, int tr, int l, int r) {
    if (l > r) return 0;
    if (l == tl && r == tr) return d[v];
    int tm = (tl + tr) / 2;
    return max(query(2 * v, tl, tm, l, min(r, tm)), query(2 * v + 1, tm + 1, tr, max(l, tm + 1), r));
}

void solve() {
    std::ios_base::sync_with_stdio(0);
    std::cin.tie(0);

    int n;
    std::cin >> n;
    std::string s;
    std::cin >> s;

    vector<int> a(n + 1);
    bool has_orange = false;
    for (int i = 0; i < n; ++i) {
        a[i + 1] = (s[i] == 'p' ? 1 : -1);
        if (s[i] == 'p') has_orange = true;
    }
    if (!has_orange) {
        std::cout << "0\n";
        return;
    }

    vector<long long> pref(n + 2, 0);
    for (int i = 1; i <= n; ++i) {
        pref[i] = pref[i - 1] + a[i];
    }
    vector<long long> suff(n + 2, 0);
    for (int i = n; i >= 1; --i) {
        suff[i] = suff[i + 1] + a[i];
    }

    vector<int> next_smaller_pref(n + 1);
    std::stack<int> st_pref;
    for (int i = n; i >= 0; --i) {
        while (!st_pref.empty() && pref[st_pref.top()] >= pref[i]) {
            st_pref.pop();
        }
        next_smaller_pref[i] = st_pref.empty() ? n + 1 : st_pref.top();
        st_pref.push(i);
    }
    vector<int> R(n + 1);
    for (int i = 1; i <= n; ++i) {
        R[i] = next_smaller_pref[i - 1] - 1;
    }

    vector<int> prev_smaller_suff(n + 2);
    std::stack<int> st_suff;
    for (int i = 1; i <= n + 1; ++i) {
        while (!st_suff.empty() && suff[st_suff.top()] >= suff[i]) {
            st_suff.pop();
        }
        prev_smaller_suff[i] = st_suff.empty() ? 0 : st_suff.top();
        st_suff.push(i);
    }
    vector<int> L(n + 1);
    for (int i = 1; i <= n; ++i) {
        L[i] = prev_smaller_suff[i + 1] + 1;
    }

    vector<vector<int>> buckets(n + 2);
    for (int w = 1; w <= n; ++w) {
        if (L[w] <= w) {
            buckets[L[w]].push_back(w);
        }
    }

    int ans = 0;
    for (int i = 1; i <= n; ++i) {
        for (int w : buckets[i]) {
            update(1, 1, n, w, w);
        }
        if (a[i] == 1) {
            int j_candidate = query(1, 1, n, i, R[i]);
            if (j_candidate >= i) {
                ans = max(ans, j_candidate - i + 1);
            }
        }
    }

    std::cout << ans << '\n';
}

int main() {
    solve();
    return 0;
}