// USING ON -----

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

// USING OFF -----
// USING ON -----

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using Marathon;

// USING OFF -----
// USING ON -----

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Xsl.Runtime;

// USING OFF -----
// USING ON -----

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

// USING OFF -----
// CONTENT ON -----

// CONTENT OFF -----
// CONTENT ON -----

#region Utility

namespace Marathon.Problem
{
    public class ArgOption
    {
        public string Key;
        public string Value;
    }

    public class ArgParser
    {
        private Dictionary<string, ArgOption> ArgOptions;
        private Dictionary<string, string> ShortKeyMap;

        public ArgParser()
        {
            ArgOptions = new Dictionary<string, ArgOption>();
            ShortKeyMap = new Dictionary<string, string>();
        }

        // Parse
        public void Parse(string[] args)
        {
            ArgOption target = null;
            string keyJoined = string.Join(" ", args);
            foreach (var arg in args)
            {
                // キーか値かの判定
                if (arg.StartsWith("--") || arg.StartsWith("-"))
                {
                    string key;
                    if (arg.StartsWith("--"))
                    {
                        key = arg.Substring(2);
                    }
                    else
                    {
                        string shortKey = arg.Substring(1);
                        if (!ShortKeyMap.ContainsKey(shortKey))
                            throw new ArgumentException($"-{shortKey} not found, args:{keyJoined}");
                        key = ShortKeyMap[shortKey];
                    }

                    if (!ArgOptions.ContainsKey(key))
                        throw new ArgumentException($"--{key} not found, args:{keyJoined}");
                    if (target != null)
                        throw new ArgumentException($"--{target.Key} not processed, args:{keyJoined}");
                    target = ArgOptions[key];
                }
                else
                {
                    if (target == null)
                        throw new ArgumentException($"key not preceded, args:{keyJoined}");
                    target.Value = arg;
                    target = null;
                }
            }

            if (target != null)
                throw new ArgumentException($"--{target.Key} not processed, args:{keyJoined}");

            foreach (var argOption in ArgOptions.Values)
            {
                if (argOption.Value == null)
                    throw new ArgumentException($"--{argOption.Key} not set, args:{keyJoined}");
            }
        }

        // 引数の定義
        public void SetArg(string key, string defaultValue = null, string shortKey = null)
        {
            ArgOptions.Add(key, new ArgOption {Key = key, Value = defaultValue});
            if (shortKey != null)
                ShortKeyMap.Add(shortKey, key);
        }

        // パラメータの取得
        public string GetStr(string key)
        {
            return ArgOptions[key].Value;
        }

        public int GetInt(string key)
        {
            return int.Parse(GetStr(key));
        }

        public double GetDouble(string key)
        {
            return double.Parse(GetStr(key));
        }

        public bool GetBool(string key)
        {
            return bool.Parse(GetStr(key));
        }
    }

    public class StatusWriter
    {
        public bool IsValid;
        public List<Tuple<string, object>> Data;
        private StreamWriter streamWriter;

        public StatusWriter(bool isValid, string path = null)
        {
            IsValid = isValid;
            Data = new List<Tuple<string, object>>();
            if (IsValid)
            {
                System.IO.Directory.CreateDirectory(Path.GetDirectoryName(path));
                streamWriter = new StreamWriter(path);
            }
        }

        public void Add(string key, object value)
        {
            Data.Add(Tuple.Create(key, value));
        }

        public string DataString(bool keyQuote, bool addNewLine)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("{");
            if (addNewLine)
                sb.AppendLine();
            for (int i = 0; i < Data.Count; i++)
            {
                var tpl = Data[i];
                string key = tpl.Item1;
                object value = tpl.Item2;
                bool isValidType = value is int || value is long ||
                                   value is bool || value is double || value is float;
                string keyString = keyQuote ? $"\"{key}\"" : $"{key}";
                string valueString = keyQuote && !isValidType ? $"\"{value}\"" : $"{value}";
                sb.Append($"{keyString}: {valueString}");
                if (i < Data.Count - 1)
                {
                    sb.Append(",");
                    if (addNewLine)
                        sb.AppendLine();
                    else
                        sb.Append(" ");
                }
                else
                {
                    if (addNewLine)
                        sb.AppendLine();
                    sb.Append("}");
                }
            }

            return sb.ToString();
        }

        public void Write()
        {
            if (IsValid)
            {
                streamWriter.WriteLine(DataString(true, true));
                streamWriter?.Close();
            }
        }

        public void Close()
        {
            if (IsValid)
                streamWriter?.Close();
        }
    }

    /// <summary>
    /// ロギング
    /// </summary>
    public class Logger
    {
        public bool IsValid;
        private StreamWriter streamWriter;

        public Logger(bool isValid, string path = null)
        {
            IsValid = isValid;
            if (IsValid)
            {
                System.IO.Directory.CreateDirectory(Path.GetDirectoryName(path));
                streamWriter = new StreamWriter(path);
            }
        }

        public void Fatal(string message)
        {
            Console.Error.WriteLine(message);
            streamWriter?.WriteLine(message);
        }

        public void Info(string message)
        {
            if (IsValid)
            {
                Console.Error.WriteLine(message);
                streamWriter.WriteLine(message);
            }
        }

        public void Debug(string message)
        {
            if (IsValid)
            {
                streamWriter.WriteLine(message);
            }
        }

        public void Close()
        {
            if (IsValid)
            {
                streamWriter?.Close();
            }
        }
    }


    /// <summary>
    /// 時間計測 
    /// </summary>
    public class Timer
    {
        private long StartTime;

        public static long NowUnixTime()
        {
            return new DateTimeOffset(DateTime.Now).ToUnixTimeMilliseconds();
        }

        public void Start()
        {
            StartTime = NowUnixTime();
        }

        public long Elapsed
        {
            get { return NowUnixTime() - StartTime; }
        }
    }

    /// <summary>
    /// プロファイリング目的の時間計測 
    /// </summary>
    public class TimerStat
    {
        List<long> sum = new List<long>();
        List<long> start = new List<long>();

        public void Start(int i)
        {
            if (Runner.MEASURE_TIME)
            {
                while (sum.Count() <= i)
                {
                    sum.Add(0L);
                    start.Add(0L);
                }

                start[i] = Timer.NowUnixTime();
            }
        }

        public void Stop(int i)
        {
            if (Runner.MEASURE_TIME)
            {
                sum[i] += Timer.NowUnixTime() - start[i];
            }
        }

        public void Print()
        {
            if (Runner.MEASURE_TIME && sum.Count > 0)
            {
                var sb = new StringBuilder();
                sb.Append("[");
                for (int i = 0; i < sum.Count; i++)
                {
                    sb.Append(sum[i]);
                    sb.Append(", ");
                }

                sb.Append("]");
                Console.Error.WriteLine(sb.ToString());
            }
        }
    }

    /// <summary>
    /// ユーティリティ（拡張メソッド）
    /// </summary>
    static class UtilExtension
    {
        public static string Show<T>(this T[,] ary)
        {
            var sb = new StringBuilder();
            sb.AppendLine("---------------------");
            int h = ary.GetLength(0);
            int w = ary.GetLength(1);
            for (int y = 0; y < h; y++)
            {
                for (int x = 0; x < w; x++)
                {
                    sb.Append(ary[y, x]);
                    if (x < w)
                        sb.Append(',');
                }

                if (y < h)
                    sb.Append('\n');
            }

            sb.AppendLine("---------------------");

            return sb.ToString();
        }

        public static string Show(this int[,,] ary, int INF)
        {
            var sb = new StringBuilder();
            sb.AppendLine("====================");
            for (int d = 0; d < ary.GetLength(2); d++)
            {
                int h = ary.GetLength(0);
                int w = ary.GetLength(1);
                for (int y = 0; y < h; y++)
                {
                    for (int x = 0; x < w; x++)
                    {
                        int value = ary[y, x, d];
                        if (value == INF)
                        {
                            sb.Append('.');
                        }
                        else
                        {
                            sb.Append(ary[y, x, d]);
                        }

                        if (x < w)
                            sb.Append(',');
                    }

                    if (y < h)
                        sb.Append('\n');
                }

                sb.AppendLine("---------------------");
            }

            sb.AppendLine("====================");

            return sb.ToString();
        }
    }

    #endregion
}

// CONTENT OFF -----
// CONTENT ON -----
namespace Marathon.Problem
{
    // ReSharper disable once ClassNeverInstantiated.Global
    public class Program
    {
        public static void Main(string[] args)
        {
            var runner = new Runner();
            runner.Run(args);
        }
    }

    public class Runner
    {
        public static bool LOCAL = false;
        public static bool DEBUG = false;
        public static bool DEBUG_HEAVY = false;
        public static bool MEASURE_TIME = false;

        public Timer timer = new Timer();
        public TimerStat timerStat = new TimerStat();
        public double TL = 1800;

        public Random rnd;
        private TextReader reader;
        private TextWriter writer;
        public static Logger logger;
        private StatusWriter statusWriter;

        // ユーティリティ
        public char[] DChars = new char[] {'D', 'R', 'U', 'L'};
        public int[] DX = new int[] {0, 1, 0, -1};
        public int[] DY = new int[] {1, 0, -1, 0};

        // 入力パラメータ
        public static int D;
        public static int K = 26;
        public static int[] C;
        public static int[,] S;

        // immutableな状態        
        public char[,] MAP;

        // mutableな状態
        public long bestScore;
        public int[] bestCommand;
        int counter;
        int counterUpdate;

        // パラメータ
        public static string Name;
        public static string Case;
        public int Seed;
        public Annealer annealer;
        double t0;
        private double t1;
        private double p1;
        
        public void Run(string[] args)
        {
#if LOCAL
            LOCAL = true;
#endif    
            timer.Start();
            
            // パラメータのセット
            if (LOCAL)
            {
                var parser = new ArgParser();
                parser.SetArg("t0",  defaultValue:"2000");
                parser.SetArg("t1", defaultValue:"600");
                parser.SetArg("p1", defaultValue:"0.5");
                parser.SetArg("name", "default", shortKey:"n");
                parser.SetArg("case", "input_02");
                parser.SetArg("tl", "1800");
                parser.Parse(args);
                t0 = parser.GetDouble("t0");
                t1 = parser.GetDouble("t1");
                TL = parser.GetDouble("tl");
                Name = parser.GetStr("name");
                Case = parser.GetStr("case");
            }
            else
            {
                t0 = 2000.0;
                t1 = 600;
                p1 = 0.5;
                Name = "none";
                Case = "none";
                TL = 1800;
            }
            
            if (LOCAL)
            {
                Directory.SetCurrentDirectory(
                    Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location));
                Directory.CreateDirectory("result");
                string inDir = "input";
                string outDir = "result";
                string inFileName = $"{Case}.txt";
                string outFileName = $"output-{Name}-{Case}.txt";
                string logFileName = $"log-{Name}-{Case}.log";
                string statusFileName = $"status-{Name}-{Case}.txt";
                string inFilePath = Path.Combine(inDir, inFileName);
                string outFilePath = Path.Combine(outDir, outFileName);
                string inFileCopyPath = Path.Combine(outDir, inFileName);
                string logFilePath = Path.Combine(outDir, logFileName);
                string statusFilePath = Path.Combine(outDir, statusFileName);
                reader = new StreamReader(inFilePath);
                writer = new StreamWriter(outFilePath);
                File.Copy(inFilePath, inFileCopyPath, overwrite: true);
                logger = new Logger(true, logFilePath);
                statusWriter = new StatusWriter(true, statusFilePath);
            }
            else
            {
                reader = Console.In;
                writer = Console.Out;
                logger = new Logger(false);
                statusWriter = new StatusWriter(false);
            }
            
            // 入力データの処理
            {
                {
                    D = int.Parse(reader.ReadLine());
                }
                {
                    C = reader.ReadLine().Split(' ').Select(int.Parse).ToArray();
                }
                {
                    S = new int[D, K];
                    for (int i = 0; i < D; i++)
                    {
                        var values = reader.ReadLine().Split(' ').Select(int.Parse).ToArray();
                        for (int k = 0; k < K; k++)
                        {
                            S[i, k] = values[k];
                        }
                    }
                }
            }

            // 初期化
            int seed = 71;
            rnd = new Random(seed);
            annealer = new Annealer(t0, t1);

            // 計算の実行
          
            Solve();
            // logger.Info($"score: {calcScore(Order)}");

            // 出力
            WriteAnswer();
            
            // データ
            statusWriter.Add("name", Name);
            statusWriter.Add("case", Case);
            statusWriter.Add("score", bestScore);
            statusWriter.Add("score_true", bestScore + 1000000);
            statusWriter.Add("timer", timer.Elapsed);
            statusWriter.Add("counter", counter);
            statusWriter.Write();

            logger.Fatal(statusWriter.DataString(false, false));
            logger.Close();
            
            writer.Close();

            timerStat.Print();
        }

        int ArgMax(int d)
        {
            int max = -1;
            int index = -1;
            for (int k = 0; k < K; k++)
            {
                int v = S[d, k];
                if (v > max)
                {
                    max = v;
                    index = k;
                }
            }

            return index;
        }

        void Solve()
        {
            var command = new int[D];
            for (int d = 0; d < D; d++)
            {
                command[d] = rnd.Next(K); // d % 26;
            }

            State state = new State(command);

            // 探索
            while (!(timer.Elapsed > TL))
            {
                // 焼きなまし
                long initialTime = timer.Elapsed;
                counter = 0;

                for (;;)
                {
                    counter++;

                    // 256ターンごとに処理
                    if ((counter & 0xFF) == 0)
                    {
                        long elapsed = timer.Elapsed;
                        if (elapsed > TL)
                        {
                            logger.Info("turn:" + counter + " bestScore:" + bestScore);
                            break;
                        }

                        if ((counter & 0xFF) == 0)
                        {
                            double anneal_t = 1.0 * (elapsed - initialTime) / (TL - initialTime);
                            annealer.SetTemperature(anneal_t);
                            logger.Info("Cooler:" + annealer.Temperature);
                        }
                    }

                    long newScore;
                    double prob = p1;
                    int flg = 0, p1_r1 = 0, p1_r2 = 0, p2_d1 = 0, p2_v1 = 0;
                    if (rnd.NextDouble() < prob)
                    {
                        flg = 1;
                        // 2点swap
                        while (true)
                        {
                            p1_r1 = rnd.Next(D);
                            p1_r2 = p1_r1 + 1 + rnd.Next(16);

                            // ReSharper disable once ReplaceWithSingleAssignment.True
                            bool valid = true;
                            if (p1_r2 >= D || state.Command[p1_r1] == state.Command[p1_r2]) 
                                valid = false;
                            if (valid)
                                break;
                        }

                        newScore = state.CalculationSwap(p1_r1, p1_r2);
                        // logger.Info($"score: {score} -> {newScore}");
                    }
                    else
                    {
                        // 1点更新
                        flg = 2;
                        while (true)
                        {
                            p2_d1 = rnd.Next(D);
                            p2_v1 = rnd.Next(K);
                            newScore = state.CalculationChange(p2_d1, p2_v1);
                        
                            // ReSharper disable once ReplaceWithSingleAssignment.True
                            bool valid = true;
                            if (state.Command[p2_d1] == p2_v1)
                                valid = false;
                            if (valid)
                                break;
                        }

                        // logger.Info($"score: {score} -> {newScore}");
                    }

                    // Timer1
                    if (annealer.Accept(state.Score, newScore))
                    {
                        // 変更が受理された場合
                        counterUpdate++;

                        if (flg == 1)
                        {
                            state.UpdateSwap(p1_r1, p1_r2);
                        }

                        if (flg == 2)
                        {
                            state.UpdateChange(p2_d1, p2_v1);
                        }

                        // logger.Debug($"accepted score: {score} turn:{turn} flg:{flg} time:{timer.Elapsed}");

                        // ベスト点数を超えている場合はその状態を保存
                        // TODO: 序盤の更新が多い場合は後半のみにするなど
                        if (bestCommand == null || (state.Score > bestScore))
                        {
                            bestScore = state.Score;
                            bestCommand = state.Command.ToArray();
                            logger.Info("score:" + bestScore + " at turn:" + counter);
                        }
                    }
                }
            }
        }

        void WriteAnswer()
        {
            var answer = bestCommand;
            for (int i = 0; i < answer.Length; i++)
            {
                // 1-indexedに直す
                writer.WriteLine(answer[i] + 1);
            }
        }
    }

    public class State
    {
        // 計算の高速化処理を含む
        public int[] Command;
        public long Score;
        public static int D;
        public static int K;
        public static int[] C;
        public static int[,] S;

        public int[,] LastContest; // 前のコンテストの日、初期値は-1 -- 常に-1日目に開催されると考えて良い
        public int[,] NextContest; // 次のコンテストの日、初期値はD -- 常にD日目に開催されると考えて良い

        public State(int[] command)
        {
            D = Runner.D;
            K = Runner.K;
            C = Runner.C;
            S = Runner.S;
            this.Command = command;
            InitialCalc();
        }

        public void InitialCalc()
        {
            long score = 0;
            for (int k = 0; k < K; k++)
            {
                long scoreK = 0;
                int last = 0;
                for (int d = 0; d < D; d++)
                {
                    if (k == Command[d])
                    {
                        scoreK += S[d, k];
                        last = d + 1;
                    }

                    scoreK -= (d + 1 - last) * C[k];
                }

                score += scoreK;
            }

            Score = score;

            // 初期化
            LastContest = new int[D, K];
            NextContest = new int[D, K];
            for (int k = 0; k < K; k++)
            {
                int last = -1;
                for (int d = 0; d < D; d++)
                {
                    LastContest[d, k] = last;
                    if (Command[d] == k)
                    {
                        last = d;
                    }
                }

                int next = D;
                for (int d = D - 1; d >= 0; d--)
                {
                    NextContest[d, k] = next;
                    if (Command[d] == k)
                    {
                        next = d;
                    }
                }
            }
        }

        public static long ScoreCalcRaw(int[] command)
        {
            // 素直な計算を行う
            long[] scoreContests = new long[K];
            for (int k = 0; k < K; k++)
            {
                long scoreK = 0;
                int last = 0;
                for (int d = 0; d < D; d++)
                {
                    if (k == command[d])
                    {
                        scoreK += S[d, k];
                        last = d + 1;
                    }

                    scoreK -= (d + 1 - last) * C[k];
                }

                scoreContests[k] = scoreK;
            }

            return scoreContests.Sum();
        }

        // ========================
        private long RemoveScore(int d, int k)
        {
            long diff = 0;
            diff -= S[d, k];
            int db1 = (d - 1) - LastContest[d, k];
            int db2 = NextContest[d, k] - (d + 1);
            int da1 = NextContest[d, k] - LastContest[d, k] - 1;
            int sb = db1 * (db1 + 1) / 2 + db2 * (db2 + 1) / 2;
            int sa = da1 * (da1 + 1) / 2;
            diff -= (-C[k] * sb);
            diff += (-C[k] * sa);
            return diff;
        }

        private long AddScore(int d, int k)
        {
            long diff = 0;
            diff += S[d, k];
            int db1 = NextContest[d, k] - LastContest[d, k] - 1;
            int da1 = (d - 1) - LastContest[d, k];
            int da2 = NextContest[d, k] - (d + 1);
            int sb = db1 * (db1 + 1) / 2;
            int sa = da1 * (da1 + 1) / 2 + da2 * (da2 + 1) / 2;
            diff -= (-C[k] * sb);
            diff += (-C[k] * sa);
            return diff;
        }

        private long SwapScore(int k, int db, int da)
        {
            // 重なるように動かすことはないとする
            Debug.Assert(da != db);
            Debug.Assert(NextContest[db, k] != da);
            Debug.Assert(LastContest[db, k] != da);

            // db -> da に動かす場合
            int next = NextContest[db, k];
            int last = LastContest[db, k];
            bool jump = (da > db && da > next) || (da < db && da < last);

            if (jump)
            {
                long diff = 0;
                diff += RemoveScore(db, k);
                diff += AddScore(da, k);
                return diff;
            }
            else
            {
                long diff = 0;
                diff -= S[db, k];
                diff += S[da, k];
                int db1 = (db - 1) - last;
                int db2 = next - (db + 1);
                int da1 = (da - 1) - last;
                int da2 = next - (da + 1);
                int sb = db1 * (db1 + 1) / 2 + db2 * (db2 + 1) / 2;
                int sa = da1 * (da1 + 1) / 2 + da2 * (da2 + 1) / 2;
                diff -= (-C[k] * sb);
                diff += (-C[k] * sa);
                return diff;
            }
        }

        private void RemoveUpdate(int dc, int k)
        {
            // Commandの処理は省略
            Score += RemoveScore(dc, k);

            // 更新
            {
                int d = dc - 1;
                while (d >= 0 && NextContest[d, k] == dc)
                {
                    NextContest[d, k] = NextContest[dc, k];
                    d--;
                }
            }

            {
                int d = dc + 1;
                while (d < D && LastContest[d, k] == dc)
                {
                    LastContest[d, k] = LastContest[dc, k];
                    d++;
                }
            }
        }

        private void AddUpdate(int dc, int k)
        {
            Command[dc] = k;
            Score += AddScore(dc, k);

            // 更新
            {
                int d = dc - 1;
                while (d >= 0 && d >= LastContest[dc, k])
                {
                    NextContest[d, k] = dc;
                    d--;
                }
            }

            {
                int d = dc + 1;
                while (d < D && d <= NextContest[dc, k])
                {
                    LastContest[d, k] = dc;
                    d++;
                }
            }
        }

        private void SwapUpdate(int k, int db, int da)
        {
            // 更新
            int next = NextContest[db, k];
            int last = LastContest[db, k];
            bool jump = (da > db && da > next) || (da < db && da < last);

            if (jump)
            {
                RemoveUpdate(db, k);
                AddUpdate(da, k);
            }
            else
            {
                Command[da] = k;
                Score += SwapScore(k, db, da);
                for (int d = last; d <= next; d++)
                {
                    if (d < 0 || d >= D) continue;
                    if (d != next)
                    {
                        if (d < da)
                            NextContest[d, k] = da;
                        else
                            NextContest[d, k] = next;
                    }

                    if (d != last)
                    {
                        if (d > da)
                            LastContest[d, k] = da;
                        else
                            LastContest[d, k] = last;
                    }
                }
            }
        }

        // ===========================-
        
        public long CalculationChange(int d, int k)
        {
            // d: kb -> k
            // kb == kであればそのまま
            int kb = Command[d];
            if (kb == k)
                return Score;

            // 差分計算
            long diff = 0;
            diff += RemoveScore(d, kb);
            diff += AddScore(d, k);

            if (Runner.DEBUG_HEAVY)
            {
                int[] command = Command.ToArray();
                command[d] = k;
                long scoreX = ScoreCalcRaw(command);
                if (scoreX != Score + diff)
                    throw new Exception();
            }

            return Score + diff;
        }

        public void UpdateChange(int d, int k)
        {
            int kb = Command[d];
            RemoveUpdate(d, kb);
            AddUpdate(d, k);

            if (Runner.DEBUG_HEAVY)
            {
                Runner.logger.Info($"Update Change d:{d} k:{k}");
                if (ScoreCalcRaw(Command) != Score)
                    throw new Exception();
            }
        }

        public long CalculationSwap(int d1, int d2)
        {
            // d1: k1 -> k2
            // d2: k2 -> k1
            // k1 == k2であればそのまま

            int k1 = Command[d1];
            int k2 = Command[d2];
            if (k1 == k2)
                return Score;

            // 差分計算
            long diff = 0;
            diff += SwapScore(k1, d1, d2);
            diff += SwapScore(k2, d2, d1);

            if (Runner.DEBUG_HEAVY)
            {
                Runner.logger.Info($"Update Swap d1:{d1} d2:{d2} k1:{k1} k2:{k2}");
                int[] command = Command.ToArray();
                command[d1] = k2;
                command[d2] = k1;
                long scoreX = ScoreCalcRaw(command);
                if (scoreX != Score + diff)
                    throw new Exception();
            }

            return Score + diff;
        }

        public void UpdateSwap(int d1, int d2)
        {
            int k1 = Command[d1];
            int k2 = Command[d2];
            SwapUpdate(k1, d1, d2);
            SwapUpdate(k2, d2, d1);
            if (Runner.DEBUG_HEAVY)
            {
                if (ScoreCalcRaw(Command) != Score)
                    throw new Exception();
            }
        }
    }

    public class Annealer
    {
        public double InitialT;
        public double FinalT;
        public double Temperature;
        private Random rand = new Random(71);

        public Annealer(double initialT, double finalT)
        {
            InitialT = initialT;
            FinalT = finalT;
        }

        public void SetTemperature(double t)
        {
            double tp0 = InitialT;
            double tp1 = FinalT;
            // 線形とした
            // TODO: 指数関数型への変更
            // Temperature = it * (1 - t) + ft * t;

            Temperature = Math.Pow(tp0, 1.0 - t) * Math.Pow(tp1, t);
        }

        public bool Accept(double prev, double cur)
        {
            if (cur >= prev) return true;
            double loss = cur - prev;
            double prob = Math.Exp(loss / Temperature);
            return rand.NextDouble() < prob;
        }
    }
}


// CONTENT OFF -----
// CONTENT ON -----

namespace Marathon.Problem
{
    #region Structure

    public struct Pos
    {
        public int y;
        public int x;

        public Pos(int y, int x)
        {
            this.y = y;
            this.x = x;
        }
    }

    public class PriorityQueue<T>
    {
        private Comparison<T> _comparison;
        private int _type = 0;

        private T[] _heap;
        private int _sz = 0;

        private int _count = 0;

        /// <summary>
        /// Priority Queue with custom comparer
        /// </summary>
        public PriorityQueue(Comparison<T> comparison)
        {
            _heap = new T[128];
            _comparison = comparison;
        }

        private int Compare(T x, T y)
        {
            return _comparison(x, y);
        }

        public void Push(T x)
        {
            _count++;
            if (_count > _heap.Length)
            {
                var newheap = new T[_heap.Length * 2];
                for (int n = 0; n < _heap.Length; n++) newheap[n] = _heap[n];
                _heap = newheap;
            }

            //node number
            var i = _sz++;

            while (i > 0)
            {
                //parent node number
                var p = (i - 1) / 2;

                if (Compare(_heap[p], x) <= 0) break;

                _heap[i] = _heap[p];
                i = p;
            }

            _heap[i] = x;
        }

        public T Pop()
        {
            _count--;

            T ret = _heap[0];
            T x = _heap[--_sz];

            int i = 0;
            while (i * 2 + 1 < _sz)
            {
                //children
                int a = i * 2 + 1;
                int b = i * 2 + 2;

                if (b < _sz && Compare(_heap[b], _heap[a]) < 0) a = b;

                if (Compare(_heap[a], x) >= 0) break;

                _heap[i] = _heap[a];
                i = a;
            }

            _heap[i] = x;

            return ret;
        }

        public int Count()
        {
            return _count;
        }

        public T Peek()
        {
            return _heap[0];
        }

        public bool Contains(T x)
        {
            for (int i = 0; i < _sz; i++)
                if (x.Equals(_heap[i]))
                    return true;
            return false;
        }

        public void Clear()
        {
            while (this.Count() > 0) this.Pop();
        }

        public IEnumerator<T> GetEnumerator()
        {
            var ret = new List<T>();

            while (this.Count() > 0)
            {
                ret.Add(this.Pop());
            }

            foreach (var r in ret)
            {
                this.Push(r);
                yield return r;
            }
        }

        public T[] ToArray()
        {
            T[] array = new T[_sz];
            int i = 0;

            foreach (var r in this)
            {
                array[i++] = r;
            }

            return array;
        }
    }

    #endregion
}

// CONTENT OFF -----


Measured memory_bytes: 25900