<|instruction|>
Solve the below problem. The solution should start with an abridged problem statement. Then key observations. Then full solution based on the observations. Then C++ and Python implementations with comments.

429. Problem Stacks
Time limit per test: 0.5 second(s)
Memory limit: 262144 kilobytes
input: standard
output: standard



Fedor and Sergey are playing a game while preparing for the World Finals. They have chosen a lot of problems to solve, and arranged the problem statements into n heaps, with i-th heap containing ai problem statements, and put those heaps along one straight line. They make alternating moves, and each move consists of taking some (maybe all) problems from the first or from the last heap (but not from both) and solving them (and thus dumping the corresponding problem statements). When some player takes all problems from the first heap, the next heap is now considered first; when some player takes all problems from the last heap, the previous heap is now considered last. The player who doesn't have any more problems to solve loses.

Obviously, both Fedor and Sergey will play optimally. Fedor makes the first move. Who is going to win?

Input
The first line of the input file contains an integer n — the number of heaps (1 ≤ n ≤ 5). The second line of the input file contains n integers a1, a2,..., an ( ) — the amounts of problems in each heap.

Output
Output "FEDOR" (without quotes) if Fedor will win, or "SERGEY" (without quotes) otherwise.

Example(s)
sample input
sample output
3
5 5 5
FEDOR

sample input
sample output
4
3 1 2 3
SERGEY

<|response|>
1) Abridged problem statement
- You have n heaps in a line with sizes a1, a2, ..., an (n ≥ 1).
- Players alternate. On a move, a player chooses either the current first or current last heap and removes any positive number of stones from that heap. Empty heaps disappear.
- The player who cannot move (all heaps are gone) loses. Fedor moves first.
- Determine the winner assuming optimal play.

2) Key observations
- With 2 heaps this is just Nim on two piles: the player to move loses if and only if the two piles are equal.
- For more heaps, only the current ends are accessible. The middle segment acts like a “transform” between the ends.
- Define g[l, r](x): for the fixed middle a[l+1..r−1], it maps the left-end size x ≥ 1 to the unique right-end size y ≥ 1 that makes (x, middle, y) a losing (P) position; if no such y exists, define g[l, r](x) = 0 (a sentinel).
- For fixed x, at most one losing y exists (otherwise you could move between two losing positions).
- Each mapping g[l, r] can be encoded by a pair (L, R) with a simple rule:
  - If x is outside [min(L, R), max(L, R)], then g(x) = x (identity).
  - If x is inside, g moves one step toward R:
    - If L ≤ R: g(x) = x + 1 for x < R, and g(R) = 0.
    - If L > R: g(x) = x − 1 for x > R, and g(R) = 0.
- Base case (length 2): middle is empty, and losing happens only when the ends are equal. This is the identity mapping, i.e., the pair (0, 0).
- Inversion: the inverse mapping (desired right-end → losing left-end) is obtained by swapping the pair: inv(L, R) = (R, L).
- DP recurrence:
  - L = g[l+1, r](a[l+1])  (the losing right-end if we clear the leftmost heap first).
  - R = inv(g[l, r−1])(a[r−1])  (the losing left-end if we clear the rightmost heap first).
  - Store g[l, r] as the pair (L, R).
- Final decision:
  - Compute target = g[1, n](a1) via the pair for the whole interval.
  - If target equals an, the starting position is losing for Fedor → print SERGEY; otherwise print FEDOR.
  - Special case n = 1: Fedor takes the only heap and wins.

3) Full solution approach
- Represent each interval [l, r] by a pair (L, R) encoding g[l, r].
- Implementation of the mapping apply_func((L, R), x):
  - Let lo = min(L, R), hi = max(L, R).
  - If x < lo or x > hi, return x.
  - Otherwise:
    - If L ≤ R: return x + 1 if x < R else 0.
    - If L > R: return x − 1 if x > R else 0.
- DP:
  - Initialize g[l][r] = (0, 0) for all l, r (this already serves as the base for intervals of length 2).
  - For length = 3..n:
    - For each l, set r = l + length − 1.
    - L = apply_func(g[l+1][r], a[l+1]).
    - R = apply_func(inv(g[l][r−1]), a[r−1]) where inv swaps the pair.
    - Set g[l][r] = (L, R).
- Answer:
  - If n == 1, print FEDOR.
  - Else compute target = apply_func(g[0][n−1], a[0]).
  - Print SERGEY if target == a[n−1], else FEDOR.
- Complexity: O(n^2) time and memory; independent of the magnitude of ai.

4) C++ implementation with detailed comments
#include <bits/stdc++.h>
using namespace std;

// Apply the encoded transform g[l, r] to an input x.
// The transform is represented by a pair (L, R) with this meaning:
// - If x ∉ [min(L, R), max(L, R)], return x (identity).
// - If x is inside, move one step toward R; if x == R, return 0 (no losing y).
static inline int apply_func(pair<int, int> fn, int x) {
    int L = fn.first, R = fn.second;
    int lo = min(L, R), hi = max(L, R);
    // Outside the active interval: identity
    if (x < lo || x > hi) return x;
    // Inside: step toward R; at R we map to 0 (sentinel)
    if (L <= R) {
        return (x == R) ? 0 : (x + 1);
    } else {
        return (x == R) ? 0 : (x - 1);
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    if (!(cin >> n)) return 0;
    vector<int> a(n);
    for (int i = 0; i < n; ++i) cin >> a[i];

    // Edge case: 1 heap → Fedor takes it and wins
    if (n == 1) {
        cout << "FEDOR\n";
        return 0;
    }

    // g[l][r] stores the pair (L, R) encoding g[l, r]
    vector<vector<pair<int, int>>> g(n, vector<pair<int, int>>(n, {0, 0}));
    // Intervals of length 2 (r == l+1) are already identity via (0, 0).

    // Build DP for increasing lengths
    for (int len = 3; len <= n; ++len) {
        for (int l = 0; l + len <= n; ++l) {
            int r = l + len - 1;
            // L = g[l+1, r](a[l+1])  (losing right-end if left is cleared first)
            int L = apply_func(g[l + 1][r], a[l + 1]);
            // R = inv(g[l, r-1])(a[r-1]) where inv(L, R) = (R, L)
            pair<int, int> inv_pair = {g[l][r - 1].second, g[l][r - 1].first};
            int R = apply_func(inv_pair, a[r - 1]);
            g[l][r] = {L, R};
        }
    }

    // Compute target right-end for the whole interval
    int target = apply_func(g[0][n - 1], a[0]);
    // If target equals the actual right end, start is losing for Fedor
    cout << (target == a[n - 1] ? "SERGEY" : "FEDOR") << '\n';
    return 0;
}

5) Python implementation with detailed comments
import sys

def apply_func(fn, x):
    """
    Apply the encoded transform g[l, r] to x.
    fn is a tuple (L, R).
    Behavior:
      - If x not in [min(L, R), max(L, R)], return x (identity).
      - Else move one step toward R; if x == R, return 0 (sentinel).
    """
    L, R = fn
    lo, hi = (L, R) if L <= R else (R, L)
    if x < lo or x > hi:
        return x
    if L <= R:
        return 0 if x == R else x + 1
    else:
        return 0 if x == R else x - 1

def solve():
    data = sys.stdin.read().strip().split()
    if not data:
        return
    it = iter(data)
    n = int(next(it))
    a = [int(next(it)) for _ in range(n)]

    # One heap: Fedor wins by taking it
    if n == 1:
        print("FEDOR")
        return

    # g[l][r] is a pair (L, R); initialize to (0, 0) which is identity for positive x
    g = [[(0, 0) for _ in range(n)] for __ in range(n)]

    # Build DP by increasing interval length
    for length in range(3, n + 1):
        for l in range(0, n - length + 1):
            r = l + length - 1
            L = apply_func(g[l + 1][r], a[l + 1])
            inv_pair = (g[l][r - 1][1], g[l][r - 1][0])
            R = apply_func(inv_pair, a[r - 1])
            g[l][r] = (L, R)

    target = apply_func(g[0][n - 1], a[0])
    print("SERGEY" if target == a[n - 1] else "FEDOR")

if __name__ == "__main__":
    solve()