#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <vector>
#include "input_class.h"
using namespace std;

int main(int ArgN, char **ArgC)
{
    assert(ArgN == 9);
    // First argument - N
    int N = atoi(ArgC[1]);
    // Second argument - Q
    int Q = atoi(ArgC[2]);
    // Third Argument - MinA
    int MinA = atoi(ArgC[3]);
    // Fourth Argument - MaxA
    int MaxA = atoi(ArgC[4]);
    // Fifth Argument - Bias
    int Bias = atoi(ArgC[5]);
    // Sixth Argument - P bias
    int PBias = atoi(ArgC[6]);
    // Seventh Argument - Special Flag
    string Flag = ArgC[7];
    // Eighth Argument - Test Number
    int TestNumber = atoi(ArgC[8]);

    srand(TestNumber);
    
    Input input(N, Q, TestNumber);

    if (Flag == "none")
    {
        input.InitializeARandom(MinA, MaxA, Bias);
        if (PBias == 0)
        {
            input.RandomQueries(MinA, MaxA, Bias);
        }
        else if (PBias == -1)
        {
            for (int i = 0; i < Q; i++)
            {
                input.AddRandomQueryBiasedP(0, N/10+1, MinA, MaxA, Bias);
            }
        }
        else if (PBias == 1)
        {
            for (int i = 0; i < Q; i++)
            {
                input.AddRandomQueryBiasedP(N-1-N/10, N-1, MinA, MaxA, Bias);
            }
        }
    }
    if (Flag == "sorted")
    {
        // todo change interesting query percentage
        input.InitializeWithNonIncreasingArrayAndQueries(50, MinA, MaxA, Bias);
    }
    if (Flag == "sortedchange")
    {
        // todo change interesting query percentage
        input.InitializeWithNonIncreasingArrayAndQueries(101, MinA, MaxA, Bias);
    }
    if (Flag == "restoring")
    {
        input.InitializeARandom(MinA, MaxA, Bias);
        input.RandomRestoringQueries(MinA, MaxA, Bias);
    }
    if (Flag == "periodic")
    {
        // todo change noise percentage
        vector<int> pattern(50, 1);
        pattern[0] = MaxA;
        input.InitializeWithPeriodicPattern(pattern, 10, MinA, MaxA, Bias);
        if (PBias == 0)
        {
            input.RandomQueries(MinA, MaxA, Bias);
        }
        else if (PBias == -1)
        {
            for (int i = 0; i < Q; i++)
            {
                input.AddRandomQueryBiasedP(0, N/10+1, MinA, MaxA, Bias);
            }
        }
        else if (PBias == 1)
        {
            for (int i = 0; i < Q; i++)
            {
                input.AddRandomQueryBiasedP(N-1-N/10, N-1, MinA, MaxA, Bias);
            }
        }
    }
    if (Flag == "NQAAuthorHack")
    {
        vector<int> pattern(50, 1);
        pattern.back() = MaxA;
        input.InitializeWithPeriodicPattern(pattern, 10, MinA, MaxA, Bias);
        for (int i = 0; i < Q; i++)
        {
            int pos = RandomInRange(N*9/10, N-1);
            int num = (rand() % 50 == 0 ? MaxA : MinA);
            input.AddQuery(pos, num);
        }
    }
    if (Flag == "mountain")
    {
       input.Mountain(1, MinA, MaxA);
    }
    if (Flag == "valley")
    {
        input.Mountain(-1, MinA, MaxA);
    }
    if (Flag == "smallbig")
    {
        // todo change range
        input.AlterSmallBig(Bias, MinA, MaxA);
    }
    input.PrintInput(cout);
    return 0;
}