Problem:
Score : 100 points

Problem Statement

This contest is CODEFESTIVAL, which can be shortened to the string CF by deleting some characters.

Mr. Takahashi, full of curiosity, wondered if he could obtain CF from other strings in the same way.

You are given a string s consisting of uppercase English letters.
Determine whether the string CF can be obtained from the string s by deleting some characters.

Constraints

2 ≤ |s| ≤ 100

All characters in s are uppercase English letters (A-Z).

Input

The input is given from Standard Input in the following format:

s

Output

Print Yes if the string CF can be obtained from the string s by deleting some characters.
Otherwise print No.

Sample Input 1

CODEFESTIVAL

Sample Output 1

Yes

CF is obtained by deleting characters other than the first character C and the fifth character F.

Sample Input 2

FESTIVALCODE

Sample Output 2

No

FC can be obtained but CF cannot be obtained because you cannot change the order of the characters.

Sample Input 3

CF

Sample Output 3

Yes

It is also possible not to delete any characters.

Sample Input 4

FCF

Sample Output 4

Yes

CF is obtained by deleting the first character.

Solution in C# (Mono 4.6.2.0) (judge verdict: Runtime Error)

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

#pragma warning disable

class Segtree<T>
{
    int n;
    T[] tree;
    Func<T, T, T> f;
    T exnum;
    public Segtree(int m, Func<T, T, T> f, T ex)
    {
        this.f = f;
        this.exnum = ex;
        n = 1;
        while (n < m) n <<= 1;

        tree = new T[(n << 1) - 1];
        for (int i = 0; i < tree.Length; i++) tree[i] = ex;
    }
    public Segtree(int m, T ini, Func<T, T, T> f, T ex)
    {
        this.f = f;
        this.exnum = ex;
        n = 1;
        while (n < m) n <<= 1;

        tree = new T[(n << 1) - 1];
        for (int i = 0; i < tree.Length; i++) tree[i] = ini;
        for (int i = 0; i < m; ++i) update(i, ini);
    }
    public void update(int j, T x)
    {
        int i = j + n - 1;
        tree[i] = x;
        while (i > 0)
        {
            i = (i - 1) >> 1;
            tree[i] = f(tree[(i << 1) + 1], tree[(i << 1) + 2]);
        }
    }
    public T look(int i) { return tree[i + n - 1]; }

    // [s, t]
    public T run(int s, int t) { return query(s, t + 1, 0, 0, n); }
    T query(int s, int t, int k, int l, int r)
    {
        if (r <= s || t <= l) return exnum;
        if (s <= l && r <= t) return tree[k];

        return f(query(s, t, (k << 1) + 1, l, (l + r) >> 1), query(s, t, (k + 1) << 1, (l + r) >> 1, r));
    }
}

class PriorityQueue<T>
{
    private Comparison<T> comp;
    private List<T> list;
    private int count;
    public PriorityQueue() : this((x, y) => ((IComparable<T>)x).CompareTo(y)) { }
    public PriorityQueue(Comparison<T> comparison)
    {
        comp = comparison;
        list = new List<T>();
        count = 0;
    }
    public void Enqueue(T x)
    {
        var pos = count++;
        list.Add(x);
        while (pos > 0)
        {
            var p = (pos - 1) / 2;
            if (comp(list[p], x) <= 0) break;
            list[pos] = list[p];
            pos = p;
        }
        list[pos] = x;
    }
    public T Dequeue()
    {
        var value = list[0];
        var x = list[--count];
        list.RemoveAt(count);
        if (count == 0) return value;
        var pos = 0;
        while (pos * 2 + 1 < count)
        {
            var a = 2 * pos + 1;
            var b = 2 * pos + 2;
            if (b < count && comp(list[b], list[a]) < 0) a = b;
            if (comp(list[a], x) >= 0) break;
            list[pos] = list[a];
            pos = a;
        }
        list[pos] = x;
        return value;
    }
    public T Peek() { return list[0]; }
    public bool Any() { return count > 0; }
    public int Count() { return count; }
}

namespace Codeforces
{
    class Program
    {
        class mymath
        {
            static int Mod = 1000000007;
            public void setMod(int m) { Mod = m; }
            public bool isprime(long a)
            {
                if (a < 2) return false;
                for (long i = 2; i * i <= a; i++) if (a % i == 0) return false;
                return true;
            }
            public bool[] sieve(int n)
            {
                var isp = new bool[n + 1];
                for (int i = 2; i <= n; i++) isp[i] = true;
                for (int i = 2; i * i <= n; i++) if (isp[i]) for (int j = i * i; j <= n; j += i) isp[j] = false;
                return isp;
            }
            public List<int> getprimes(int n)
            {
                var prs = new List<int>();
                var isp = sieve(n);
                for (int i = 2; i <= n; i++) if (isp[i]) prs.Add(i);
                return prs;
            }
            public long[][] E(int n)
            {
                var ret = new long[n][];
                for (int i = 0; i < n; i++)
                {
                    ret[i] = new long[n];
                    ret[i][i] = 1;
                }
                return ret;
            }
            public long[][] powmat(long[][] A, long n)
            {
                if (n == 0) return E(A.Length);
                var t = powmat(A, n / 2);
                if ((n & 1) == 0) return mulmat(t, t);
                return mulmat(mulmat(t, t), A);
            }
            public long[] mulmat(long[][] A, long[] x)
            {
                int n = A.Length, m = x.Length;
                var ans = new long[n];
                for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) ans[i] = (ans[i] + x[j] * A[i][j]) % Mod;
                return ans;
            }
            public long[][] mulmat(long[][] A, long[][] B)
            {
                int n = A.Length, m = B[0].Length, l = B.Length;
                var ans = new long[n][];
                for (int i = 0; i < n; i++)
                {
                    ans[i] = new long[m];
                    for (int j = 0; j < m; j++) for (int k = 0; k < l; k++) ans[i][j] = (ans[i][j] + A[i][k] * B[k][j]) % Mod;
                }
                return ans;
            }
            public long[] addmat(long[] x, long[] y)
            {
                int n = x.Length;
                var ans = new long[n];
                for (int i = 0; i < n; i++) ans[i] = (x[i] + y[i]) % Mod;
                return ans;
            }
            public long[][] addmat(long[][] A, long[][] B)
            {
                int n = A.Length, m = A[0].Length;
                var ans = new long[n][];
                for (int i = 0; i < n; i++) ans[i] = addmat(A[i], B[i]);
                return ans;
            }
            public long powmod(long a, long b)
            {
                if (a >= Mod) return powmod(a % Mod, b);
                if (a == 0) return 0;
                if (b == 0) return 1;
                var t = powmod(a, b / 2);
                if ((b & 1) == 0) return t * t % Mod;
                return t * t % Mod * a % Mod;
            }
            public long inv(long a) { return powmod(a, Mod - 2); }
            public long gcd(long a, long b)
            {
                while (b > 0) { var t = a % b; a = b; b = t; }
                return a;
            }
            public long lcm(long a, long b) { return a * (b / gcd(a, b)); }
            public long Comb(int n, int r)
            {
                if (n < 0 || r < 0 || r > n) return 0;
                if (n - r < r) r = n - r;
                if (r == 0) return 1;
                if (r == 1) return n;
                var numerator = new int[r];
                var denominator = new int[r];
                for (int k = 0; k < r; k++)
                {
                    numerator[k] = n - r + k + 1;
                    denominator[k] = k + 1;
                }
                for (int p = 2; p <= r; p++)
                {
                    int pivot = denominator[p - 1];
                    if (pivot > 1)
                    {
                        int offset = (n - r) % p;
                        for (int k = p - 1; k < r; k += p)
                        {
                            numerator[k - offset] /= pivot;
                            denominator[k] /= pivot;
                        }
                    }
                }
                long result = 1;
                for (int k = 0; k < r; k++) if (numerator[k] > 1) result = result * numerator[k] % Mod;
                return result;
            }
        }

        const long InfL = 4011686018427387913L;
        static char[] sep = new char[] { ' ', '/' };


        //static int[] dx = { -1, 0, 1, -1, 1, -1, 0, -1 };
        //static int[] dy = { 1, 1, 1, 0, 0, -1, -1, -1 };

        static int[] dx = { -1, 0, 0, 1 };
        static int[] dy = { 0, 1, -1, 0 };


        /// <summary>
        /// basic dfs function
        /// </summary>
        /// 
        /* public class List_of_List<T> : List<List<T>> { }
        static int result = 0;

        static List<bool> visited = new List<bool>();
        static List_of_List<int> adj = new List_of_List<int>();

        static void dfs(int here)
        {
            if (here == n * m - 1)
            {
                result++;
                return;
            }
            visited[here] = true;

            for(int i = 0; i<adj[here].Count; i++)
            {
                int there = adj[here][i];
                if (!visited[there])
                    dfs(there);
                visited[there] = false;   
            }
        }

        static void dfsAll()
        {
            for(int i = 0; i<adj.Count; i++)
            {
                dfs(i);
            }
        }


        /* static int getInt => int.Parse(Console.ReadLine());
        static int[] getIntArr => Console.ReadLine().Trim().Split(sep).Select(a => int.Parse(a)).ToArray();
        static List<int> getIntList => Console.ReadLine().Trim().Split(sep).Select(a => int.Parse(a)).ToList<int>();
        static string getString => Console.ReadLine().Trim();
        static string[] getStrArr => Console.ReadLine().Trim().Split(sep);
        static List<string> getStrList => Console.ReadLine().Trim().Split(sep).ToList<string>();
        */
        static int m;
        static int n;
        static int[] input = new int[100001];



        static void Main(string[] args)
        {
            int[] first_input = Console.ReadLine().Trim().Split(sep).Select(a => int.Parse(a)).ToArray();
            int[] second_input = Console.ReadLine().Trim().Split(sep).Select(a => int.Parse(a)).ToArray();

            List<int> cake_count = new List<int>();
            for(int i = 0; i<second_input.Count(); i++)
            {
                cake_count.Add(second_input[i]);
            }

            cake_count.Sort();
            cake_count.Reverse();

            int result = 0;
            int cake_average = first_input[0] / first_input[1];
            for (int i = first_input[0]; i >= 0; i--) {
                if (cake_count.Count == 1)
                {
                    result = cake_count[0] - 1;
                    break;
                }
                if (cake_count.Count == 0) break;
                if(cake_count[0] > 0 && cake_count[1] > 0)
                {
                    cake_count[0]--;
                    cake_count[1]--;
                    if (cake_count[1] == 0) cake_count.RemoveAt(1);
                    if (cake_count[0] == 0) cake_count.RemoveAt(0);
                }
                cake_count.Sort();
                cake_count.Reverse();
            }

            Console.WriteLine(result);

        }

        /*
        /// <summary>
        /// 이분 매칭 알고리즘
        /// </summary>

        static bool[,] adj; // 연결 리스트. 이분 매칭이기 때문에 bool 형식이다. 혹-시라도 타임아웃이 뜬다면 인접리스트로 바꿔볼 것. 조금 빨라진다.
        static List<bool> visited; // 왼쪽의 한 정점에서 오른쪽의 모든 정점으로 방문 기록을 정리하는 리스트
        static List<int> m_match; // 왼쪽에 있는 정점들의 집합
        static List<int> n_match; // 오른쪽에 있는 정점들의 집합


        static bool dfs(int a) // 왼쪽 정점 a 에서 오른쪽 정점으로 가는 경로를 찾는다
        {
            if (visited[a]) return false;
            visited[a] = true;
            for (int b = 0; b < n; b++)
            {
                if (adj[a, b]) // 왼쪽 정점 a 에서 오른쪽 정점중 b에 연결할 수 있는 경우
                {
                    if (n_match[b] == -1 || dfs(n_match[b])) // b가 이미 매칭되어 있다면 n_match[b]에서 시작되는 증가경로를 찾는다
                    {
                        // 증가 경로를 발견한 경우 a와 b를 매치시키고 true를 반환한다
                        m_match[a] = b;
                        n_match[b] = a;
                        return true;
                    }
                }
            }
            return false;
        }

        static int bipartite_match()
        {
            m_match = Enumerable.Repeat(-1, m).ToList(); // 왼쪽에 있는 정점들의 각 원소가 오른쪽에 있는 어떤 정점과 대응되는지 기록하는 리스트
            n_match = Enumerable.Repeat(-1, n).ToList(); // 오른쪽에 있는 정점들의 각 원소가 왼쪽에 있는 어떤 정점과 대응되는지 기록하는 리스트

            int size = 0; // 몇 쌍이 대응되는지 기록하는 변수
            for (int start = 0; start < m; start++) // m_match (왼쪽에 있는 정점들 집합) 의 모든 원소에 대해 dfs 실시
            {
                visited = Enumerable.Repeat(false, m).ToList(); // 모든 점에 대해 초기화 (방문하지 않음으로 표시)

                if (dfs(start)) size++; // 각 왼쪽 정점에서 dfs를 실시해서 갈 수 있는 경로가 있다면 경로의 개수를 1 늘린다
            }
            return size;
        }
        */

        /*
        /// <summary>
        /// 네트워크 유량 문제용 포드-풀커슨 알고리즘
        /// </summary>

        const int INF = 987654321;
        static int v; // 정점의 수. source와 sink가 있으므로 감안해서 계산
        static int max_v;
        static int[,] capacity, flow;
        // capacity[u,v] = u에서 v로 보낼 수 있는 용량, flow[u,v] = u에서 v로 흘러가는 유량 (반대방향인 경우 음수)

        // flow[,] 를 계산하고 총 유량을 반환하는 함수
        static int networkFlow(int source, int sink)
        {
            flow = new int[max_v, max_v]; // flow 배열의 초기화
            int totalFlow = 0;
            while (true)
            {
                List<int> parent = Enumerable.Repeat(-1, max_v).ToList();
                Queue<int> q = new Queue<int>();
                parent[source] = source;
                q.Enqueue(source);
                while (q.Count != 0 && parent[sink] == -1)
                {
                    int here = q.Dequeue();
                    for (int there = 0; there < v; there++)
                    {
                        if (capacity[here, there] - flow[here, there] > 0 && parent[there] == -1)
                        {
                            q.Enqueue(there);
                            parent[there] = here;
                        }
                    }
                }

                if (parent[sink] == -1) break;

                int amount = INF;
                for(int p = sink; p != source; p = parent[p])
                {
                    amount = Math.Min(capacity[parent[p], p] - flow[parent[p], p], amount);
                }
                for(int p = sink; p != source; p = parent[p])
                {
                    flow[parent[p], p] += amount;
                    flow[p, parent[p]] -= amount;
                }
             
                totalFlow += amount;
            }
            return totalFlow;
        }
        */
    }
}