import core.bitop, std.bitmanip;
import core.checkedint;
import std.algorithm, std.functional, std.meta;
import std.array, std.container;
import std.bigint;
import std.conv;
import std.math, std.numeric;
import std.range, std.range.interfaces;
import std.stdio, std.string;
import std.ascii, std.typecons;

void main(string[ ] args) {
    int t;
    readf!"%s"(t);
    readln;

    while (t--) {
        readln;

        int n, k;
        readf!"%s %s"(n, k);
        readln;

        auto f = readln.chomp.split.map!(to!int).array;

        auto g = new int[][] (n+1);
        foreach (i; 0 .. n-1) {
            int x, y;
            readf!"%s %s"(x, y);
            readln;

            g[x] ~= y;
            g[y] ~= x;
        }

        auto pos = new bool[n+1];
        pos[] = true;
        f.each!(v => pos[v] = false);

        alias r = Tuple!(bool, "good", int, "enemyDepth");

        immutable int INF = 10 ^^ 6;

        r dfs(int v, int fr, int d) {
            if (!pos[v]) {
                return r(false, d);
            }

            if (d != 0 && g[v].length == 1) {
                return r(true, INF);
            }

            int minEnemyDepth = INF;
            bool pathExists = false;
            foreach (u; g[v]) {
                if (u == fr) { continue; }

                auto res = dfs(u, v, d + 1);
                pathExists |= res.good;
                minEnemyDepth = min(minEnemyDepth, res.enemyDepth);
            }

            auto enemyStepsToReach = minEnemyDepth - d;

            return r(pathExists && enemyStepsToReach > d, minEnemyDepth);
        }

        auto ans = dfs(1, 0, 0);

        writeln(ans.good ? "YES" : "NO");
    }
}

import std.algorithm, std.array, std.container, std.conv, std.math, std.numeric, std.random, std.range, std.stdio, std.string, std.typecons, core.bitop;

struct node { int vlad_dist = -1, friend_dist = -1; };
alias PairII = Tuple!(int, int);

void dfs(int s, int[][] adj, node[] a, int dist)
{
  a[s].vlad_dist = dist;
  foreach (d ; adj[s]) {
    if (a[d].vlad_dist != -1)
      continue;
    dfs(d, adj, a, dist + 1);
  }
}

void bfs(int[] friends, int[][] adj, node[] a)
{
  auto queue = new DList!PairII;
  foreach (friend ; friends) {
    a[friend].friend_dist = 0;
    queue.insertBack(tuple(friend, 0));
  }
  while (!queue.empty) {
    auto x = queue.front;
    queue.removeFront;
    int s = x[0];
    int dist = x[1];
    foreach (d ; adj[s]) {
      if (a[d].friend_dist != -1)
        continue;
      a[d].friend_dist = dist + 1;
      queue.insertBack(tuple(d, dist + 1));
    }
  }
}

void main()
{
  foreach (casenum ; 1 .. readln.strip.to!int + 1) {
    int n, k;
    readf!" %d %d "(n, k);
    auto friends = readln.splitter.map!(x => x.to!int - 1).array;
    node[] a = new node[](n);
    int[][] adj = new int[][](n);
    foreach (i ; 0 .. n - 1) {
      int v, u;
      readf!" %d %d "(v, u);
      v--;
      u--;
      adj[v] ~= u;
      adj[u] ~= v;
    }
    dfs(0, adj, a, 0);
    bfs(friends, adj, a);
    bool vlad_wins = false;
    foreach (i ; 1 .. n) {
      if (adj[i].length != 1)
        continue;
      if (a[i].vlad_dist < a[i].friend_dist) {
        vlad_wins = true;
        break;
      }
    }
    writeln(vlad_wins ? "YES" : "NO");
  }
}

import std.algorithm;
import std.conv;
import std.range;
import std.stdio;
import std.string;

void main ()
{
	auto tests = readln.strip.to !(int);
	foreach (test; 0..tests)
	{
		int n, k;
		readf !(" %s %s") (n, k);
		readln;

		auto x = readln.splitter.map !(to !(int)).array;
		x[] -= 1;
		auto b = new bool [n];
		foreach (ref c; x)
		{
			b[c] = true;
		}

		auto g = new int [] [n];
		foreach (j; 0..n - 1)
		{
			int u, v;
			readf !(" %s %s") (u, v);
			u -= 1;
			v -= 1;
			g[u] ~= v;
			g[v] ~= u;
		}

		auto depth = new int [n];

		void recurDepth (int v, int p, int cur)
		{
			depth[v] = cur;
			foreach (u; g[v])
			{
				if (u == p)
				{
					continue;
				}
				recurDepth (u, v, cur + 1);
			}
		}

		recurDepth (0, -1, 0);

		auto friend = new int [n];

		void recurFriend (int v, int p)
		{
			int res = n;
			if (b[v])
			{
				res = 0;
			}
			foreach (u; g[v])
			{
				if (u == p)
				{
					continue;
				}
				recurFriend (u, v);
				res = min (res, friend[u] + 1);
			}
			friend[v] = res;
		}

		recurFriend (0, -1);

		bool recurVisit (int v, int p)
		{
			if (friend[v] <= depth[v])
			{
				return false;
			}
			if (v != 0 && g[v].length == 1)
			{
				return true;
			}
			foreach (u; g[v])
			{
				if (u == p)
				{
					continue;
				}
				if (recurVisit (u, v))
				{
					return true;
				}
			}
			return false;
		}

		auto res = recurVisit (0, -1);

		writeln (res ? "YES" : "NO");
	}
}

import std.stdio;
import std.math;
import std.numeric;
import std.container;
import std.typecons;
import core.stdc.stdio : scanf;
import std.conv;
import std.array;
import std.string;
import std.range;
import std.algorithm;

T read(T)() { return readln.chomp.to!T; }
T[] readarray(T)() { return readln.chomp.split(" ").map!(to!T).array; }

void main() {
    int T = read!int;
    foreach (t; 0 .. T) solve();
}

enum int INF = 1<<29;

void solve() {
    readln;
    int N, K; readf("%d %d\n", &N, &K);
    auto X = readarray!int;
    foreach (ref x; X) x--;
    auto G = new int[][N];
    foreach (i; 0 .. N - 1) {
        int U, V; readf("%d %d\n", &U, &V);
        U--; V--;
        G[U] ~= V;
        G[V] ~= U;
    }

    void bfs(in int[] ss, ref int[] d) {
        d[] = INF;
        DList!int Q;
        foreach (s; ss) {
            Q.insert(s);
            d[s] = 0;
        }
        while (! Q.empty) {
            auto c = Q.front; Q.removeFront;
            foreach (next; G[c]) {
                if (d[next] <= d[c] + 1) continue;
                d[next] = d[c] + 1;
                Q.insert(next);
            }
        }
    }
    int[] fromR = new int[N];
    int[] fromF = new int[N];
    bfs([0], fromR);
    bfs(X, fromF);
    bool f() {
        foreach (v; 1 .. N) {
            if (G[v].length != 1) continue;
            if (fromR[v] < fromF[v]) return true;
        }
        return false;
    }
    writeln(f() ? "YES" : "NO");
}


import std.stdio, std.conv, std.functional, std.string;
import std.algorithm, std.array, std.container, std.range, std.typecons;
import std.bigint, std.numeric, std.math, std.random;
import core.bitop;

string FMT_F = "%.10f";

static File _f;
void file_io(string fn) { _f = File(fn, "r"); }
static string[] s_rd;
T _RD(T = long)() { while(!s_rd.length) s_rd = readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T _RD(T = long)(File f) { while(!s_rd.length) s_rd = f.readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T[] _RDA(T = long)(T fix = 0) { auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
T[] _RDA(T = long)(File f, T fix = 0) { auto r = f.readln.chomp.split.to!(T[]); r[] += fix; return r; }
T RD(T = long)() { if (_f.isOpen) return _RD!T(_f); else return _RD!T; }
T[] RDA(T = long)(T fix = 0) { if (_f.isOpen)  return _RDA!T(_f, fix); else return _RDA!T(fix); }

size_t[] MAKE_IDX(alias less = "a < b", Range)(Range range) { auto idx = new size_t[](range.length); makeIndex!(less)(range, idx); return idx;}
size_t MIN_POS(alias less = "a < b", Range)(Range range) { auto r = minPos!(less)(range); return range.length - r.length; }

void chmin(T)(ref T x, T y) { x = min(x, y); } void chmax(T)(ref T x, T y) { x = max(x, y); }
bool inside(T)(T x, T b, T e) { return x >= b && x < e; }
T lcm(T)(T x, T y) { return x * (y / gcd(x, y)); }

long mod = 10^^9 + 7;
//long mod = 998_244_353;
//long mod = 1_000_003;
void moda(T)(ref T x, T y) { x = (x + y) % mod; }
void mods(T)(ref T x, T y) { x = ((x + mod) - (y % mod)) % mod; }
void modm(T)(ref T x, T y) { x = (x * y) % mod; }
void modpow(T)(ref T x, T y) { if (!y) { x = 1; return; } auto t = x; x.modpow(y>>1); x.modm(x); if (y&1) x.modm(t); }
void modd(T)(ref T x, T y) { y.modpow(mod - 2); x.modm(y); }

void main()
{
	auto t = RD!int;
	auto ans = new int[][](t);
	foreach (ti; 0..t)
	{
		auto l = RD!int;
		auto r = RD!int;

		if (l*2 > r)
			ans[ti] = [-1, -1];
		else
			ans[ti] = [l, l*2];
	}

	foreach (e; ans)
	{
		writeln(e[0], " ", e[1]);
	}
	stdout.flush;
	debug readln;
}

import std.algorithm;
import std.conv;
import std.range;
import std.stdio;
import std.string;

void main ()
{
	auto tests = readln.strip.to !(int);
	foreach (test; 0..tests)
	{
		int a, b;
		readf !(" %s %s") (a, b);
		if (a * 2 <= b)
		{
			writeln (a, " ", a * 2);
		}
		else
		{
			writeln (-1, " ", -1);
		}
	}
}


// Vicfred
// https://codeforces.com/contest/1426/problem/B
// greedy
import std.stdio;

void main() {
    int t;
    readf("%s\n", &t);

    int n, m;
    int a, b, c, d;
    while(t--) {
        readf("%s %s\n", &n, &m);
        bool found = false;
        for(int i = 0; i < n; ++i) {
            readf("%s %s\n%s %s\n", &a, &b, &c, &d);
            if(b == c)
                found = true;
        }
        if(m%2 == 1)
            found = false;
        if(found)
            "YES".writeln;
        else
            "NO".writeln;
    }
}

// Cheese-Cracker: cheese-cracker.github.io
import std.stdio, std.conv, std.functional, std.string, std.algorithm;
import std.container, std.range, std.typecons, std.numeric, std.math, std.random;

alias ll = long;
alias rbt = redBlackTree;
alias tup = Tuple!(long, long);
static string[] inp;
T rd(T = long)(){while(!inp.length) inp = readln.chomp.split; string a = inp[0]; inp.popFront; return a.to!T;}
T[] rdarr(T = long)(T fix = 0){ auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
void show(A...)(A a) { debug{ foreach(t; a){ write(t, "| "); } writeln; } }
/*******************************It's a Me, Mario!*******************************************/

void play(){
    int n, m;
    n = rd!int;
    m = rd!int;
    bool sym = 0, sym2 = 0;
    ll a, b, c, d;
    foreach(i; 0..n){
        a = rd;
        b = rd;
        c = rd;
        d = rd;
        if(b == c){ sym = 1; }
    }
    if(sym && m % 2 == 0){
            writeln("YES");
    }else{
        writeln("NO");
    }
}

int main(){
    long t = 1;
    t = rd;        // Toggle!
    while(t--) play();  // Let's play!
    stdout.flush;
    return 0;
}

// Cheese-Cracker: cheese-cracker.github.io
import std.stdio, std.conv, std.functional, std.string, std.algorithm;
import std.container, std.range, std.typecons, std.numeric, std.math, std.random;

alias ll = long;
alias rbt = redBlackTree;
alias tup = Tuple!(long, long);
static string[] inp;
T rd(T = long)(){while(!inp.length) inp = readln.chomp.split; string a = inp[0]; inp.popFront; return a.to!T;}
T[] rdarr(T = long)(T fix = 0){ auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
void show(A...)(A a) { debug{ foreach(t; a){ write(t, "| "); } writeln; } }
/*******************************It's a Me, Mario!*******************************************/

void play(){
    int n, m;
    n = rd!int;
    m = rd!int;
    bool sym = 0, sym2 = 0;
    ll a, b, c, d;
    foreach(i; 0..n){
        a = rd;
        b = rd;
        c = rd;
        d = rd;
        if(b == c){ sym = 1; }
        if(a == d && b == c){ sym2 = 1; }
    }
    if(sym && m % 2 == 0){
        if(m == 2 && !sym2){
            writeln("NO");
        }else{
            writeln("YES");
        }
    }else{
        writeln("NO");
    }
}

int main(){
    long t = 1;
    t = rd;        // Toggle!
    while(t--) play();  // Let's play!
    stdout.flush;
    return 0;
}

// Cheese-Cracker: cheese-cracker.github.io
import std.stdio, std.conv, std.functional, std.string, std.algorithm;
import std.container, std.range, std.typecons, std.numeric, std.math, std.random;

alias ll = long;
alias rbt = redBlackTree;
alias tup = Tuple!(long, long);
static string[] inp;
T rd(T = long)(){while(!inp.length) inp = readln.chomp.split; string a = inp[0]; inp.popFront; return a.to!T;}
T[] rdarr(T = long)(T fix = 0){ auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
void show(A...)(A a) { debug{ foreach(t; a){ write(t, "| "); } writeln; } }
/*******************************It's a Me, Mario!*******************************************/

void play(){
    int n, m;
    n = rd!int;
    m = rd!int;
    bool sym = 0, sym2 = 0;
    ll a, b, c, d;
    foreach(i; 0..n){
        a = rd;
        b = rd;
        c = rd;
        d = rd;
        if(a == d){ sym = 1; }
        if(a == d && b == c){ sym2 = 1; }
    }
    if(sym && m % 2 == 0){
        if(m == 2 && !sym2){
            writeln("NO");
        }else{
            writeln("YES");
        }
    }else{
        writeln("NO");
    }
}

int main(){
    long t = 1;
    t = rd;        // Toggle!
    while(t--) play();  // Let's play!
    stdout.flush;
    return 0;
}


import std.algorithm;
import std.conv;
import std.range;
import std.stdio;
import std.string;

void main ()
{
	auto tests = readln.strip.to !(int);
	foreach (test; 0..tests)
	{
		auto n = readln.strip.to !(int);
		auto a = readln.splitter.map !(to !(int)).array;
		sort (a.stride (2));
		sort (a.drop (1).stride (2));
		writeln (a.isSorted ? "YES" : "NO");
	}
}

import std.stdio, std.conv, std.functional, std.string;
import std.algorithm, std.array, std.container, std.range, std.typecons;
import std.bigint, std.numeric, std.math, std.random;
import core.bitop;

string FMT_F = "%.10f";

static File _f;
void file_io(string fn) { _f = File(fn, "r"); }
static string[] s_rd;
T _RD(T = long)() { while(!s_rd.length) s_rd = readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T _RD(T = long)(File f) { while(!s_rd.length) s_rd = f.readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T[] _RDA(T = long)(T fix = 0) { auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
T[] _RDA(T = long)(File f, T fix = 0) { auto r = f.readln.chomp.split.to!(T[]); r[] += fix; return r; }
T RD(T = long)() { if (_f.isOpen) return _RD!T(_f); else return _RD!T; }
T[] RDA(T = long)(T fix = 0) { if (_f.isOpen)  return _RDA!T(_f, fix); else return _RDA!T(fix); }

size_t[] MAKE_IDX(alias less = "a < b", Range)(Range range) { auto idx = new size_t[](range.length); makeIndex!(less)(range, idx); return idx;}
size_t MIN_POS(alias less = "a < b", Range)(Range range) { auto r = minPos!(less)(range); return range.length - r.length; }

void chmin(T)(ref T x, T y) { x = min(x, y); } void chmax(T)(ref T x, T y) { x = max(x, y); }
bool inside(T)(T x, T b, T e) { return x >= b && x < e; }
T lcm(T)(T x, T y) { return x * (y / gcd(x, y)); }
double[] rotate(double[] vec, double rad) { return [cos(rad)*vec[0] - sin(rad)*vec[1], sin(rad)*vec[0] + cos(rad)*vec[1]]; }

long mod = 10^^9 + 7;
//long mod = 998_244_353;
//long mod = 1_000_003;
void moda(ref long x, long y) { x = (x + y) % mod; }
void mods(ref long x, long y) { x = ((x + mod) - (y % mod)) % mod; }
void modm(ref long x, long y) { x = (x * y) % mod; }
void modpow(ref long x, long y) { if (!y) { x = 1; return; } auto t = x; x.modpow(y>>1); x.modm(x); if (y&1) x.modm(t); }
void modd(ref long x, long y) { y.modpow(mod - 2); x.modm(y); }

void main()
{
	auto t = RD!int;
	auto ans = new bool[](t);
	foreach (ti; 0..t)
	{
		auto n = RD!int;
		auto a = RDA;

		long[][long] cnt;
		foreach (e; a)
			cnt[e] = [0, 0];

		auto index = a.MAKE_IDX;
		foreach (ii, i; index)
		{
			auto j = ii % 2;
			++cnt[a[i]][j];
		}

		ans[ti] = true;
		foreach (i; 0..n)
		{
			auto j = i % 2;
			if (cnt[a[i]][j] == 0)
			{
				ans[ti] = false;
				break;
			}
			else
				--cnt[a[i]][j];
		}
	}

	foreach (e; ans)
	{
		writeln(e ? "YES" : "NO");
	}
	stdout.flush;
	debug readln;
}

// code by cutx64

module main;

import std.string, std.array, std.container, std.typecons;
import std.stdio, std.format, std.file, std.outbuffer;
import std.algorithm, std.conv, std.functional, std.range, core.bitop;
// import std.bigint, std.complex, std.bitmanip;
import std.math, std.mathspecial, std.numeric;

void main() {

  int tests; readf!"%s\n"(tests);
  while(tests--) {
    immutable(int) Maxn = 10 ^^ 5 + 5;
    int n; readf!"%s\n"(n);
    auto a = readln.splitter.map!(to!int).array;
    auto b = a.dup.sort;
    int[Maxn][2] c;
    foreach(i; 0 .. n) {
      c[i % 2][b[i]]++;
    }
    bool ok = true;
    foreach(i; 0 .. n) {
      if (c[i % 2][a[i]] == 0) {
        ok = false;
        break;
      }
      c[i % 2][a[i]]--;
    }
    writefln!"%s"(ok ? "YES" : "NO");
  }

} // main

import std.algorithm, std.array, std.container, std.conv, std.math, std.numeric, std.random, std.range, std.stdio, std.string, std.typecons, core.bitop;

void main()
{
  int t;
  readf!" %d "(t);
  while (t--) {
    int n, i, j, k;
    readf!" %d "(n);
    auto a = readln.strip.split.map!(to!int).array;
    auto b = zip(a, iota(0, n)).array.sort!((x, y) => x[0] < y[0]).array;
    bool good = true;
    i = 0;
    while (i < n) {
      j = i;
      while (j < n && b[i][0] == b[j][0])
        j++;
      int[2] tmp = [0, 0];
      for (k = i; k < j; k++) {
        tmp[k % 2] += abs(b[k][1] - k) % 2;
      }
      if (tmp[0] != tmp[1]) {
        good = false;
        break;
      }
      i = j;
    }
    writeln(good ? "YES" : "NO");
  }
}

import std.algorithm, std.array, std.container, std.conv, std.math, std.numeric, std.random, std.range, std.stdio, std.string, std.typecons, core.bitop;

void main()
{
  int t;
  readf!" %d "(t);
  while (t--) {
    int n, i, j, k;
    readf!" %d "(n);
    auto a = readln.strip.split.map!(to!int).array;
    auto b = zip(a, iota(0, n)).array.sort!((x, y) => x[0] < y[0]).array;
    bool good = true;
    i = 0;
    while (i < n) {
      if (abs(b[i][1] - i) % 2 != 0) {
        if (i + 1 < n && b[i][0] == b[i + 1][0] && abs(b[i + 1][1] - (i + 1)) % 2 != 0) {
          // L L pattern (we can change it to R R)
          swap(b[i], b[i + 1]);
          continue;
        } else if (i + 2 < n && b[i][0] == b[i + 2][0] && abs(b[i + 2][1] - (i + 2)) % 2 == 0) {
          // L R R pattern (we can change it to L L L)
          swap(b[i + 1], b[i + 2]);
          continue;
        } else {
          good = false;
          break;
        }
      }
      i++;
    }
    writeln(good ? "YES" : "NO");
  }
}

import std.algorithm, std.array, std.container, std.conv, std.math, std.numeric, std.random, std.range, std.stdio, std.string, std.typecons, core.bitop;

void main()
{
  int t;
  readf!" %d "(t);
  while (t--) {
    int n, i, j, k;
    readf!" %d "(n);
    auto a = readln.strip.split.map!(to!int).array;
    auto b = zip(a, iota(0, n)).array.sort!((x, y) => x[0] < y[0]).array;
    bool good = true;
    i = 0;
    while (i < n) {
      if (abs(b[i][1] - i) % 2 != 0) {
        if (i + 1 < n && b[i][0] == b[i + 1][0] && abs(b[i + 1][1] - (i + 1)) % 2 != 0)
          i++;
        else
          good = false;
      }
      i++;
    }
    writeln(good ? "YES" : "NO");
  }
}

import std.algorithm, std.array, std.container, std.conv, std.math, std.numeric, std.random, std.range, std.stdio, std.string, std.typecons, core.bitop;

void main()
{
  int t;
  readf!" %d "(t);
  while (t--) {
    int n, i, j, k;
    readf!" %d "(n);
    auto a = readln.strip.split.map!(to!int).array;
    auto b = zip(a, iota(0, n)).array.sort!((x, y) => x[0] < y[0]).array;
    bool good = true;
    i = 0;
    while (i < n) {
      if (abs(b[i][1] - i) % 2 != 0) {
        if (i + 1 < n && b[i][0] == b[i + 1][0] && abs(b[i + 1][1] - (i + i)) % 2 != 0)
          i++;
        else
          good = false;
      }
      i++;
    }
    writeln(good ? "YES" : "NO");
  }
}

import std.algorithm, std.array, std.container, std.conv, std.math, std.numeric, std.random, std.range, std.stdio, std.string, std.typecons, core.bitop;

void main()
{
  int t;
  readf!" %d "(t);
  while (t--) {
    int n, i, j, k;
    readf!" %d "(n);
    auto a = readln.strip.split.map!(to!int).array;
    auto b = zip(a, iota(0, n)).array.sort!((x, y) => x[0] < y[0]).array;
    bool good = true;
    i = 0;
    while (i < n) {
      j = i;
      while (j < n && b[i][0] == b[j][0])
        j++;
      int tmp = 0;
      for (k = i; k < j; k++) {
        tmp += abs(b[k][1] - k) % 2;
      }
      if (tmp % 2 != 0) {
        good = false;
        break;
      }
      i = j;
    }
    writeln(good ? "YES" : "NO");
  }
}


import std.algorithm;
import std.conv;
import std.range;
import std.stdio;
import std.string;

immutable long infinity = long.max / 4;

void main ()
{
	int n;
	long r1, r2, r3, d;
	while (readf !(" %s %s %s %s %s") (n, r1, r2, r3, d) > 0)
	{
		readln;
		auto a = readln.splitter.map !(to !(long)).array;
		auto b = a.map !(x => r1 * x + r3).array;
		debug {writeln (b);}
		auto c = a.map !(x => min (r1 * (x + 1), r2) + r1).array;
		debug {writeln (c);}
		auto e = new long [n];
		foreach (i; 0..n)
		{
			e[i] = min (b[i], c[i]);
		}
		debug {writeln (e);}

		auto f = [0L];
		foreach (i; 0..n)
		{
			auto cur = f[i] + b[i] + d;
			if (i > 0)
			{
				cur = min (cur, f[i - 1] +
				    e[i - 1] + e[i] + d * 4);
			}
			if (i > 1)
			{
				cur = min (cur, f[i - 2] +
				    e[i - 2] + e[i - 1] + e[i] + d * 7);
			}
			f ~= cur;
		}
		debug {writeln (f);}

		long res = min (f[n] - d,
		    f[n - 2] + e[n - 2] + b[n - 1] + d * 2);

		writeln (res);
	}
}

import std.algorithm, std.conv, std.range, std.stdio;
void main () {
	int n;
	long r1, r2, r3, d;
	while (readf !(" %s %s %s %s %s") (n, r1, r2, r3, d) > 0) {
		readln;
		auto a = readln.splitter.map !(to !(long)).array;
		auto b = a.map !(x => r1 * x + r3).array;
		auto c = a.map !(x => min (r1 * (x + 1), r2) + r1).array;
		auto e = n.iota.map !(i => min (b[i], c[i])).array;
		auto f = [0L];
		foreach (i; 0..n) {
			auto cur = f[i] + b[i] + d;
			if (i > 0) cur = min (cur, f[i - 1] + e[i - 1] + e[i] + d * 4);
			if (i > 1) cur = min (cur, f[i - 2] + e[i - 2] + e[i - 1] + e[i] + d * 7);
			f ~= cur;
		}
		writeln (min (f[n] - d, f[n - 2] + e[n - 2] + b[n - 1] + d * 2));
	}
}


import std.algorithm;
import std.array;
import std.conv;
import std.range;
import std.stdio;
import std.string;
import std.typecons;

void main ()
{
	int n;
	while (readf (" %s", &n) > 0)
	{
		readln;
		auto a = readln.split.map !(to !(int)).array;
		a = 0 ~ a ~ 0;
		auto p = readln.split.map !(to !(int)).array;

		auto r = new int [n + 2];
		r[] = -1;
		auto w = new long [n + 2];

		long [] ans;
		long cur = 0;

		int root (int v)
		{
			if (r[v] != -1 && r[v] != v)
			{
				r[v] = root (r[v]);
			}
			return r[v];
		}

		void unite (int q)
		{
			long temp = a[q];
			r[q] = q;
			int u = root (q - 1);
			if (u != -1)
			{
				r[u] = q;
				temp += w[u];
			}
			int v = root (q + 1);
			if (v != -1)
			{
				r[v] = q;
				temp += w[v];
			}
			w[q] = temp;
			cur = max (cur, temp);
		}

		foreach_reverse (q; p)
		{
			ans ~= cur;
			unite (q);
		}
		writefln ("%(%s\n%)", ans.retro);
	}
}

import core.bitop;
import core.checkedint;
import core.simd;
import core.stdc.stdio;
import core.stdc.stdlib;
import core.stdc.string;
import std.algorithm;
import std.array;
import std.ascii;
import std.bigint;
import std.bitmanip;
import std.complex;
import std.container;
import std.conv;
import std.datetime;
import std.format;
import std.functional;
import std.math;
import std.meta;
import std.numeric;
import std.random;
import std.range;
import std.regex;
//import std.stdio;
import std.string;
import std.typecons;
import std.variant;

__gshared:

alias BitSet(size_t n) = size_t[(n + size_t.sizeof * 8 - 1) / (size_t.sizeof * 8)];

auto getAddrTuple() {
    return tuple();
}

auto getAddrTuple(T, U...)(ref T head, ref U tail) {
    return tuple(&head, getAddrTuple(tail).expand);
}

bool read(T...)(ref T vars) if (vars.length > 0) {
    return readf(' ' ~ replicate("%s ", vars.length), getAddrTuple(vars).expand) == vars.length;
}

T[ ] allocate(T)(size_t n) {
    return (cast(T*)malloc(n * T.sizeof))[0 .. n];
}

auto pairwise(R)(R range) if (isForwardRange!R) {
    return lockstep(range, dropOne(range));
}

struct Node {
    private {
        mixin(bitfields!(
            uint, `index`,   31,
            bool, `delayed`, 1,
        ));
    }
    int size = 1;
    Splay left, right, parent;

    invariant {
        foreach (child; AliasSeq!(left, right))
            if (child !is null)
                assert(child.parent is &this);
        assert(size == left.size + right.size + 1);
    }

    void assign(int id) {
        index = id;
        delayed = true;
    }

    static void split(Splay t, ref Splay l, ref Splay r, int x)
    in {
        assert(x <= t.size);
    }
    out {
        assert(l.size == x);
    }
    body {
        if (x == t.size) {
            l = t;
            r = null;
        } else {
            r = t.splayByKey(x);
            l = r.left;
            l.unlink();
        }
    }

    static Splay merge(/+return+/ Splay l, /+return+/ Splay r)
    in {
        if (l !is null) {
            assert(l.parent is null);
            assert(l !is r);
        }
        if (r !is null)
            assert(r.parent is null);
    }
    out (result) {
        assert(result.parent is null);
    }
    body {
        if (l is null)
            return r;
        if (r is null)
            return l;
        auto t = r.splayLeft();
        l.link(L, t);
        return t;
    }

    Splay splayLeft() return
    out (result) {
        assert(result.parent is null);
        assert(result.left is null);
    }
    body {
        push();
        if (left !is null)
            return left.splayLeft();
        splay();
        return Splay(&this);
    }

    Splay splayByKey(int x) return
    in {
        assert(x < size);
    }
    out (result) {
        assert(result.left.size == x);
        assert(result.parent is null);
    }
    body {
        return _splayByKey(x);
    }

    private Splay _splayByKey(int x) return
    in {
        assert(x < size);
    }
    body {
        push();
        if (x == left.size) {
            splay();
            return Splay(&this);
        } else if (x < left.size)
            return left._splayByKey(x);
        else
            return right._splayByKey(x - left.size - 1);
    }

    void splay()
    out {
        assert(parent is null);
    }
    body {
        while (true) {
            auto parent = parent;
            if (parent is null)
                return;
            if (parent.parent is null) {
                rotate();
                return;
            }
            if (side == parent.side)
                parent.rotate();
            else
                rotate();
            rotate();
        }
    }

    void rotate()
    in {
        assert(parent !is null);
    }
    body {
        auto parent = parent;
        auto gparent = parent.parent;
        auto side = side;
        auto parentSide = gparent ? parent.side : 0;
        unlink();
        parent.unlink();
        if (side == L) {
            if (auto right = right) {
                right.unlink();
                right.link(L, parent);
            }
            parent.link(R, Splay(&this));
        } else {
            if (auto left = left) {
                left.unlink();
                left.link(R, parent);
            }
            parent.link(L, Splay(&this));
        }
        link(parentSide, gparent);
    }

private:
    void push()
    out {
        assert(!delayed);
    }
    body {
        if (!delayed)
            return;
        foreach (child; AliasSeq!(left, right))
            if (child !is null)
                child.assign(index);
        delayed = false;
    }

    void recalc() {
        size = left.size + right.size + 1;
    }

    enum { L, R }

    @property bool side() const
    in {
        assert(parent !is null);
    }
    body {
        return &this is parent.left ? L : R;
    }

    void link(int c, Splay newParent)
    in {
        assert(parent is null);
        if (newParent !is null)
            assert((c == L ? newParent.left : newParent.right) is null);
    }
    out {
        assert(parent is newParent);
    }
    body {
        if (newParent is null)
            return;
        parent = newParent;
        if (c == L)
            parent.left = &this;
        else
            parent.right = &this;
        parent.recalc();
    }

    void unlink()
    out {
        assert(parent is null);
    }
    body {
        if (parent is null)
            return;
        if (side == L)
            parent.left = null;
        else
            parent.right = null;
        parent.recalc();
        parent = null;
    }
}

struct Splay {
    Node* _node;

    alias _node this;

    @property int size() const { return _node ? _node.size : 0; }

    static Splay build(int n) {
        Splay t;
        foreach (ref node; _nodes[0 .. n])
            t = Node.merge(t, Splay(&node));
        return t;
    }

    int getIndex(int i) {
        this = splayByKey(i);
        return index;
    }

    void update(int i, int j, int value) {
        Splay prefix, suffix;
        Node.split(this, this, suffix, j);
        Node.split(this, prefix, this, i);
        if (_node !is null)
            assign(value);
        this = Node.merge(Node.merge(prefix, this), suffix);
    }
}

alias Interval = Tuple!(int, `left`, int, `right`);

int[10^^5] _arr;
long[10^^5 + 1] psum;
Interval[10^^5 + 1] intervals;
Node[10^^5] _nodes;

long getSum(int i, int j) {
    return psum[j] - psum[i];
}

void main() {
    int n;
    while (scanf("%d", &n) == 1) {
        auto arr = _arr[0 .. n];
        version (LocalProject)
            _nodes[ ] = Node.init;
        //psum[0] = 0;
        foreach (i, ref x; arr) {
            scanf("%d", &x);
            psum[i + 1] = psum[i] + x;
        }
        int intervalCount = 1;
        intervals[0] = Interval(0, n);
        auto intervalSums = redBlackTree!true(psum[n]);
        auto t = Splay.build(n);
        foreach (i; 0 .. n) {
            int x;
            scanf("%d", &x);
            x--;

            const id = t.getIndex(x);
            intervalSums.removeKey(getSum(intervals[id].left, intervals[id].right));
            intervals[intervalCount] = Interval(x + 1, intervals[id].right);
            intervals[id].right = x;
            intervalSums.insert(getSum(intervals[id].left, x));
            intervalSums.insert(getSum(x + 1, intervals[intervalCount].right));
            t.update(x + 1, intervals[intervalCount].right, intervalCount);
            intervalCount++;

            printf("%lld\n", intervalSums.back);
        }
        debug putchar('\n');
    }
}

import core.bitop;
import core.checkedint;
import core.simd;
import core.stdc.stdio;
import core.stdc.stdlib;
import core.stdc.string;
import std.algorithm;
import std.array;
import std.ascii;
import std.bigint;
import std.bitmanip;
import std.complex;
import std.container;
import std.conv;
import std.datetime;
import std.format;
import std.functional;
import std.math;
import std.meta;
import std.numeric;
import std.random;
import std.range;
import std.regex;
//import std.stdio;
import std.string;
import std.typecons;
import std.variant;

__gshared:

alias BitSet(size_t n) = size_t[(n + size_t.sizeof * 8 - 1) / (size_t.sizeof * 8)];

auto getAddrTuple() {
    return tuple();
}

auto getAddrTuple(T, U...)(ref T head, ref U tail) {
    return tuple(&head, getAddrTuple(tail).expand);
}

bool read(T...)(ref T vars) if (vars.length > 0) {
    return readf(' ' ~ replicate("%s ", vars.length), getAddrTuple(vars).expand) == vars.length;
}

T[ ] allocate(T)(size_t n) {
    return (cast(T*)malloc(n * T.sizeof))[0 .. n];
}

auto pairwise(R)(R range) if (isForwardRange!R) {
    return lockstep(range, dropOne(range));
}

struct Node {
    private {
        mixin(bitfields!(
            uint, `index`,   31,
            bool, `delayed`, 1,
        ));
    }
    int size = 1;
    Splay left, right, parent;

    invariant {
        foreach (child; AliasSeq!(left, right))
            if (child !is null)
                assert(child.parent is &this);
        assert(size == left.size + right.size + 1);
    }

    void assign(int id) {
        index = id;
        delayed = true;
    }

    static void split(Splay t, ref Splay l, ref Splay r, int x)
    in {
        assert(x <= t.size);
    }
    out {
        assert(l.size == x);
    }
    body {
        if (x == t.size) {
            l = t;
            r = null;
        } else {
            r = t.splayByKey(x);
            l = r.left;
            l.unlink();
        }
    }

    static Splay merge(/+return+/ Splay l, /+return+/ Splay r)
    in {
        if (l !is null) {
            assert(l.parent is null);
            assert(l !is r);
        }
        if (r !is null)
            assert(r.parent is null);
    }
    out (result) {
        assert(result.parent is null);
    }
    body {
        if (l is null)
            return r;
        if (r is null)
            return l;
        auto t = r.splayLeft();
        l.link(L, t);
        return t;
    }

    Splay splayLeft() return
    out (result) {
        assert(result.parent is null);
        assert(result.left is null);
    }
    body {
        push();
        if (left !is null)
            return left.splayLeft();
        splay();
        return Splay(&this);
    }

    Splay splayByKey(int x) return
    in {
        assert(x < size);
    }
    out (result) {
        assert(result.left.size == x);
        assert(result.parent is null);
    }
    body {
        return _splayByKey(x);
    }

    private Splay _splayByKey(int x) return
    in {
        assert(x < size);
    }
    body {
        push();
        if (x == left.size) {
            splay();
            return Splay(&this);
        } else if (x < left.size)
            return left._splayByKey(x);
        else
            return right._splayByKey(x - left.size - 1);
    }

    void splay()
    out {
        assert(parent is null);
    }
    body {
        while (true) {
            auto parent = parent;
            if (parent is null)
                return;
            if (parent.parent is null) {
                rotate();
                return;
            }
            if (side == parent.side)
                parent.rotate();
            else
                rotate();
            rotate();
        }
    }

    void rotate()
    in {
        assert(parent !is null);
    }
    body {
        auto parent = parent;
        auto gparent = parent.parent;
        auto side = side;
        auto parentSide = gparent ? parent.side : 0;
        unlink();
        parent.unlink();
        if (side == L) {
            if (auto right = right) {
                right.unlink();
                right.link(L, parent);
            }
            parent.link(R, Splay(&this));
        } else {
            if (auto left = left) {
                left.unlink();
                left.link(R, parent);
            }
            parent.link(L, Splay(&this));
        }
        link(parentSide, gparent);
    }

private:
    void push()
    out {
        assert(!delayed);
    }
    body {
        if (!delayed)
            return;
        foreach (child; AliasSeq!(left, right))
            if (child !is null)
                child.assign(index);
        delayed = false;
    }

    void recalc() {
        size = left.size + right.size + 1;
    }

    enum { L, R }

    @property bool side() const
    in {
        assert(parent !is null);
    }
    body {
        return &this is parent.left ? L : R;
    }

    void link(int c, Splay newParent)
    in {
        assert(parent is null);
        if (newParent !is null)
            assert((c == L ? newParent.left : newParent.right) is null);
    }
    out {
        assert(parent is newParent);
    }
    body {
        if (newParent is null)
            return;
        parent = newParent;
        if (c == L)
            parent.left = &this;
        else
            parent.right = &this;
        parent.recalc();
    }

    void unlink()
    out {
        assert(parent is null);
    }
    body {
        if (parent is null)
            return;
        if (side == L)
            parent.left = null;
        else
            parent.right = null;
        parent.recalc();
        parent = null;
    }
}

struct Splay {
    Node* _node;

    alias _node this;

    @property int size() const { return _node ? _node.size : 0; }

    static Splay build(int n) {
        Splay t;
        foreach (ref node; _nodes[0 .. n])
            t = Node.merge(t, Splay(&node));
        return t;
    }

    int getIndex(int i) {
        this = splayByKey(i);
        return index;
    }

    void update(int i, int j, int value) {
        Splay prefix, suffix;
        Node.split(this, this, suffix, j);
        Node.split(this, prefix, this, i);
        if (_node !is null)
            assign(value);
        this = Node.merge(Node.merge(prefix, this), suffix);
    }
}

alias Interval = Tuple!(int, `left`, int, `right`);

int[10^^5] _arr;
long[10^^5 + 1] psum;
Interval[10^^5 + 1] intervals;
Node[10^^5] _nodes;

long getSum(int i, int j) {
    return psum[j] - psum[i];
}

void main() {
    int n;
    while (scanf("%d", &n) == 1) {
        auto arr = _arr[0 .. n];
        version (LocalProject)
            _nodes[ ] = Node.init;
        //psum[0] = 0;
        foreach (i, ref x; arr) {
            scanf("%d", &x);
            psum[i + 1] = psum[i] + x;
        }
        int intervalCount = 1;
        intervals[0] = Interval(0, n);
        auto intervalSums = redBlackTree!true(psum[n]);
        auto t = Splay.build(n);
        foreach (i; 0 .. n) {
            int x;
            scanf("%d", &x);
            x--;
            int id = t.getIndex(x);
            intervalSums.removeKey(getSum(intervals[id].left, intervals[id].right));
            intervals[intervalCount] = Interval(x + 1, intervals[id].right);
            intervals[id].right = x;
            intervalSums.insert(getSum(intervals[id].left, x));
            intervalSums.insert(getSum(x + 1, intervals[intervalCount].right));
            t.update(x + 1, intervals[intervalCount].right, intervalCount);
            intervalCount++;
            printf("%d\n", intervalSums.back);
        }
        debug putchar('\n');
    }
}


import std.algorithm, std.conv, std.range, std.stdio, std.string;

void main ()
{
	readln;
	int m = readln.strip.to!int;
	auto c = (readln ~ readln).split.map !("1 - 1 / a.to!real").fold !"a * b" (1.0);
	writefln ("%.10f", c ? m / c - m : -1);
}

import std.stdio;

int main ()
{
	int n, m, i;
	double c = 1.0, x;
	scanf ("%d%d", &n, &m);
	for (i = 0; i < n * 2; i++)
	{
		scanf ("%lf", &x);
		c *= 1 - 1 / x;
	}
	printf ("%.10lf", c > 0 ? m / c - m : -1);
	return 0;
}

import std.algorithm, std.conv, std.stdio;

void main ()
{
	int n, m;
	readf (" %s %s ", n, m);
	auto c = (readln ~ readln)
	    .splitter
	    .map !(to!double)
	    .map !(x => 1 - 1 / x)
	    .fold !"a * b";
	writefln ("%.10f", c > 0 ? m / c - m : -1);
}

import std.algorithm;
import std.conv;
import std.range;
import std.stdio;
import std.string;

void main ()
{
	int n, m;
	while (readf (" %s %s", &n, &m) > 0)
	{
		readln;
		auto a = readln.splitter.map !(to !(int)).array;
		auto b = readln.splitter.map !(to !(int)).array;

		if (chain (a, b).any !(q{a == 1}))
		{
			writeln (-1);
			continue;
		}

		long res = 0;
		real lo = 0;
		real hi = 1E10;
		foreach (step; 0..200)
		{
			real me = (lo + hi) * 0.5;
			real cur = m + me;
			foreach (i; 0..n)
			{
				cur *= 1.0L - 1.0L / a[i];
				cur *= 1.0L - 1.0L / b[i];
			}
			if (cur >= m)
			{
				hi = me;
			}
			else
			{
				lo = me;
			}
		}
		writefln ("%.10f", lo);
	}
}

import std.algorithm, std.conv, std.stdio;

void main ()
{
	int n, m;
	readf !" %s %s " (n, m);
	auto c = (readln ~ readln)
	    .splitter
	    .map !(to!double)
	    .map !(x => 1 - 1 / x)
	    .fold !"a * b";
	writefln !"%.10f" (c > 0 ? m / c - m : -1);
}

import core.bitop;
import std.algorithm;
import std.array;
import std.bitmanip;
import std.container;
import std.conv;
import std.functional;
import std.math;
import std.numeric;
import std.range;
import std.stdio;
import std.string;
import std.typecons;
import std.range.interfaces;

void main()
{
    int n, m;
    readf("%s", &n);
    readln;
    readf("%s", &m);
    readln;

    auto r = () => readln.chomp.split.map!(to!int).array;
    auto a = r();
    auto b = r();

    int[] arr;
    foreach (e1, e2; lockstep(a, b)) {
        arr ~= e1;
        arr ~= e2;
    }

    double ans = 0, curm = m;
    foreach_reverse (e; arr) {
        if (e == 1) {
            writeln(-1);
            return;
        }

        debug { writeln(e, ' ', curm); }

        double curf = curm / (e - 1);
        ans += curf;
        curm += curf;
    }

    ans.writefln!("%.10f");
}

import std.stdio, std.array, std.string, std.conv, std.algorithm;
import std.typecons, std.range, std.random, std.math, std.container;
import std.numeric, std.bigint, core.bitop, std.bitmanip;

void main() {
    auto N = readln.chomp.to!int;
    auto M = readln.chomp.to!int;
    auto A = readln.split.map!(to!long).array;
    auto B = readln.split.map!(to!long).array;

    bool ok(real fuel) {
        foreach (i; 0..N-1) {
            real x = (M + fuel) / A[i];
            fuel -= x;
            if (fuel < 0) return false;
            x = (M + fuel) / B[i+1];
            fuel -= x;
            if (fuel < 0) return false;
        }
        real x = (M + fuel) / A[N-1];
        fuel -= x;
        if (fuel < 0) return false;
        x = (M + fuel) / B[0];
        fuel -= x;
        if (fuel < 0) return false;
        return true;
    }

    real hi = 10L^^10;
    real lo = 0;

    foreach (_; 0..100) {
        real mid = (hi + lo) / 2;
        (ok(mid) ? hi : lo) = mid;
    }

    if (hi > 10^^9+100)
        writeln(-1);
    else
        writefln("%.9f", hi);
}

import std.stdio, std.range, std.string, std.algorithm, std.conv;

void main() {
    int n; double m;
    readf("%d\n%f\n", &n, &m);
    double[] a = readln.strip.split.map!(to!double).array;
    double[] b = readln.strip.split.map!(to!double).array;
    bool check(double fuel) {
        foreach (p; zip(a, b)) {
            double now_a = p[0], now_b = p[1];
            fuel -= (m + fuel) / now_a;
            if (fuel < 0) return false;
            fuel -= (m + fuel) / now_b;
            if (fuel < 0) return false;
        }
        return true;
    }
    if (!check(1e10)) {
        writeln(-1);
        return;
    }
    double min_x = 0, max_x = 1e9;
    foreach (phase; 0..200) {
        double mid = (min_x + max_x) / 2;
        if (!check(mid)) min_x = mid;
        else max_x = mid;
    }
    writefln("%.20f", max_x);
}

import std.algorithm, std.conv, std.range, std.stdio;
void main () {
	readln;
	int m = readln.split[0].to!int;
	auto c = (readln ~ readln).split.map !("1 - 1 / a.to!real").fold!"a * b";
	writef ("%.9f", c ? m / c - m : -1);
}

import std.stdio;

int main ()
{
	int n, m, i;
	double c = 1.0, x;
	scanf ("%d%d", &n, &m);
	for (i = 0; i < n * 2; i++)
	{
		scanf ("%lf", &x);
		c *= 1 - 1 / x;
	}
	printf ("%.10lf\n", c > 0 ? m / c - m : -1);
	return 0;
}

import std.stdio;

int main ()
{
	int n, m, i;
	double c = 1.0, x;
	scanf ("%d%d", &n, &m);
	for (i = 0; i < n * 2; i++)
	{
		scanf ("%lf", &x);
		c *= 1 - 1 / x;
	}
	printf ("%.10f\n", c > 0 ? m / c - m : -1);
	return 0;
}

import std.algorithm, std.conv, std.range, std.stdio, std.string;

void main ()
{
	readln;
	int m = readln.strip.to!int;
	auto c = (readln ~ readln).split.map !("1 - 1 / a.to!real").fold !"a * b" (1.0);
	writeln (c ? m / c - m : -1);
}


import std.string, std.stdio, std.conv, std.algorithm, std.range, std.array;

void main()
{
    auto nm = readln.split.map!(to!int);
    auto n = nm[0], m = nm[1];
    auto flag = m.iota.map!(_ => readln.chomp).array;
    auto hasSameColorInRow = flag.map!(a=>a.all!(b=>b==a[0])).all!"a==true";
    auto hasAdjacentColorInColumn = n.iota.array.map!(i=>flag.transversal(i).chunkBy!"a==b".all!(a=>a.array.length==1)).fold!"a&&b"(true);
    writeln(!(hasSameColorInRow && hasAdjacentColorInColumn)?"NO":"YES");
}

import std.string, std.stdio, std.conv, std.algorithm, std.range, std.array;

void main()
{
    auto nm = readln.split.map!(to!int);
    auto n = nm[0], m = nm[1];
    auto flag = m.iota.map!(_ => readln.chomp).array;
    auto hasSameColorInRow = flag.map!(a=>a.all!(b=>b==a[0])).all!"a==true";
    auto hasAdjacentColorInColumn = true;
    foreach(i; 0..n)
        hasAdjacentColorInColumn = hasAdjacentColorInColumn &&  flag.transversal(i).array.chunkBy!"a==b".all!(a=>a.array.length==1);
    writeln(!(hasSameColorInRow && hasAdjacentColorInColumn)?"NO":"YES");
}


import std;
void main () {
	int n = readln.strip.to!int, r = n - (n % 3 != 1), c = 1;
	auto a = [[r, c]];
	foreach (i; 0..n) {
		r -= 1 + (i & 1);
		c += 1 + !(i & 1);
		if (r < 1 || c > n) break;
		a ~= [r, c];
	}
	writefln!"%s\n%(%(%s %)\n%)" (a.length, a);
}

import std.algorithm;
import std.conv;
import std.range;
import std.stdio;
import std.string;

void main ()
{
	int n;
	while (readf !(" %s") (n) > 0)
	{
		int [2] [] answer;
		int row = n - (n % 3 != 1);
		int col = 1;
		answer ~= [row, col];
		foreach (step; 0..n)
		{
			row -= 1 + (step & 1);
			col += 1 + !(step & 1);
			if (row < 1 || col > n)
			{
				break;
			}
			answer ~= [row, col];
		}
		writeln (answer.length);
		foreach (ref line; answer)
		{
			writefln !("%(%s %)") (line);
		}
	}
}

import std.conv, std.functional, std.range, std.stdio, std.string;
import std.algorithm, std.array, std.bigint, std.bitmanip, std.complex, std.container, std.math, std.mathspecial, std.numeric, std.regex, std.typecons;
import core.bitop;

class EOFException : Throwable { this() { super("EOF"); } }
string[] tokens;
string readToken() { for (; tokens.empty; ) { if (stdin.eof) { throw new EOFException; } tokens = readln.split; } auto token = tokens.front; tokens.popFront; return token; }
int readInt() { return readToken.to!int; }
long readLong() { return readToken.to!long; }
real readReal() { return readToken.to!real; }

bool chmin(T)(ref T t, in T f) { if (t > f) { t = f; return true; } else { return false; } }
bool chmax(T)(ref T t, in T f) { if (t < f) { t = f; return true; } else { return false; } }

int binarySearch(alias pred, T)(in T[] as) { int lo = -1, hi = cast(int)(as.length); for (; lo + 1 < hi; ) { const mid = (lo + hi) >> 1; (unaryFun!pred(as[mid]) ? hi : lo) = mid; } return hi; }
int lowerBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a >= val)); }
int upperBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a > val)); }

bool experiment(int N, int M) {
  bool found;
  void check(int[] zs) {
    auto a = new char[][](N, N);
    foreach (x; 0 .. N) foreach (y; 0 .. N) {
      a[x][y] = '?';
    }
    foreach (z; zs) {
      const x = z / N, y = z % N;
      foreach (xx; 0 .. N) foreach (yy; 0 .. N) {
        if (x == xx || y == yy || x - y == xx - yy) {
          a[xx][yy] = '.';
        }
      }
    }
    foreach (z; zs) {
      const x = z / N, y = z % N;
      a[x][y] = '#';
    }
    bool ok = true;
    foreach (x; 0 .. N) foreach (y; 0 .. N) {
      ok = ok && (a[x][y] != '?');
    }
    if (ok) {
      found = true;
      foreach (x; 0 .. N) {
        writeln(a[x]);
      }
      writeln;
      stdout.flush;
    }
  }
  void dfs(int[] zs) {
    if (zs.length == M) {
      check(zs);
    } else {
      foreach (z; (zs.empty ? 0 : (zs[$ - 1] + 1)) .. N^^2) {
        dfs(zs ~ z);
      }
    }
  }
  dfs([]);
  return found;
}

alias Pt = Tuple!(int, "x", int, "y");

Pt[] solve(int N) {
  Pt[] ans;
  const a = (N - 1) / 3;
  foreach (i; 0 .. a + 1) {
    ans ~= Pt(i, a - i);
  }
  foreach (i; 0 .. a) {
    ans ~= Pt(N - 1 - i, N - 1 - (a - 1 - i));
  }
  if (N % 3 == 0) {
    ans ~= Pt(N - 1 - a, N - 1 - a);
  }
  return ans;
}

void judge(int N, const(Pt[]) P) {
  foreach (p; P) {
    assert(0 <= p.x); assert(p.x < N);
    assert(0 <= p.y); assert(p.y < N);
  }
  foreach (x; 0 .. N) foreach (y; 0 .. N) {
    bool ok;
    foreach (p; P) {
      ok = ok || (x == p.x || y == p.y || x - y == p.x - p.y);
    }
    assert(ok);
  }
}

void main() {
  /*
  debug {
    foreach (n; 1 .. 9 + 1) {
      for (int m = 1; ; ++m) {
        const res = experiment(n, m);
        if (res) {
          stderr.writeln(n, ": ", m);
          stderr.flush;
          break;
        }
      }
    }
    return;
  }
  //*/

  debug {
    foreach (n; 1 .. 20 + 1) {
      const ans = solve(n);
      // writeln(n, ": ", ans.length, " ", ans);
      writeln(n, ": ", ans.length);
      judge(n, ans);
    }
  }

  try {
    for (; ; ) {
      const N = readInt;

      auto ans = solve(N);
      writeln(ans.length);
      foreach (p; ans) {
        writeln(p.x + 1, " ", p.y + 1);
      }
    }
  } catch (EOFException e) {
  }
}


import std.stdio, std.conv, std.functional, std.string;
import std.algorithm, std.array, std.container, std.range, std.typecons;
import std.bigint, std.numeric, std.math, std.random;
import core.bitop;

string FMT_F = "%.10f";

static File _f;
void file_io(string fn) { _f = File(fn, "r"); }
static string[] s_rd;
T _RD(T = long)() { while(!s_rd.length) s_rd = readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T _RD(T = long)(File f) { while(!s_rd.length) s_rd = f.readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T[] _RDA(T = long)(T fix = 0) { auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
T[] _RDA(T = long)(File f, T fix = 0) { auto r = f.readln.chomp.split.to!(T[]); r[] += fix; return r; }
T RD(T = long)() { if (_f.isOpen) return _RD!T(_f); else return _RD!T; }
T[] RDA(T = long)(T fix = 0) { if (_f.isOpen)  return _RDA!T(_f, fix); else return _RDA!T(fix); }

size_t[] MAKE_IDX(alias less = "a < b", Range)(Range range) { auto idx = new size_t[](range.length); makeIndex!(less)(range, idx); return idx;}
size_t MIN_POS(alias less = "a < b", Range)(Range range) { auto r = minPos!(less)(range); return range.length - r.length; }

void chmin(T)(ref T x, T y) { x = min(x, y); } void chmax(T)(ref T x, T y) { x = max(x, y); }
bool inside(T)(T x, T b, T e) { return x >= b && x < e; }
long lcm(long x, long y) { return x * (y / gcd(x, y)); }

long mod = 10^^9 + 7;
//long mod = 998244353;
//long mod = 1_000_003;
void moda(ref long x, long y) { x = (x + y) % mod; }
void mods(ref long x, long y) { x = ((x + mod) - (y % mod)) % mod; }
void modm(ref long x, long y) { x = (x * y) % mod; }

void main()
{
	auto n = RD!int;
	auto a = RDA!int;
	int[][] arr;
	int begin;
	foreach (i; 1..n)
	{
		if (a[i] <= a[i-1])
		{
			arr ~= [begin, i];
			begin = i;
		}
	}
	arr ~= [begin, n];

	if (arr.length == 1)
		writeln(n);
	else
	{
		int ans = arr[0][1] - arr[0][0];
		foreach (i; 1..arr.length)
		{
			auto len1 = arr[i-1][1] - arr[i-1][0];
			auto len2 = arr[i][1] - arr[i][0];
			ans.chmax(len2);
			if (len1 != 1 && len2 != 1)
			{
				{
					auto r = arr[i-1][1]-2;
					auto l = arr[i][0];
					if (a[r] < a[l])
						ans.chmax(len2 + len1 - 1);
				}
				{
					auto r = arr[i-1][1]-1;
					auto l = arr[i][0]+1;
					if (a[r] < a[l])
						ans.chmax(len2 + len1 - 1);
				}
			}
		}
		writeln(ans);
	}

	stdout.flush;
	debug readln;
}

import std.stdio, std.string;
import std.array, std.conv;
import std.algorithm;

int solve(int[] a)
{
    auto n = to!int(a.length);
    auto fdp = new int[n];
    auto bdp = new int[n];
    auto res = 0;
    foreach_reverse (i; 0 .. n)
    {
        fdp[i] = 1;
        if (i < n - 1 && a[i] < a[i + 1]) fdp[i] = fdp[i + 1] + 1;
        res = max(res, fdp[i]);
    }
    foreach (i; 0 .. n)
    {
        bdp[i] = 1;
        if (i > 0 && a[i - 1] < a[i]) bdp[i] = bdp[i - 1] + 1;
    }
    foreach (i; 1 .. n - 1)
    {
        if (a[i - 1] < a[i + 1]) res = max(res, bdp[i - 1] + fdp[i + 1]);
    }
    return res;
}

int main(string[] args)
{
    readln;
    auto a = map!(x => to!int(x))(readln.strip.split(" ")).array;
    auto ret = solve(a);
    writeln(ret);
    return 0;
}

import std.stdio, std.conv, std.string, std.array, std.range, std.algorithm, std.container;
import std.math, std.random, std.bigint, std.datetime, std.format;
void main(string[] args){ if(args.length > 1) if(args[1] == "-debug") DEBUG = 1; solve(); }
void log()(){ writeln(""); } void log(T, A ...)(T t, lazy A a){ if(DEBUG) write(t, " "), log(a); } bool DEBUG = 0;
string rstring(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }
T rtype(T)(){ return rstring.to!T; } alias rint = rtype!int, rlong = rtype!long, rreal = rtype!real;
T[] rtypes(T)(int n){ return n.iota.map!(i => rtype!T()).array; } alias rint = rtypes!int, rlong = rtypes!long, rreal = rtypes!real;
T[][] rtypess(T)(int n, int m){ return n.iota.map!(i => rtypes!T(m)).array; } alias rint = rtypess!int, rlong = rtypess!long, rreal = rtypess!real;
T chmin(T)(ref T x, T y){ if(x > y) x = y; return x; } T chmax(T)(ref T x, T y){ if(x < y) x = y; return x; }

// ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- //

void solve(){
	int n = rint;
	long[] as = rlong(n);

	int[] xs = new int[](n);
	int[] ys = new int[](n); // xs[i]: best using i without skip; ys[i]: best using i and skipped one before
	foreach(i; 0 .. n){
		xs[i] = 1, ys[i] = 0;
		if(i > 0 && as[i - 1] < as[i]) xs[i].chmax(xs[i - 1] + 1);
		if(i > 0 && as[i - 1] < as[i]) ys[i].chmax(ys[i - 1] + 1);
		if(i > 1 && as[i - 2] < as[i]) ys[i].chmax(xs[i - 2] + 1);
	}
	long ans;
	foreach(x; xs) ans.chmax(x);
	foreach(y; ys) ans.chmax(y);
	ans.writeln;
}

import std.algorithm;
import std.range;
import std.stdio;
import std.typecons;
import std.traits;
import std.array;
struct Input
{
  T next(T)()
  {
    import std.conv;
    return to!T(nextWord);
  }
  string nextWord()
  {
    if (_nextWords.empty)
	_nextWords.insertFront(readln().split);
    string word = _nextWords.front; _nextWords.removeFront;
    return word;
  }
  import std.container;
  DList!string _nextWords;
}
Input input;
void read(T...)(ref T args)
{
  import std.traits;
  static foreach(i; 0 .. T.length)
    static if(isArray!(T[i]) && !is(T[i] == string))
      foreach(ref e; args[i])
    	read(e);
    else static if(isTuple!(T[i]))
      static foreach(n; 0 .. T[i].Types.length)
	read(args[i][n]);
    else
      args[i] = input.next!(typeof(args[i]))();
}
auto itup(alias k, alias F)()
{
  alias T = Parameters!F;
  foreach(i; 0 .. k)
    {
      T t; get(t);
      F(t);
    }
}
alias get = read;
void wone(T)(T t, char end)
{
  static if(isArray!T && !is(T == string))
    {
      foreach(i; 0 .. t.length - 1)
	  write(t[i], ' ');
      write(t[$ - 1], end);
    }
  else
      write(t, end);
}
void wr(T...)(T t)
{
  static foreach(i; 0 .. T.length)
    static if(i + 1 < T.length)
      wone(t[i], ' ');
    else
      wone(t[i], '\n');
}
void ans(T...)(T t)
{
  import core.stdc.stdlib;
  wr(t);
  exit(0);
}
void main()
{
  int n; get(n);
  auto a = new int[n]; get(a);
  int[2][] ps;
  int i = 0;
  int res = 0;
  for(; i < n;)
    {
      int si = i, fi = i;
      while(fi + 1 < n && a[fi + 1] > a[fi])
	{
	  fi++;
	}
      ps ~= [si, fi];
      res = max(res, fi - si + 1);
      i = fi + 1;
    }
  for(int j = 1; j < ps.length; j++)
    {
      auto curr = ps[j];
      auto prev = ps[j - 1];
      int comb = 0;
      if (prev[0] < prev[1])
	{
	  if(a[prev[1] - 1] < a[curr[0]])
	    {
	      comb = max(comb, curr[1] - curr[0] + 1 + prev[1] - prev[0]);
	    }
	}
      if (curr[0] < curr[1])
	{
	  if(a[prev[1]] < a[curr[0] + 1])
	    {
	      comb = max(comb, curr[1] - curr[0] + prev[1] - prev[0] + 1);
	    }
	}
      res = max(res, comb);
    }
  ans(res);
}

import std.stdio, std.array, std.string, std.conv, std.algorithm;
import std.typecons, std.range, std.random, std.math, std.container;
import std.numeric, std.bigint, core.bitop;

immutable int INF = 1 << 29;

void main() {
    auto N = readln.chomp.to!int;
    auto A = readln.split.map!(to!int).array;

    auto dp = new int[][][](N, 2, 2);
    foreach (i; 0..N) foreach (j; 0..2) foreach (k; 0..2) dp[i][j][k] = j + k == 0 ? 1 : 0;
    dp[0][0][0] = 1;
    dp[0][1][1] = 0;

    foreach (i; 1..N) {
        if (A[i] > A[i-1]) {
            dp[i][0][0] = max(dp[i][0][0], dp[i-1][0][0] + 1);
            dp[i][1][0] = max(dp[i][1][0], dp[i-1][1][0] + 1);
        }
        if (i > 1 && A[i] > A[i-2]) {
            dp[i][1][0] = max(dp[i][1][0], dp[i-1][1][1] + 1);
        }
        dp[i][1][1] = max(dp[i][1][1], dp[i-1][0][0]);
    }

    int ans = 0;
    foreach (i; 0..N) foreach (j; 0..2) foreach (k; 0..2) ans = max(ans, dp[i][j][k]);
    ans.writeln;
}

import std.stdio, std.conv, std.functional, std.string;
import std.algorithm, std.array, std.container, std.range, std.typecons;
import std.bigint, std.numeric, std.math, std.random;
import core.bitop;

string FMT_F = "%.10f";

static File _f;
void file_io(string fn) { _f = File(fn, "r"); }
static string[] s_rd;
T _RD(T = long)() { while(!s_rd.length) s_rd = readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T _RD(T = long)(File f) { while(!s_rd.length) s_rd = f.readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T[] _RDA(T = long)(T fix = 0) { auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
T[] _RDA(T = long)(File f, T fix = 0) { auto r = f.readln.chomp.split.to!(T[]); r[] += fix; return r; }
T RD(T = long)() { if (_f.isOpen) return _RD!T(_f); else return _RD!T; }
T[] RDA(T = long)(T fix = 0) { if (_f.isOpen)  return _RDA!T(_f, fix); else return _RDA!T(fix); }

size_t[] MAKE_IDX(alias less = "a < b", Range)(Range range) { auto idx = new size_t[](range.length); makeIndex!(less)(range, idx); return idx;}
size_t MIN_POS(alias less = "a < b", Range)(Range range) { auto r = minPos!(less)(range); return range.length - r.length; }

void chmin(T)(ref T x, T y) { x = min(x, y); } void chmax(T)(ref T x, T y) { x = max(x, y); }
bool inside(T)(T x, T b, T e) { return x >= b && x < e; }
long lcm(long x, long y) { return x * (y / gcd(x, y)); }

long mod = 10^^9 + 7;
//long mod = 998244353;
//long mod = 1_000_003;
void moda(ref long x, long y) { x = (x + y) % mod; }
void mods(ref long x, long y) { x = ((x + mod) - (y % mod)) % mod; }
void modm(ref long x, long y) { x = (x * y) % mod; }

void main()
{
	auto n = RD!int;
	auto a = RDA!int;
	int l1, l2, ans = 1;
	int last;
	foreach (i; 1..n)
	{
		if (a[i] <= last)
		{
			auto len = i - l1 - 1;
			ans.chmax(len);
			l1 = l2;
			l2 = i;
			if (i < 2)
				last = a[i];
			else if (a[i] > a[i-2])
				last = a[i];
			else
				last = a[i-1];
		}
		else
			last = a[i];
	}
	ans.chmax(n - l1 - 1);
	ans.chmax(n - l2);

	writeln(ans);
	stdout.flush;
	debug readln;
}

import std.stdio, std.conv, std.functional, std.string;
import std.algorithm, std.array, std.container, std.range, std.typecons;
import std.bigint, std.numeric, std.math, std.random;
import core.bitop;

string FMT_F = "%.10f";

static File _f;
void file_io(string fn) { _f = File(fn, "r"); }
static string[] s_rd;
T _RD(T = long)() { while(!s_rd.length) s_rd = readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T _RD(T = long)(File f) { while(!s_rd.length) s_rd = f.readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T[] _RDA(T = long)(T fix = 0) { auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
T[] _RDA(T = long)(File f, T fix = 0) { auto r = f.readln.chomp.split.to!(T[]); r[] += fix; return r; }
T RD(T = long)() { if (_f.isOpen) return _RD!T(_f); else return _RD!T; }
T[] RDA(T = long)(T fix = 0) { if (_f.isOpen)  return _RDA!T(_f, fix); else return _RDA!T(fix); }

size_t[] MAKE_IDX(alias less = "a < b", Range)(Range range) { auto idx = new size_t[](range.length); makeIndex!(less)(range, idx); return idx;}
size_t MIN_POS(alias less = "a < b", Range)(Range range) { auto r = minPos!(less)(range); return range.length - r.length; }

void chmin(T)(ref T x, T y) { x = min(x, y); } void chmax(T)(ref T x, T y) { x = max(x, y); }
bool inside(T)(T x, T b, T e) { return x >= b && x < e; }
long lcm(long x, long y) { return x * (y / gcd(x, y)); }

long mod = 10^^9 + 7;
//long mod = 998244353;
//long mod = 1_000_003;
void moda(ref long x, long y) { x = (x + y) % mod; }
void mods(ref long x, long y) { x = ((x + mod) - (y % mod)) % mod; }
void modm(ref long x, long y) { x = (x * y) % mod; }

void main()
{
	auto n = RD!int;
	auto a = RDA!int;
	/*while (true)
	{
	auto n = uniform(5, 10);
	auto a = new int[](n);
	foreach (i; 0..n)
	{
		a[i] = uniform(1, 10);
	}
	writeln(n);
	writeln(a);*/
	long ans = 1;
	auto dp = new int[][][](n+1, 2, 2);
	foreach (i; 0..n)
	{
		if (a[i] <= dp[i][1][0])
		{
			ans.chmax(dp[i][1][1]);
			dp[i+1][0] = [a[i], 1];
		}
		else
			dp[i+1][1] = [a[i], dp[i][1][1]+1];

		if (a[i] <= dp[i][0][0])
		{
			if (dp[i][0][1] > dp[i+1][1][1])
				dp[i+1][1] = [a[i], dp[i][0][1]];
		}
		else
			dp[i+1][0] = [a[i], dp[i][0][1]+1];
	}
	ans.chmax(dp[n][0][1]);
	ans.chmax(dp[n][1][1]);

	writeln(ans);
	stdout.flush;
	//readln;
	//}
	debug readln;
}

import std.stdio, std.conv, std.functional, std.string;
import std.algorithm, std.array, std.container, std.range, std.typecons;
import std.bigint, std.numeric, std.math, std.random;
import core.bitop;

string FMT_F = "%.10f";

static File _f;
void file_io(string fn) { _f = File(fn, "r"); }
static string[] s_rd;
T _RD(T = long)() { while(!s_rd.length) s_rd = readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T _RD(T = long)(File f) { while(!s_rd.length) s_rd = f.readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T[] _RDA(T = long)(T fix = 0) { auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
T[] _RDA(T = long)(File f, T fix = 0) { auto r = f.readln.chomp.split.to!(T[]); r[] += fix; return r; }
T RD(T = long)() { if (_f.isOpen) return _RD!T(_f); else return _RD!T; }
T[] RDA(T = long)(T fix = 0) { if (_f.isOpen)  return _RDA!T(_f, fix); else return _RDA!T(fix); }

size_t[] MAKE_IDX(alias less = "a < b", Range)(Range range) { auto idx = new size_t[](range.length); makeIndex!(less)(range, idx); return idx;}
size_t MIN_POS(alias less = "a < b", Range)(Range range) { auto r = minPos!(less)(range); return range.length - r.length; }

void chmin(T)(ref T x, T y) { x = min(x, y); } void chmax(T)(ref T x, T y) { x = max(x, y); }
bool inside(T)(T x, T b, T e) { return x >= b && x < e; }
long lcm(long x, long y) { return x * (y / gcd(x, y)); }

long mod = 10^^9 + 7;
//long mod = 998244353;
//long mod = 1_000_003;
void moda(ref long x, long y) { x = (x + y) % mod; }
void mods(ref long x, long y) { x = ((x + mod) - (y % mod)) % mod; }
void modm(ref long x, long y) { x = (x * y) % mod; }

void main()
{
	auto n = RD!int;
	auto a = RDA!int;
	int l1, l2, ans = 1;
	foreach (i; 1..n)
	{
		if (a[i] <= a[i-1])
		{
			auto len = i - l1 - 1;
			ans.chmax(len);
			l1 = l2;
			l2 = i;
		}
	}
	ans.chmax(n - l1 - 1);
	ans.chmax(n - l2);

	writeln(ans);
	stdout.flush;
	debug readln;
}

import std.stdio, std.conv, std.functional, std.string;
import std.algorithm, std.array, std.container, std.range, std.typecons;
import std.bigint, std.numeric, std.math, std.random;
import core.bitop;

string FMT_F = "%.10f";

static File _f;
void file_io(string fn) { _f = File(fn, "r"); }
static string[] s_rd;
T _RD(T = long)() { while(!s_rd.length) s_rd = readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T _RD(T = long)(File f) { while(!s_rd.length) s_rd = f.readln.chomp.split; string res = s_rd[0]; s_rd.popFront; return res.to!T; }
T[] _RDA(T = long)(T fix = 0) { auto r = readln.chomp.split.to!(T[]); r[] += fix; return r; }
T[] _RDA(T = long)(File f, T fix = 0) { auto r = f.readln.chomp.split.to!(T[]); r[] += fix; return r; }
T RD(T = long)() { if (_f.isOpen) return _RD!T(_f); else return _RD!T; }
T[] RDA(T = long)(T fix = 0) { if (_f.isOpen)  return _RDA!T(_f, fix); else return _RDA!T(fix); }

size_t[] MAKE_IDX(alias less = "a < b", Range)(Range range) { auto idx = new size_t[](range.length); makeIndex!(less)(range, idx); return idx;}
size_t MIN_POS(alias less = "a < b", Range)(Range range) { auto r = minPos!(less)(range); return range.length - r.length; }

void chmin(T)(ref T x, T y) { x = min(x, y); } void chmax(T)(ref T x, T y) { x = max(x, y); }
bool inside(T)(T x, T b, T e) { return x >= b && x < e; }
long lcm(long x, long y) { return x * (y / gcd(x, y)); }

long mod = 10^^9 + 7;
//long mod = 998244353;
//long mod = 1_000_003;
void moda(ref long x, long y) { x = (x + y) % mod; }
void mods(ref long x, long y) { x = ((x + mod) - (y % mod)) % mod; }
void modm(ref long x, long y) { x = (x * y) % mod; }

void main()
{
	auto n = RD!int;
	auto a = RDA!int;
	int l1, l2, ans;
	foreach (i; 1..n)
	{
		if (a[i] <= a[i-1])
		{
			auto len = i - l1 - 1;
			ans.chmax(len);
			l1 = l2;
			l2 = i;
		}
	}
	ans.chmax(n - l1 - 1);
	ans.chmax(n - l2);

	writeln(ans);
	stdout.flush;
	debug readln;
}


// Code By H~$~C

module main;

import std.stdio, std.array, std.string, std.math, std.uni, std.format, std.bigint;
import std.algorithm, std.conv, std.container, std.range, std.functional;
import std.random, std.typecons;

immutable Maxn = 500005;

int n, k, m;
modint ans;
int[Maxn] l, r, x, prf, mx;
modint[Maxn] dp, pre;

void solve(in int testcase) {
  n.read, k.read, m.read;
  foreach(i; 0 .. m) {
    l[i].read, r[i].read, x[i].read;
  }
  ans = 1;
  foreach(b; 0 .. k) {
    debug{writefln!"b = %s"(b);}
    prf[] = 0;
    mx[] = 0;
    foreach(i; 0 .. m) {
      int cur = (x[i] >> b) & 1;
      if (cur == 1) {
        prf[l[i]]++;
        prf[r[i] + 1]--;
      }
      else {
        mx[r[i]] = max(mx[r[i]], l[i]);
      }
    }
    foreach(i; 1 .. n + 1) {
      mx[i] = max(mx[i], mx[i - 1]);
      prf[i] += prf[i - 1];
    }
    dp[] = modint(0L);
    dp[0] = 1;
    pre[0] = 1;
    debug{writefln!"i = %s, dp = %s, pre = %s"(0, dp[0].to!int, pre[0].to!int);}
    foreach(i; 1 .. n + 2) {
      debug{writefln!"i = %s"(i);}
      if (prf[i] > 0) {
        dp[i] = 0;
        pre[i] = pre[i - 1];
        continue;
      }
      debug{writefln!"mx[%s] = %s"(i - 1, mx[i - 1]);}
      dp[i] = pre[i - 1];
      if (mx[i - 1] != 0) {
        dp[i] -= pre[mx[i - 1] - 1];
      }
      pre[i] = pre[i - 1] + dp[i];
      debug{writefln!"dp = %s, pre = %s"(dp[i].to!int, pre[i].to!int);}
    }
    debug{writefln!"ans = %s"(dp[n + 1].to!int);}
    ans *= dp[n + 1];
  }
  ans.to!int.writeln;
}

// ************************************************************

T reader(T)() { return readToken().to!T; }
void read(T)(ref T t) { t = reader!T; }
T[] readarray(T)() { return readln.splitter.map!(to!T).array; }
void chmax(T)(ref T a, T b) { a = max(a, b); }
void chmin(T)(ref T a, T b) { a = min(a, b); }
alias less = (a, b) => a < b;
alias greater = (a, b) => a > b;
T min_element(T)(in T[] a) { return a.element!less; }
T max_element(T)(in T[] a) { return a.element!greater; }
alias unique = uniq;

// constant or some variables
immutable int inf = 0x3f3f3f3f;
immutable long lnf = 0x3f3f3f3f3f3f3f3f;
immutable typeof(null) NULL = null;
string[] _tokens;

// functions
T element(alias pred, T)(in T[] a) {
  int pos = 0;
  for (int i = 1; i < cast(int)(a.length); ++i)
    if (binaryFun!pred(a[i], a[pos])) pos = i;
  return a[pos];
}
string readToken() {
  for (; _tokens.empty; ) {
    if (stdin.eof) return "";
    _tokens = readln.split;
  }
  auto token = _tokens.front;
  _tokens.popFront;
  return token;
}
int binary_bearch(alias pred, T)(in T[] as) {
  int l = -1, h = cast(int)(as.length), mid;
  for (; l + 1 < h; ) {
    mid = (l + h) >> 1;
    (unaryFun!pred(as[mid]) ? h : l) = mid;
  }
  return h;
}
int lower_bound(alias pred = less, T)(in T[] as, T val) {
  return as.binary_bearch!(a => a == val || pred(val, a));
}
int upper_bound(alias pred = less, T)(in T[] as, T val) {
  return as.binary_bearch!(a => pred(val, a));
}
int countbit(T)(T x) {
  int res = 0;
  while (x) {
    res++;
    x &= x - 1;
  }
  return res;
}

void main(string[] args) {
  int tests = 1;
//  tests.read();
  foreach(test; 1 .. tests + 1) solve(test);
}

struct modular_int(uint M_) {
  alias M = M_;
  uint x;
  modular_int inv() const {
    uint a = M, b = x;
    long u = 0, v = 1;
    while (b) {
      uint t = a / b;
      a -= t * b; swap(a, b);
      u -= t * v; swap(u, v);
    }
    if (u < 0) u += M;
    return modular_int(u);
  }
  this(modular_int a) { x = a.x; }
  this(long a) { a %= M; if (a < 0) a += M; x = cast(int)a; }
  ref modular_int opAssign(long a) { return (this = modular_int(a)); }
  ref modular_int opOpAssign(string op)(modular_int a) {
    static if (op == "+") { x += a.x; if (x >= M) x -= M; }
    else static if (op == "-") { x -= a.x; if (x & (1U << 31)) x += M; }
    else static if (op == "*") { x = cast(uint)((cast(long)(x) * a.x) % M); }
    else static if (op == "/") { this *= a.inv(); }
    else static assert(false);
    return this;
  }
  ref modular_int opOpAssign(string op)(long a) {
    static if (op == "^^") {
      modular_int t2 = this, te = modular_int(1);
      if (a < 0) a = -a, t2 = t2.inv();
      for (long e = a; e; e >>= 1) {
        if (e & 1) te *= t2;
        t2 *= t2;
      }
      x = te.x;
      return this;
    }
    else return mixin("this " ~ op ~ "= modular_int(a)");
  }
  modular_int opUnary(string op)() const if (op == "-") {
    return modular_int(M - x);
  }
  modular_int opBinary(string op, T)(T a) const {
    return mixin("modular_int(this) " ~ op ~ "= a");
  }
  modular_int opBinaryRight(string op)(long a) const {
    return mixin("modular_int(a) " ~ op ~ "= this");
  }
  T to(T)() const {
    return x.to!T;
  }
}
alias modint = modular_int!998244353;

// Code By H~$~C

module main;

import std.stdio, std.array, std.string, std.math, std.uni, std.format, std.bigint;
import std.algorithm, std.conv, std.container, std.range, std.functional;
import std.random, std.typecons;

immutable Maxn = 500005;

int n, k, m;
modint ans;
int[Maxn] l, r, x, prf, mx;
modint[Maxn] dp, pre;

void solve(in int testcase) {
  n.read, k.read, m.read;
  foreach(i; 0 .. m) {
    l[i].read, r[i].read, x[i].read;
  }
  ans = 1;
  foreach(b; 0 .. k) {
    prf[] = 0;
    mx[] = 0;
    foreach(i; 0 .. m) {
      int cur = (x[i] >> b) & 1;
      if (cur == 1) {
        prf[l[i]]++;
        prf[r[i] + 1]--;
      }
      else {
        mx[r[i]] = max(mx[r[i]], l[i]);
      }
    }
    foreach(i; 1 .. n + 1) {
      mx[i] = max(mx[i], mx[i - 1]);
      prf[i] += prf[i - 1];
    }
    dp[] = modint(0L);
    dp[0] = 1;
    pre[0] = 1;
    foreach(i; 1 .. n + 2) {
      if (prf[i] > 0) {
        dp[i] = 0;
        pre[i] = pre[i - 1];
        continue;
      }
      dp[i] = pre[i - 1];
      if (mx[i - 1] != 0) {
        dp[i] -= pre[mx[i - 1] - 1];
      }
      pre[i] = pre[i - 1] + dp[i];
    }
    ans *= dp[n + 1];
  }
  ans.to!int.writeln;
}

// ************************************************************

T reader(T)() { return readToken().to!T; }
void read(T)(ref T t) { t = reader!T; }
T[] readarray(T)() { return readln.splitter.map!(to!T).array; }
void chmax(T)(ref T a, T b) { a = max(a, b); }
void chmin(T)(ref T a, T b) { a = min(a, b); }
alias less = (a, b) => a < b;
alias greater = (a, b) => a > b;
T min_element(T)(in T[] a) { return a.element!less; }
T max_element(T)(in T[] a) { return a.element!greater; }
alias unique = uniq;

// constant or some variables
immutable int inf = 0x3f3f3f3f;
immutable long lnf = 0x3f3f3f3f3f3f3f3f;
immutable typeof(null) NULL = null;
string[] _tokens;

// functions
T element(alias pred, T)(in T[] a) {
  int pos = 0;
  for (int i = 1; i < cast(int)(a.length); ++i)
    if (binaryFun!pred(a[i], a[pos])) pos = i;
  return a[pos];
}
string readToken() {
  for (; _tokens.empty; ) {
    if (stdin.eof) return "";
    _tokens = readln.split;
  }
  auto token = _tokens.front;
  _tokens.popFront;
  return token;
}
int binary_bearch(alias pred, T)(in T[] as) {
  int l = -1, h = cast(int)(as.length), mid;
  for (; l + 1 < h; ) {
    mid = (l + h) >> 1;
    (unaryFun!pred(as[mid]) ? h : l) = mid;
  }
  return h;
}
int lower_bound(alias pred = less, T)(in T[] as, T val) {
  return as.binary_bearch!(a => a == val || pred(val, a));
}
int upper_bound(alias pred = less, T)(in T[] as, T val) {
  return as.binary_bearch!(a => pred(val, a));
}
int countbit(T)(T x) {
  int res = 0;
  while (x) {
    res++;
    x &= x - 1;
  }
  return res;
}

void main(string[] args) {
  int tests = 1;
//  tests.read();
  foreach(test; 1 .. tests + 1) solve(test);
}

struct modular_int(uint M_) {
  alias M = M_;
  uint x;
  modular_int inv() const {
    uint a = M, b = x;
    long u = 0, v = 1;
    while (b) {
      uint t = a / b;
      a -= t * b; swap(a, b);
      u -= t * v; swap(u, v);
    }
    if (u < 0) u += M;
    return modular_int(u);
  }
  this(modular_int a) { x = a.x; }
  this(long a) { a %= M; if (a < 0) a += M; x = cast(int)a; }
  ref modular_int opAssign(long a) { return (this = modular_int(a)); }
  ref modular_int opOpAssign(string op)(modular_int a) {
    static if (op == "+") { x += a.x; if (x >= M) x -= M; }
    else static if (op == "-") { x -= a.x; if (x & (1U << 31)) x += M; }
    else static if (op == "*") { x = cast(uint)((cast(long)(x) * a.x) % M); }
    else static if (op == "/") { this *= a.inv(); }
    else static assert(false);
    return this;
  }
  ref modular_int opOpAssign(string op)(long a) {
    static if (op == "^^") {
      modular_int t2 = this, te = modular_int(1);
      if (a < 0) a = -a, t2 = t2.inv();
      for (long e = a; e; e >>= 1) {
        if (e & 1) te *= t2;
        t2 *= t2;
      }
      x = te.x;
      return this;
    }
    else return mixin("this " ~ op ~ "= modular_int(a)");
  }
  modular_int opUnary(string op)() const if (op == "-") {
    return modular_int(M - x);
  }
  modular_int opBinary(string op, T)(T a) const {
    return mixin("modular_int(this) " ~ op ~ "= a");
  }
  modular_int opBinaryRight(string op)(long a) const {
    return mixin("modular_int(a) " ~ op ~ "= this");
  }
  T to(T)() const {
    return x.to!T;
  }
}
alias modint = modular_int!998244353;


import std.conv, std.functional, std.range, std.stdio, std.string;
import std.algorithm, std.array, std.bigint, std.bitmanip, std.complex, std.container, std.math, std.numeric, std.regex, std.typecons;
import core.bitop;

class EOFException : Throwable { this() { super("EOF"); } }
string[] tokens;
string readToken() { for (; tokens.empty; ) { if (stdin.eof) { throw new EOFException; } tokens = readln.split; } auto token = tokens.front; tokens.popFront; return token; }
int readInt() { return readToken.to!int; }
long readLong() { return readToken.to!long; }
real readReal() { return readToken.to!real; }

bool chmin(T)(ref T t, in T f) { if (t > f) { t = f; return true; } else { return false; } }
bool chmax(T)(ref T t, in T f) { if (t < f) { t = f; return true; } else { return false; } }

int binarySearch(alias pred, T)(in T[] as) { int lo = -1, hi = cast(int)(as.length); for (; lo + 1 < hi; ) { const mid = (lo + hi) >> 1; (unaryFun!pred(as[mid]) ? hi : lo) = mid; } return hi; }
int lowerBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a >= val)); }
int upperBound(T)(in T[] as, T val) { return as.binarySearch!(a => (a > val)); }

enum INF = 10^^9;

int segN;
Tuple!(int, int)[] seg;

void update(int a, int val) {
  seg[a += segN][0] += val;
  for (; a >>= 1; ) {
    seg[a] = min(seg[a << 1], seg[a << 1 | 1]);
  }
}

void main() {
  try {
    for (; ; ) {
      const N = readInt();
      const M = readInt();
      auto A = new int[M];
      auto B = new int[M];
      foreach (i; 0 .. M) {
        A[i] = readInt() - 1;
        B[i] = readInt() - 1;
      }

      auto G = new int[][N];
      foreach (i; 0 .. M) {
        G[A[i]] ~= B[i];
        G[B[i]] ~= A[i];
      }

      for (segN = 1; segN < N; segN <<= 1) {}
      seg.length = segN << 1;
      seg[] = tuple(INF, -1);
      foreach (u; 0 .. N) {
        seg[segN + u] = tuple(0, u);
      }
      foreach_reverse (a; 1 .. segN) {
        seg[a] = min(seg[a << 1], seg[a << 1 | 1]);
      }

      int ans;
      foreach (h; 0 .. N) {
        const u = seg[1][1];
        debug {
          writeln("u = ", u);
        }
        if (seg[1][0] == h) {
          debug {
            writeln("  new comp");
          }
          ++ans;
        }
        update(u, INF);
        foreach (v; G[u]) {
          update(v, 1);
        }
      }
      --ans;
      writeln(ans);
    }
  } catch (EOFException e) {
  }
}

import std.algorithm;
import std.conv;
import std.range;
import std.stdio;
import std.string;

void main ()
{
	int n, m;
	while (readf (" %s %s", &n, &m) > 0)
	{
		auto adj = new bool [int] [n];
		foreach (j; 0..m)
		{
			int u, v;
			readf (" %s %s", &u, &v);
			u -= 1;
			v -= 1;
			adj[u][v] = true;
			adj[v][u] = true;
		}

		long res = -1;
		auto p = n.iota.array;
		int [] q;

		while (!p.empty)
		{
			if (q.empty)
			{
				int u = p[$ - 1];
				q ~= u;
				p.length -= 1;
				res += 1;
			}
			else
			{
				int v = q[0];
				q = q[1..$];
				q.assumeSafeAppend ();

				for (int i = 0; i < p.length; i++)
				{
					int u = p[i];
					if (u !in adj[v])
					{
						q ~= u;
						swap (p[i], p[$ - 1]);
						p.length -= 1;
						i -= 1;
					}
				}
			}
		}

		writeln (res);
	}
}