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)); }

struct ModInt(int M_) {
  import std.conv : to;
  alias M = M_;
  int x;
  this(ModInt a) { x = a.x; }
  this(long a) { x = cast(int)(a % M); if (x < 0) x += M; }
  ref ModInt opAssign(long a) { return (this = ModInt(a)); }
  ref ModInt opOpAssign(string op)(ModInt a) {
    static if (op == "+") { x += a.x; if (x >= M) x -= M; }
    else static if (op == "-") { x -= a.x; if (x < 0) x += M; }
    else static if (op == "*") { x = cast(int)((cast(long)(x) * a.x) % M); }
    else static if (op == "/") { this *= a.inv(); }
    else static assert(false);
    return this;
  }
  ref ModInt opOpAssign(string op)(long a) {
    static if (op == "^^") {
      if (a < 0) return (this = inv()^^(-a));
      ModInt t2 = this, te = ModInt(1);
      for (long e = a; e > 0; e >>= 1) {
        if (e & 1) te *= t2;
        t2 *= t2;
      }
      x = cast(int)(te.x);
      return this;
    } else return mixin("this " ~ op ~ "= ModInt(a)");
  }
  ModInt inv() const {
    int a = x, b = M, y = 1, z = 0, t;
    for (; ; ) {
      t = a / b; a -= t * b;
      if (a == 0) {
        assert(b == 1 || b == -1);
        return ModInt(b * z);
      }
      y -= t * z;
      t = b / a; b -= t * a;
      if (b == 0) {
        assert(a == 1 || a == -1);
        return ModInt(a * y);
      }
      z -= t * y;
    }
  }
  ModInt opUnary(string op: "-")() const { return ModInt(-x); }
  ModInt opBinary(string op, T)(T a) const {
    return mixin("ModInt(this) " ~ op ~ "= a");
  }
  ModInt opBinaryRight(string op)(long a) const {
    return mixin("ModInt(a) " ~ op ~ "= this");
  }
  bool opCast(T: bool)() const { return (x != 0); }
  string toString() const { return x.to!string; }
}

enum MO = 10^^9 + 7;
alias Mint = ModInt!MO;

enum LIM = 2020;
Mint[] inv, fac, invFac;
void prepare() {
  inv = new Mint[LIM];
  fac = new Mint[LIM];
  invFac = new Mint[LIM];
  inv[1] = 1;
  foreach (i; 2 .. LIM) {
    inv[i] = -(Mint.M / i) * inv[cast(size_t)(Mint.M % i)];
  }
  fac[0] = invFac[0] = 1;
  foreach (i; 1 .. LIM) {
    fac[i] = fac[i - 1] * i;
    invFac[i] = invFac[i - 1] * inv[i];
  }
}
Mint binom(long n, long k) {
  if (0 <= k && k <= n) {
    assert(n < LIM);
    return fac[cast(size_t)(n)] * invFac[cast(size_t)(k)] * invFac[cast(size_t)(n - k)];
  } else {
    return Mint(0);
  }
}

void main() {
  prepare;

  try {
    for (; ; ) {
      const M = readInt();
      const N = readInt();
      auto A = new string[M];
      foreach (i; 0 .. N) {
        A[i] = readToken();
      }

      auto bell = new Mint[M + 1];
      bell[0] = 1;
      foreach (i; 1 .. M + 1) {
        foreach (j; 0 .. i) {
          bell[i] += binom(i - 1, j) * bell[j];
        }
      }

      auto bs = new string[M];
      foreach (i; 0 .. N) {
        foreach (j; 0 .. M) {
          bs[j] ~= A[i][j];
        }
      }
      bs.sort;
      Mint ans = 1;
      foreach (grp; bs.group) {
        ans *= bell[grp[1]];
      }
      writeln(ans);
    }
  } catch (EOFException e) {
  }
}

/+ dub.sdl:
    name "E"
    dependency "dunkelheit" version=">=0.9.0"
+/

import std.stdio, std.algorithm, std.range, std.conv;
// import dkh.foundation, dkh.scanner;

// import dkh.datastructure.unionfind;

// import dkh.modint;
alias Mint = ModInt!(10^^9 + 7);

int main() {
    Scanner sc = new Scanner(stdin);
    scope(exit) sc.read!true;

    int n, m; // for hackeres: swapped(n, m)
    sc.read(n, m);
    bool[][] g = new bool[][](n, n);
    foreach (ph; 0..m) {
        string s;
        sc.read(s);
        foreach (i; 0..n) {
            foreach (j; i+1..n) {
                if (s[i] != s[j]) {
                    g[i][j] = true;
                }
            }
        }
    }

    auto uf = UnionFind(n);
    foreach (i; 0..n) {
        foreach (j; i+1..n) {
            if (g[i][j]) continue;
            uf.merge(i, j);
        }
    }

    auto fact = factTable!Mint(10000);
    auto iFac = invFactTable!Mint(10000);
    Mint C(int n, int k) {
        if (n < k || n < 0) return Mint(0);
        return fact[n] * iFac[k] * iFac[n-k];
    }

    Mint[] dp = new Mint[n+1];
    dp[0] = Mint(1);
    foreach (i; 1..n+1) {
        foreach (j; 0..i) {
            dp[i] += dp[i-(1+j)] * C(i-1, j);
        }
    }

    Mint ans = Mint(1);
    int[] ls;
    foreach (i; 0..n) {
        if (!uf.isLeader(i)) continue;
        auto l = uf.group(i).length.to!int;
        ls ~= l;
        ans *= dp[l];
    }
    writeln(ans);
    return 0;
}
/* IMPORT /Users/yosupo/Program/dunkelheit/source/dkh/container/stackpayload.d */
// module dkh.container.stackpayload;

struct StackPayload(T, size_t MINCAP = 4) if (MINCAP >= 1) {
    import core.exception : RangeError;

    private T* _data;
    private uint len, cap;

    @property bool empty() const { return len == 0; }
    @property size_t length() const { return len; }
    alias opDollar = length;

    inout(T)[] data() inout { return (_data) ? _data[0..len] : null; }

    ref inout(T) opIndex(size_t i) inout {
        version(assert) if (len <= i) throw new RangeError();
        return _data[i];
    }
    ref inout(T) front() inout { return this[0]; }
    ref inout(T) back() inout { return this[$-1]; }

    void reserve(size_t newCap) {
        import core.memory : GC;
        import core.stdc.string : memcpy;
        import std.conv : to;
        if (newCap <= cap) return;
        void* newData = GC.malloc(newCap * T.sizeof);
        cap = newCap.to!uint;
        if (len) memcpy(newData, _data, len * T.sizeof);
        _data = cast(T*)(newData);
    }
    void free() {
        import core.memory : GC;
        GC.free(_data);
    }

    void clear() {
        len = 0;
    }

    void insertBack(T item) {
        import std.algorithm : max;
        if (len == cap) reserve(max(cap * 2, MINCAP));
        _data[len++] = item;
    }
    alias opOpAssign(string op : "~") = insertBack;
    void removeBack() {
        assert(!empty, "StackPayload.removeBack: Stack is empty");
        len--;
    }
}

/* IMPORT /Users/yosupo/Program/dunkelheit/source/dkh/ldc/inline.d */
// module dkh.ldc.inline;

version(LDC) {
    pragma(LDC_inline_ir) R inlineIR(string s, R, P...)(P);
}
/* IMPORT /Users/yosupo/Program/dunkelheit/source/dkh/foundation.d */

// module dkh.foundation;

static if (__VERSION__ <= 2070) {
    /*
    Copied by https://github.com/dlang/phobos/blob/master/std/algorithm/iteration.d
    Copyright: Andrei Alexandrescu 2008-.
    License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
    */
    template fold(fun...) if (fun.length >= 1) {
        auto fold(R, S...)(R r, S seed) {
            import std.algorithm : reduce;
            static if (S.length < 2) {
                return reduce!fun(seed, r);
            } else {
                import std.typecons : tuple;
                return reduce!fun(tuple(seed), r);
            }
        }
    }

}
/* IMPORT /Users/yosupo/Program/dunkelheit/source/dkh/modint.d */
// module dkh.modint;

// import dkh.numeric.primitive;

struct ModInt(uint MD) if (MD < int.max) {
    import std.conv : to;
    uint v;
    this(int v) {this(long(v));}
    this(long v) {this.v = (v%MD+MD)%MD;}
    static auto normS(uint x) {return (x<MD)?x:x-MD;}
    static auto make(uint x) {ModInt m; m.v = x; return m;}

    auto opBinary(string op:"+")(ModInt r) const {return make(normS(v+r.v));}

    auto opBinary(string op:"-")(ModInt r) const {return make(normS(v+MD-r.v));}

    auto opBinary(string op:"*")(ModInt r) const {return make((ulong(v)*r.v%MD).to!uint);}

    auto opBinary(string op:"/")(ModInt r) const {return this*inv(r);}
    auto opOpAssign(string op)(ModInt r) {return mixin ("this=this"~op~"r");}

    static ModInt inv(ModInt x) {return ModInt(extGcd!int(x.v, MD)[0]);}
    string toString() const {return v.to!string;}
}

struct DModInt(string name) {
    import std.conv : to;
    static uint MD;
    uint v;
    this(int v) {this(long(v));}
    this(long v) {this.v = ((v%MD+MD)%MD).to!uint;}
    static auto normS(uint x) {return (x<MD)?x:x-MD;}
    static auto make(uint x) {DModInt m; m.MD = MD; m.v = x; return m;}

    auto opBinary(string op:"+")(DModInt r) const {return make(normS(v+r.v));}

    auto opBinary(string op:"-")(DModInt r) const {return make(normS(v+MD-r.v));}

    auto opBinary(string op:"*")(DModInt r) const {return make((ulong(v)*r.v%MD).to!uint);}

    auto opBinary(string op:"/")(DModInt r) const {return this*inv(r);}
    auto opOpAssign(string op)(DModInt r) {return mixin ("this=this"~op~"r");}

    static DModInt inv(DModInt x) {
        return DModInt(extGcd!int(x.v, MD)[0]);
    }
    string toString() {return v.to!string;}
}

template isModInt(T) {
    const isModInt =
        is(T : ModInt!MD, uint MD) || is(S : DModInt!S, string s);
}

T[] factTable(T)(size_t length) if (isModInt!T) {
    import std.range : take, recurrence;
    import std.array : array;
    return T(1).recurrence!((a, n) => a[n-1]*T(n)).take(length).array;
}

T[] invFactTable(T)(size_t length) if (isModInt!T) {
    import std.algorithm : map, reduce;
    import std.range : take, recurrence, iota;
    import std.array : array;
    auto res = new T[length];
    res[$-1] = T(1) / iota(1, length).map!T.reduce!"a*b";
    foreach_reverse (i, v; res[0..$-1]) {
        res[i] = res[i+1] * T(i+1);
    }
    return res;
}

T[] invTable(T)(size_t length) if (isModInt!T) {
    auto f = factTable!T(length);
    auto invf = invFactTable!T(length);
    auto res = new T[length];
    foreach (i; 1..length) {
        res[i] = invf[i] * f[i-1];
    }
    return res;
}

/* IMPORT /Users/yosupo/Program/dunkelheit/source/dkh/datastructure/unionfind.d */
// module dkh.datastructure.unionfind;

struct UnionFind {
    private int[] id;
    private int[][] groups;
    size_t count;

    this(size_t n) {
        import std.algorithm : map;
        import std.range : iota, array;
        import std.conv : to;
        int _n = n.to!int;
        id = _n.iota.array;
        groups = _n.iota.map!"[a]".array;
        count = n;
    }

    void merge(size_t a, size_t b) {
        import std.algorithm : swap, each;
        if (same(a, b)) return;
        count--;
        uint x = id[a], y = id[b];
        if (groups[x].length < groups[y].length) swap(x, y);
        groups[y].each!(a => id[a] = x);
        groups[x] ~= groups[y];
        groups[y] = [];
    }

    const(int[]) group(size_t i) const {
        return groups[id[i]];
    }

    bool isLeader(size_t i) const {
        return i == id[i];
    }

    bool same(size_t a, size_t b) const {
        return id[a] == id[b];
    }
}

/* IMPORT /Users/yosupo/Program/dunkelheit/source/dkh/scanner.d */
// module dkh.scanner;

// import dkh.container.stackpayload;

class Scanner {
    import std.stdio : File;
    import std.conv : to;
    import std.range : front, popFront, array, ElementType;
    import std.array : split;
    import std.traits : isSomeChar, isStaticArray, isArray;
    import std.algorithm : map;
    File f;
    this(File f) {
        this.f = f;
    }
    char[512] lineBuf;
    char[] line;
    private bool succW() {
        import std.range.primitives : empty, front, popFront;
        import std.ascii : isWhite;
        while (!line.empty && line.front.isWhite) {
            line.popFront;
        }
        return !line.empty;
    }
    private bool succ() {
        import std.range.primitives : empty, front, popFront;
        import std.ascii : isWhite;
        while (true) {
            while (!line.empty && line.front.isWhite) {
                line.popFront;
            }
            if (!line.empty) break;
            line = lineBuf[];
            f.readln(line);
            if (!line.length) return false;
        }
        return true;
    }

    private bool readSingle(T)(ref T x) {
        import std.algorithm : findSplitBefore;
        import std.string : strip;
        import std.conv : parse;
        if (!succ()) return false;
        static if (isArray!T) {
            alias E = ElementType!T;
            static if (isSomeChar!E) {

                auto r = line.findSplitBefore(" ");
                x = r[0].strip.dup;
                line = r[1];
            } else static if (isStaticArray!T) {
                foreach (i; 0..T.length) {
                    bool f = succW();
                    assert(f);
                    x[i] = line.parse!E;
                }
            } else {
                StackPayload!E buf;
                while (succW()) {
                    buf ~= line.parse!E;
                }
                x = buf.data;
            }
        } else {
            x = line.parse!T;
        }
        return true;
    }

    int unsafeRead(T, Args...)(ref T x, auto ref Args args) {
        if (!readSingle(x)) return 0;
        static if (args.length == 0) {
            return 1;
        } else {
            return 1 + read(args);
        }
    }
    void read(bool enforceEOF = false, T, Args...)(ref T x, auto ref Args args) {
        import std.exception;
        enforce(readSingle(x));
        static if (args.length == 0) {
            enforce(enforceEOF == false || !succ());
        } else {
            read!enforceEOF(args);
        }
    }
    void read(bool enforceEOF = false, Args...)(auto ref Args args) {
        import std.exception;
        static if (args.length == 0) {
            enforce(enforceEOF == false || !succ());
        } else {
            enforce(readSingle(args[0]));
            read!enforceEOF(args);
        }
    }
}

/* IMPORT /Users/yosupo/Program/dunkelheit/source/dkh/numeric/primitive.d */
// module dkh.numeric.primitive;

import std.traits;
import std.bigint;

Unqual!T pow(T, U)(T x, U n)
if (!isFloatingPoint!T && (isIntegral!U || is(U == BigInt))) {
    return pow(x, n, T(1));
}

Unqual!T pow(T, U, V)(T x, U n, V e)
if ((isIntegral!U || is(U == BigInt)) && is(Unqual!T == Unqual!V)) {
    Unqual!T b = x, v = e;
    Unqual!U m = n;
    while (m) {
        if (m & 1) v *= b;
        b *= b;
        m /= 2;
    }
    return v;
}

T powMod(T, U, V)(T x, U n, V md)
if (isIntegral!U || is(U == BigInt)) {
    T r = T(1);
    while (n) {
        if (n & 1) r = (r*x)%md;
        x = (x*x)%md;
        n >>= 1;
    }
    return r % md;
}

// import dkh.int128;

ulong ulongPowMod(U)(ulong x, U n, ulong md)
if (isIntegral!U || is(U == BigInt)) {
    x %= md;
    ulong r = 1;
    while (n) {
        if (n & 1) {
            r = mul128(r, x).mod128(md);
        }
        x = mul128(x, x).mod128(md);
        n >>= 1;
    }
    return r % md;
}

T lcm(T)(in T a, in T b) {
    import std.numeric : gcd;
    return a / gcd(a,b) * b;
}

T[3] extGcd(T)(in T a, in T b)
if (!isIntegral!T || isSigned!T)
{
    if (b==0) {
        return [T(1), T(0), a];
    } else {
        auto e = extGcd(b, a%b);
        return [e[1], e[0]-a/b*e[1], e[2]];
    }
}

/* IMPORT /Users/yosupo/Program/dunkelheit/source/dkh/int128.d */

// module dkh.int128;

version(LDC) {
//     import dkh.ldc.inline;
}

version(LDC) version(X86_64) {
    version = LDC_IR;
}

ulong[2] mul128(ulong a, ulong b) {
    ulong[2] res;
    version(LDC_IR) {
        ulong upper, lower;
        inlineIR!(`
            %r0 = zext i64 %0 to i128
            %r1 = zext i64 %1 to i128
            %r2 = mul i128 %r1, %r0
            %r3 = trunc i128 %r2 to i64
            %r4 = lshr i128 %r2, 64
            %r5 = trunc i128 %r4 to i64
            store i64 %r3, i64* %2
            store i64 %r5, i64* %3`, void)(a, b, &lower, &upper);
        return [lower, upper];
    } else version(D_InlineAsm_X86_64) {
        ulong upper, lower;
        asm {
            mov RAX, a;
            mul b;
            mov lower, RAX;
            mov upper, RDX;
        }
        return [lower, upper];
    } else {
        ulong B = 2UL^^32;
        ulong[2] a2 = [a % B, a / B];
        ulong[2] b2 = [b % B, b / B];
        ulong[4] c;
        foreach (i; 0..2) {
            foreach (j; 0..2) {
                c[i+j] += a2[i] * b2[j] % B;
                c[i+j+1] += a2[i] * b2[j] / B;
            }
        }
        foreach (i; 0..3) {
            c[i+1] += c[i] / B;
            c[i] %= B;
        }
        return [c[0] + c[1] * B, c[2] + c[3] * B];
    }
}

ulong div128(ulong[2] a, ulong b) {
    version(LDC_IR) {
        return inlineIR!(`
            %r0 = zext i64 %0 to i128
            %r1 = zext i64 %1 to i128
            %r2 = shl i128 %r1, 64
            %r3 = add i128 %r0, %r2
            %r4 = zext i64 %2 to i128
            %r5 = udiv i128 %r3, %r4
            %r6 = trunc i128 %r5 to i64
            ret i64 %r6`,ulong)(a[0], a[1], b);
    } else version(D_InlineAsm_X86_64) {
        ulong upper = a[1], lower = a[0];
        ulong res;
        asm {
            mov RDX, upper;
            mov RAX, lower;
            div b;
            mov res, RAX;
        }
        return res;
    } else {
        if (b == 1) return a[0];
        while (!(b & (1UL << 63))) {
            a[1] <<= 1;
            if (a[0] & (1UL << 63)) a[1] |= 1;
            a[0] <<= 1;
            b <<= 1;
        }
        ulong ans = 0;
        foreach (i; 0..64) {
            bool up = (a[1] & (1UL << 63)) != 0;
            a[1] <<= 1;
            if (a[0] & (1UL << 63)) a[1] |= 1;
            a[0] <<= 1;

            ans <<= 1;
            if (up || b <= a[1]) {
                a[1] -= b;
                ans++;
            }
        }
        return ans;
    }
}

ulong mod128(ulong[2] a, ulong b) {
    version(D_InlineAsm_X86_64) {
        ulong upper = a[1], lower = a[0];
        ulong res;
        asm {
            mov RDX, upper;
            mov RAX, lower;
            div b;
            mov res, RDX;
        }
        return res;
    } else {
        return a[0] - div128(a, b) * b;
    }
}

/*
This source code generated by dunkelheit and include dunkelheit's source code.
dunkelheit's Copyright: Copyright (c) 2016- Kohei Morita. (https://github.com/yosupo06/dunkelheit)
dunkelheit's License: MIT License(https://github.com/yosupo06/dunkelheit/blob/master/LICENSE.txt)
*/

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)); }

struct ModInt(int M_) {
  import std.conv : to;
  alias M = M_;
  int x;
  this(ModInt a) { x = a.x; }
  this(long a) { x = cast(int)(a % M); if (x < 0) x += M; }
  ref ModInt opAssign(long a) { return (this = ModInt(a)); }
  ref ModInt opOpAssign(string op)(ModInt a) {
    static if (op == "+") { x += a.x; if (x >= M) x -= M; }
    else static if (op == "-") { x -= a.x; if (x < 0) x += M; }
    else static if (op == "*") { x = cast(int)((cast(long)(x) * a.x) % M); }
    else static if (op == "/") { this *= a.inv(); }
    else static assert(false);
    return this;
  }
  ref ModInt opOpAssign(string op)(long a) {
    static if (op == "^^") {
      if (a < 0) return (this = inv()^^(-a));
      ModInt t2 = this, te = ModInt(1);
      for (long e = a; e > 0; e >>= 1) {
        if (e & 1) te *= t2;
        t2 *= t2;
      }
      x = cast(int)(te.x);
      return this;
    } else return mixin("this " ~ op ~ "= ModInt(a)");
  }
  ModInt inv() const {
    int a = x, b = M, y = 1, z = 0, t;
    for (; ; ) {
      t = a / b; a -= t * b;
      if (a == 0) {
        assert(b == 1 || b == -1);
        return ModInt(b * z);
      }
      y -= t * z;
      t = b / a; b -= t * a;
      if (b == 0) {
        assert(a == 1 || a == -1);
        return ModInt(a * y);
      }
      z -= t * y;
    }
  }
  ModInt opUnary(string op: "-")() const { return ModInt(-x); }
  ModInt opBinary(string op, T)(T a) const {
    return mixin("ModInt(this) " ~ op ~ "= a");
  }
  ModInt opBinaryRight(string op)(long a) const {
    return mixin("ModInt(a) " ~ op ~ "= this");
  }
  bool opCast(T: bool)() const { return (x != 0); }
  string toString() const { return x.to!string; }
}

enum MO = 10^^9 + 7;
alias Mint = ModInt!MO;

enum LIM = 2020;
Mint[] inv, fac, invFac;
void prepare() {
  inv = new Mint[LIM];
  fac = new Mint[LIM];
  invFac = new Mint[LIM];
  inv[1] = 1;
  foreach (i; 2 .. LIM) {
    inv[i] = -(Mint.M / i) * inv[cast(size_t)(Mint.M % i)];
  }
  fac[0] = invFac[0] = 1;
  foreach (i; 1 .. LIM) {
    fac[i] = fac[i - 1] * i;
    invFac[i] = invFac[i - 1] * inv[i];
  }
}
Mint binom(long n, long k) {
  if (0 <= k && k <= n) {
    assert(n < LIM);
    return fac[cast(size_t)(n)] * invFac[cast(size_t)(k)] * invFac[cast(size_t)(n - k)];
  } else {
    return Mint(0);
  }
}

void main() {
  prepare;

  try {
    for (; ; ) {
      const M = readInt();
      const N = readInt();
      auto A = new string[M];
      foreach (i; 0 .. N) {
        A[i] = readToken();
      }

      auto bell = new Mint[M + 1];
      bell[0] = 1;
      foreach (i; 1 .. M) {
        foreach (j; 0 .. i) {
          bell[i] += binom(i - 1, j) * bell[j];
        }
      }

      auto bs = new string[M];
      foreach (i; 0 .. N) {
        foreach (j; 0 .. M) {
          bs[j] ~= A[i][j];
        }
      }
      bs.sort;
      Mint ans = 1;
      foreach (grp; bs.group) {
        ans *= bell[grp[1]];
      }
      writeln(ans);
    }
  } catch (EOFException e) {
  }
}


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)); }

struct ModInt(int M_) {
  import std.conv : to;
  alias M = M_;
  int x;
  this(ModInt a) { x = a.x; }
  this(long a) { x = cast(int)(a % M); if (x < 0) x += M; }
  ref ModInt opAssign(long a) { return (this = ModInt(a)); }
  ref ModInt opOpAssign(string op)(ModInt a) {
    static if (op == "+") { x += a.x; if (x >= M) x -= M; }
    else static if (op == "-") { x -= a.x; if (x < 0) x += M; }
    else static if (op == "*") { x = cast(int)((cast(long)(x) * a.x) % M); }
    else static if (op == "/") { this *= a.inv(); }
    else static assert(false);
    return this;
  }
  ref ModInt opOpAssign(string op)(long a) {
    static if (op == "^^") {
      if (a < 0) return (this = inv()^^(-a));
      ModInt t2 = this, te = ModInt(1);
      for (long e = a; e > 0; e >>= 1) {
        if (e & 1) te *= t2;
        t2 *= t2;
      }
      x = cast(int)(te.x);
      return this;
    } else return mixin("this " ~ op ~ "= ModInt(a)");
  }
  ModInt inv() const {
    int a = x, b = M, y = 1, z = 0, t;
    for (; ; ) {
      t = a / b; a -= t * b;
      if (a == 0) {
        assert(b == 1 || b == -1);
        return ModInt(b * z);
      }
      y -= t * z;
      t = b / a; b -= t * a;
      if (b == 0) {
        assert(a == 1 || a == -1);
        return ModInt(a * y);
      }
      z -= t * y;
    }
  }
  ModInt opUnary(string op: "-")() const { return ModInt(-x); }
  ModInt opBinary(string op, T)(T a) const {
    return mixin("ModInt(this) " ~ op ~ "= a");
  }
  ModInt opBinaryRight(string op)(long a) const {
    return mixin("ModInt(a) " ~ op ~ "= this");
  }
  bool opCast(T: bool)() const { return (x != 0); }
  string toString() const { return x.to!string; }
}

enum MO = 10^^9 + 7;
alias Mint = ModInt!MO;

int root(int[] uf, int u) {
  return (uf[u] < 0) ? u : (uf[u] = uf.root(uf[u]));
}
bool connect(int[] uf, int u, int v) {
  u = uf.root(u);
  v = uf.root(v);
  if (u == v) return false;
  if (uf[u] > uf[v]) swap(u, v);
  uf[u] += uf[v];
  uf[v] = u;
  return true;
}

void main() {
  try {
    for (; ; ) {
      const M = readInt();
      auto X = new int[M];
      auto Y = new int[M];
      foreach (i; 0 .. M) {
        X[i] = readInt();
        Y[i] = readInt();
      }

      const xs = X.dup.sort.uniq.array;
      const ys = Y.dup.sort.uniq.array;
      const xsLen = cast(int)(xs.length);
      const ysLen = cast(int)(ys.length);
      const V = xsLen + ysLen;

      auto uf = new int[V];
      uf[] = -1;
      foreach (i; 0 .. M) {
        const u = xs.lowerBound(X[i]);
        const v = xsLen + ys.lowerBound(Y[i]);
        uf.connect(u, v);
      }

      auto numEdges = new int[V];
      foreach (i; 0 .. M) {
        const u = xs.lowerBound(X[i]);
        ++numEdges[uf.root(u)];
      }

      Mint ans = 1;
      foreach (r; 0 .. V) {
        if (uf[r] < 0) {
          if (numEdges[r] == -uf[r] - 1) {
            ans *= (Mint(2)^^(-uf[r]) - 1);
          } else {
            ans *= Mint(2)^^(-uf[r]);
          }
        }
      }
      writeln(ans);
    }
  } catch (EOFException e) {
  }
}

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;

void main() {
    auto N = readln.chomp.to!int;
    auto P = N.iota.map!(_ => readln.split.map!(to!int).array).array;
    int[][int] R;
    int[][int] C;
    foreach (i; 0..N) {
        R[P[i][0]] ~= i;
        C[P[i][1]] ~= i;
    }
    bool[int] used_r;
    bool[int] used_c;
    int[][] groups;

    foreach (i; 0..N) {
        int r = P[i][0];
        int c = P[i][1];
        if ((r in used_r) || (c in used_c)) continue;
        int[] stack = [i];
        int[] group;
        while (!stack.empty) {
            int n = stack.back;
            stack.popBack;
            int nr = P[n][0];
            int nc = P[n][1];
            if (!(nr in used_r)) foreach (m; R[nr]) if (!(P[m][1] in used_c)) stack ~= m;
            used_r[nr] = true;
            if (!(nc in used_c)) foreach (m; C[nc]) if (!(P[m][0] in used_r)) stack ~= m;
            used_c[nc] = true;
            group ~= n;
        }
        groups ~= group.sort().uniq.array;
    }

    immutable long MOD = 10^^9 + 7;
    long ans = 1;

    foreach (g; groups) {
        int[] rows, cols;
        foreach (i; g) rows ~= P[i][0];
        foreach (i; g) cols ~= P[i][1];
        int r = rows.sort().uniq.array.length.to!int;
        int c = cols.sort().uniq.array.length.to!int;
        int n = r + c;
        int m = g.length.to!int;

        long tmp = 0;
        long comb = 1;
        foreach (i; 0..m+1) {
            tmp += comb;
            tmp %= MOD;
            comb = comb * (n - i) % MOD * powmod(i + 1, MOD - 2, MOD) % MOD;
        }
        ans = ans * tmp % MOD;
    }

    ans.writeln;
}

long powmod(long a, long x, long m) {
    long ret = 1;
    while (x) {
        if (x % 2) ret = ret * a % m;
        a = a * a % m;
        x /= 2;
    }
    return ret;
}

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;

void main() {
    auto N = readln.chomp.to!int;
    auto P = N.iota.map!(_ => readln.split.map!(to!int).array).array;
    int[][int] R;
    int[][int] C;
    foreach (i; 0..N) {
        R[P[i][0]] ~= i;
        C[P[i][1]] ~= i;
    }
    bool[int] used_r;
    bool[int] used_c;
    int[][] groups;

    immutable long MOD = 10^^9 + 7;
    long ans = 0;

    foreach (i; 0..N) {
        int r = P[i][0];
        int c = P[i][1];
        if ((r in used_r) || (c in used_c)) continue;
        int[] stack = [i];
        int[] group;
        while (!stack.empty) {
            int n = stack.back;
            stack.popBack;
            int nr = P[n][0];
            int nc = P[n][1];
            if (!(nr in used_r)) foreach (m; R[nr]) stack ~= m;
            if (!(nc in used_c)) foreach (m; C[nc]) stack ~= m;
            used_r[nr] = true;
            used_c[nc] = true;
            group ~= n;
        }
        groups ~= group.sort().uniq.array;
    }

    foreach (g; groups) {
        int[] rows, cols;
        foreach (i; g) rows ~= P[i][0];
        foreach (i; g) cols ~= P[i][1];
        int r = rows.sort().uniq.array.length.to!int;
        int c = cols.sort().uniq.array.length.to!int;
        int m = r + c;
        int n = g.length.to!int;

        long comb = 1;
        foreach (i; 0..m+1) {
            ans += comb;
            ans %= MOD;
            comb = comb * (n - i) % MOD * powmod(i + 1, MOD - 2, MOD);
        }
    }

    ans.writeln;
}

long powmod(long a, long x, long m) {
    long ret = 1;
    while (x) {
        if (x % 2) ret = ret * a % m;
        a = a * a % m;
        x /= 2;
    }
    return ret;
}

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;

void main() {
    auto N = readln.chomp.to!int;
    auto P = N.iota.map!(_ => readln.split.map!(to!int).array).array;
    int[][int] R;
    int[][int] C;
    foreach (i; 0..N) {
        R[P[i][0]] ~= i;
        C[P[i][1]] ~= i;
    }
    bool[int] used_r;
    bool[int] used_c;
    int[][] groups;

    foreach (i; 0..N) {
        int r = P[i][0];
        int c = P[i][1];
        if ((r in used_r) || (c in used_c)) continue;
        int[] stack = [i];
        int[] group;
        while (!stack.empty) {
            int n = stack.back;
            stack.popBack;
            int nr = P[n][0];
            int nc = P[n][1];
            if (!(nr in used_r)) foreach (m; R[nr]) stack ~= m;
            if (!(nc in used_c)) foreach (m; C[nc]) stack ~= m;
            used_r[nr] = true;
            used_c[nc] = true;
            group ~= n;
        }
        groups ~= group.sort().uniq.array;
    }

    immutable long MOD = 10^^9 + 7;
    long ans = 1;

    foreach (g; groups) {
        int[] rows, cols;
        foreach (i; g) rows ~= P[i][0];
        foreach (i; g) cols ~= P[i][1];
        int r = rows.sort().uniq.array.length.to!int;
        int c = cols.sort().uniq.array.length.to!int;
        int n = r + c;
        int m = g.length.to!int;

        long tmp = 0;
        long comb = 1;
        foreach (i; 0..m+1) {
            tmp += comb;
            tmp %= MOD;
            comb = comb * (n - i) % MOD * powmod(i + 1, MOD - 2, MOD);
        }
        ans = ans * tmp % MOD;
    }

    ans.writeln;
}

long powmod(long a, long x, long m) {
    long ret = 1;
    while (x) {
        if (x % 2) ret = ret * a % m;
        a = a * a % m;
        x /= 2;
    }
    return ret;
}


module _template;
import std.stdio;
import std.string;
import std.algorithm;
import std.container;
import std.range;
import std.math;
import std.numeric;
import std.conv;
import std.typecons;
import std.format;

struct IO {
        string read_string() {
                while (tokens.empty) {
                tokens = readln.split;
        }
        auto token = tokens.front;
                tokens.popFront;
                return token;
        }

        int read_int() {
                return read_string.to!int;
        }

        string[] tokens;
}

void main() {
        IO cin;
        int t = 1;
        // int t = cin.read_int;
        while (t--) {
                string s = cin.read_string;
                if (s[indexOf(s, '.') - 1] == '9') {
                        writeln("GOTO Vasilisa.");
                } else {
                        int loc_of_dot = indexOf(s, '.');
                        if (s[loc_of_dot + 1] < '5') {
                                for (int i = 0; i < loc_of_dot; i++) {
                                        write(s[i]);
                                }
                                writeln();
                        } else {
                                for (int i = 0; i < loc_of_dot - 1; i++) {
                                        write(s[i]);
                                }
                                write(s[loc_of_dot - 1] - 47);
                                writeln();
                        }
                }
        }
}

module _template;
import std.stdio;
import std.string;
import std.algorithm;
import std.container;
import std.range;
import std.math;
import std.numeric;
import std.conv;
import std.typecons;
import std.format;

struct IO {
        string read_string() {
                while (tokens.empty) {
                tokens = readln.split;
        }
        auto token = tokens.front;
                tokens.popFront;
                return token;
        }

        int read_int() {
                return read_string.to!int;
        }

        string[] tokens;
}

void main() {
        IO cin;
        int t = 1;
        // int t = cin.read_int;
        while (t--) {
                string s = cin.read_string;
                if (s[indexOf(s, '.') - 1] == '9') {
                        writeln("GOTO Vasilisa.");
                } else {
                        int loc_of_dot = indexOf(s, '.');
                        if (s[loc_of_dot + 1] < '5') {
                                writeln(s[0..loc_of_dot]);
                        } else {
                                write(s[0..loc_of_dot - 1]);
                                write(s[loc_of_dot - 1] - 47);
                                writeln();
                        }
                }
        }
}


import std;

void main () {
    uint tests;
    readf!"%s\n"(tests);

    foreach (_; 0 .. tests) {
        uint n, k;
        readf!"%s %s\n"(n, k);

        uint[] a = readln().chomp
            .split(" ")
            .to!(uint[]);

        uint[] b = readln().chomp
            .split(" ")
            .to!(uint[]);

        auto result = zip(a, b)
            .array
            .sort!"a[0] < b[0]";

        foreach (val; result) {
            if (k >= val[0])
                k += val[1];
            else
                break;
        }

        writeln(k);
    }
}
// ""

// Cheese-Cracker: cheese-cracker.github.io

void solve(){
    long n = scan;
    long k = scan;
    auto ai = scanArray;
    auto bi = scanArray;
    tup[] arr;
    for(int i = 0; i < n; ++i){
        arr ~= tup(ai[i], bi[i]);
    }
    arr.sort;
    /* show(arr); */
    for(int i = 0; i < n; ++i){
        if(arr[i][0] <= k){
            k += arr[i][1];
        }
    }
    writeln(k);
}

void main(){
    long tests = scan;        // Toggle!
    while(tests--) solve;
}

/**************    *****    That's All Folks!    *****    **************/
import std.stdio, std.range, std.conv, std.typecons, std.algorithm, std.container, std.math, std.numeric;
string[] tk; T scan(T=long)(){while(!tk.length)tk = readln.split; string a=tk.front; tk.popFront; return a.to!T;}
T[] scanArray(T=long)(){ auto r = readln.split.to!(T[]); return r; }
void show(A...)(A a){ debug{ foreach(t; a){stderr.write(t, "| ");} stderr.writeln; } }
alias ll = long, tup = Tuple!(long, "x",  long, "y");

void main() { runSolver(); }

void problem() {
  auto QN = scan!long;

  auto solve() {
    auto subSolve() {
      auto N = scan!int;
      auto K = scan!int;
      auto A = scan!int(N);
      auto B = scan!int(N);

      int ram = K;
      foreach(req, add; zip(A, B).sort!"a[0] < b[0]") {
        if (ram >= req) ram += add;
      }

      return ram;
    }

    foreach(_; 0..QN) subSolve.writeln;
  }

  outputForAtCoder(&solve);
}

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

import std.stdio, std.conv, std.array, std.string, std.algorithm, std.container, std.range, core.stdc.stdlib, std.math, std.typecons, std.numeric, std.traits, std.functional, std.bigint, std.datetime.stopwatch, core.time, core.bitop;
T[][] combinations(T)(T[] s, in long m) {   if (!m) return [[]];   if (s.empty) return [];   return s[1 .. $].combinations(m - 1).map!(x => s[0] ~ x).array ~ s[1 .. $].combinations(m); }
string scan(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }
T scan(T)(){ return scan.to!T; }
T[] scan(T)(long n){ return n.iota.map!(i => scan!T()).array; }
void deb(T ...)(T t){ debug writeln(t); }
alias Point = Tuple!(long, "x", long, "y");
Point invert(Point p) { return Point(p.y, p.x); }
long[] divisors(long n) { long[] ret; for (long i = 1; i * i <= n; i++) { if (n % i == 0) { ret ~= i; if (i * i != n) ret ~= n / i; } } return ret.sort.array; }
bool chmin(T)(ref T a, T b) { if (b < a) { a = b; return true; } else return false; }
bool chmax(T)(ref T a, T b) { if (b > a) { a = b; return true; } else return false; }
string charSort(alias S = "a < b")(string s) { return (cast(char[])((cast(byte[])s).sort!S.array)).to!string; }
ulong comb(ulong a, ulong b) { if (b == 0) {return 1;}else{return comb(a - 1, b - 1) * a / b;}}
string toAnswerString(R)(R r) { return r.map!"a.to!string".joiner(" ").array.to!string; }
struct ModInt(uint MD) if (MD < int.max) {ulong v;this(string v) {this(v.to!long);}this(int v) {this(long(v));}this(long v) {this.v = (v%MD+MD)%MD;}void opAssign(long t) {v = (t%MD+MD)%MD;}static auto normS(ulong x) {return (x<MD)?x:x-MD;}static auto make(ulong x) {ModInt m; m.v = x; return m;}auto opBinary(string op:"+")(ModInt r) const {return make(normS(v+r.v));}auto opBinary(string op:"-")(ModInt r) const {return make(normS(v+MD-r.v));}auto opBinary(string op:"*")(ModInt r) const {return make((ulong(v)*r.v%MD).to!ulong);}auto opBinary(string op:"^^", T)(T r) const {long x=v;long y=1;while(r){if(r%2==1)y=(y*x)%MD;x=x^^2%MD;r/=2;} return make(y);}auto opBinary(string op:"/")(ModInt r) const {return this*memoize!inv(r);}static ModInt inv(ModInt x) {return x^^(MD-2);}string toString() const {return v.to!string;}auto opOpAssign(string op)(ModInt r) {return mixin ("this=this"~op~"r");}}
alias MInt1 = ModInt!(10^^9 + 7);
alias MInt9 = ModInt!(998_244_353);
void outputForAtCoder(T)(T delegate() fn) {
  static if (is(T == float) || is(T == double) || is(T == real)) "%.16f".writefln(fn());
  else static if (is(T == void)) fn();
  else static if (is(T == string)) fn().writeln;
  else static if (isInputRange!T) {
    static if (!is(string == ElementType!T) && isInputRange!(ElementType!T)) foreach(r; fn()) r.toAnswerString.writeln;
    else foreach(r; fn()) r.writeln;
  }
  else fn().writeln;
}
void runSolver() {
  enum BORDER = "==================================";
  debug { BORDER.writeln; while(!stdin.eof) { "<<< Process time: %s >>>".writefln(benchmark!problem(1)); BORDER.writeln; } }
  else problem();
}
enum YESNO = [true: "Yes", false: "No"];

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

struct GridPoint {
  static enum ZERO = GridPoint(0, 0);
  long x, y;

  static GridPoint reversed(long y, long x) {
    return GridPoint(x, y);
  }

  this(long x, long y) {
    this.x = x;
    this.y = y;
  }

  inout GridPoint left() { return GridPoint(x - 1, y); }
  inout GridPoint right() { return GridPoint(x + 1, y); }
  inout GridPoint up() { return GridPoint(x, y - 1); }
  inout GridPoint down() { return GridPoint(x, y + 1); }
  inout GridPoint leftUp() { return GridPoint(x - 1, y - 1); }
  inout GridPoint leftDown() { return GridPoint(x - 1, y + 1); }
  inout GridPoint rightUp() { return GridPoint(x + 1, y - 1); }
  inout GridPoint rightDown() { return GridPoint(x + 1, y + 1); }
  inout GridPoint[] around() { return [left(), up(), right(), down()]; }
  inout GridPoint[] around(GridPoint max) { GridPoint[] ret; if (x > 0) ret ~= left; if(x < max.x-1) ret ~= right; if(y > 0) ret ~= up; if(y < max.y-1) ret ~= down; return ret; }
  inout T of(T)(inout ref T[][] grid) { return grid[cast(int)y][cast(int)x]; }
}


import std.stdio;
import std.uni;
import std.conv;
import std.container;
import std.functional;
import std.algorithm;
import std.array;
import std.typecons;
import std.range;
import std.numeric;
import std.traits;
import std.math;

void main(string[] args)
{
  auto n = next!long;
  auto m = next!int;
  long[2] s, f;
  s[0] = next!long; s[1] = next!long;
  f[0] = next!long; f[1] = next!long;
  long[2][] points = new long[2][](m);
  foreach(ref point; points)
    {
      point[0] = next!long; point[1] = next!long;
    }
  auto adj = new Tuple!(int, long)[][](m + 2);
  auto ix = iota(0, m).array.sort!((i, j) => points[i][0] < points[j][0]).array;
  auto iy = iota(0, m).array.sort!((i, j) => points[i][1] < points[j][1]).array;
  foreach(k, i; ix)
    {
      if (k >= 1)
	{
	  adj[i] ~= tuple(ix[k - 1], abs(points[i][0] - points[ix[k - 1]][0]));
	}
      if (k + 1 < ix.length)
	{
	  adj[i] ~= tuple(ix[k + 1], abs(points[i][0] - points[ix[k + 1]][0]));
	}
    }
  foreach(k, i; iy)
    {
      if (k >= 1)
	adj[i] ~= tuple(iy[k - 1], abs(points[i][1] - points[iy[k - 1]][1]));
      if (k + 1 < iy.length)
	adj[i] ~= tuple(iy[k + 1], abs(points[i][1] - points[iy[k + 1]][1]));
    }
  foreach(i; 0 .. m)
    {
      auto cost = min(abs(s[0] - points[i][0]), abs(s[1] - points[i][1]));
      adj[m] ~= tuple(i, cost);
      adj[i] ~= tuple(m, cost);
    }
  foreach(i; 0 .. m)
    {
      auto cost = abs(f[0] - points[i][0]) + abs(f[1] - points[i][1]);
      adj[m + 1] ~= tuple(i, cost);
      adj[i] ~= tuple(m + 1, cost);
    }
  adj[m] ~= tuple(m + 1, abs(s[0] - f[0]) + abs(s[1] - f[1]));
  auto pq = redBlackTree!(Tuple!(long, int))();
  auto distance = new long[](m + 2);
  distance[] = long.max / 2;
  pq.insert(tuple(cast(long)0, m));
  distance[m] = 0;
  while(!pq.empty)
    {
      auto nextnode = pq.front;
      pq.removeFront;
      if (nextnode[0] > distance[nextnode[1]]) continue;
      foreach(nei; adj[nextnode[1]])
	{
	  if (distance[nextnode[1]] + nei[1] < distance[nei[0]])
	    {
	      distance[nei[0]] = distance[nextnode[1]] + nei[1];
	      pq.insert(tuple(distance[nei[0]], nei[0]));
	    }
	}
    }
  distance[m + 1].writeln;
}

static this()
{
  popChar;
}

struct Any(T)
{
  static auto read()
  {
    static if (is(T == char))
      {
	auto res = frontChar;
	popChar;
	return res;
      }
  }
}

struct Unsigned(T)
{
  auto read()
  {
    auto res = T(0);
    while(!frontChar.isDigit) popChar;
    do
      {
	res = res * T(10) + T(frontChar - '0');
	popChar;
      }
    while(frontChar.isDigit);
    return res;
  }
}

struct Matrix(T, alias rows, alias cols)
{
  T[][] _cell;
  alias _cell this;
  // Ring constructor
  this(int n)
  {
    final switch(n)
      {
      case 0:
	_cell = new T[][](rows, cols);
	break;
      case 1:
	debug assert(rows == cols);
	_cell = new T[][](rows, cols);
	foreach(i; 0 .. rows)
	  _cell[i][i] = T(1);
	break;
      }
  }
  // Copy constructor
  this(Matrix!(T, rows, cols) other)
  {
    _cell = new T[][](rows, cols);
    foreach(i; 0 .. rows)
      _cell[i][] = other[i][];
  }
  auto opBinary(string op)(Matrix!(T, rows, cols) other)
       if (op == "+" || op == "-")
	 {
	   auto res = Matrix!(T, rows, cols)(0);
	   foreach(i; 0 .. rows)
	     foreach(j; 0 .. cols)
	       res[i][j] = mixin(q{this[i][j]}, op, q{other[i][j]});
	   return res;
	 }
  auto opBinary(string op, alias otherRows, alias otherCols)(Matrix!(T, otherRows, otherCols) other)
       if (op == "*")
	 {
	   debug assert(cols == otherRows);
	   auto res = Matrix!(T, rows, otherCols)(0);
	   foreach(i; 0 .. rows)
	     foreach(k; 0 .. cols)
	       foreach(j; 0 .. otherCols)
		 res[i][j] += this[i][k] * other[k][j];
	   return res;
	 }
  ref auto opOpAssign(string op)(Matrix!(T, rows, cols) other)
  {
    static if (op == "*")
      {
	debug assert(rows == cols);
	alias n = rows;
	auto res = Matrix!(T, n, n)(0);
	T factor;
	foreach(i; 0 .. n)
	  foreach(k; 0 .. n)
	    foreach(j; 0 .. n)
	      res[i][j] += this[i][k] * other[k][j];
	foreach(i; 0 .. n)
	  this[i][] = res[i][];
      }
    else
      {
	foreach(i; 0 .. rows)
	  foreach(j; 0 .. cols)
	    mixin(q{this[i][j] }, text(op, q{=}), q{ other[i][j];});
      }
    return this;
  }
  mixin powMethod;
}

struct Mod(T, alias mod)
{
  alias This = Mod!(T, mod);
  T _rep;
  this(T t)
  {
    _rep = t % mod;
    if (_rep < 0) _rep += mod;
  }
  static auto plain(T t)
  {
    auto res = Mod!(T, mod)();
    res._rep = t;
    return res;
  }
  static auto fromPositive(T t)
  {
    pragma(inline, true);
    return Mod!(T, mod).plain(t % mod);
  }
  static auto fromNegative(T t)
  {
    pragma(inline, true);
    return Mod!(T, mod).plain(t % mod + mod);
  }
  string toString()
  {
    return to!string(_rep);
  }
  debug invariant
  {
    assert(_rep >= 0 && _rep < mod);
  }
  auto opBinary(string op)(This b)
  {
    static if (op == "+")
      {
	T resrep = _rep + b._rep;
	if (resrep >= mod) resrep -= mod;
	return This.plain(resrep);
      }
    else static if (op == "-")
      {
	T resrep = _rep - b._rep;
	if (resrep < 0) resrep += mod;
	return This.plain(resrep);
      }
    else static if (op == "*")
      {
	return This.fromPositive(_rep * b._rep);
      }
  }
  auto opOpAssign(string op)(This b)
  {
    mixin(q{_rep }, text(op, "="), q{b._rep;});
    static if (op == "+")
      {
	if (_rep >= mod) _rep -= mod;
      }
    else static if (op == "-")
      {
	if (_rep < 0) _rep += mod;
      }
    else static if (op == "*")
      {
	_rep %= mod;
      }
    return this;
  }

  auto opBinary(string op)(long exp)
       if (op == "^^")
	 {
	   return pow(exp);
	 }
  mixin powMethod;
}

mixin template powMethod()
{
  auto pow(this ThisType)(long exp)
    {
      auto res = ThisType(1);
      auto pow = ThisType(this);
      while(exp)
	{
	  if (exp & 1) res *= pow;
	  pow *= pow;
	  exp >>= 1;
	}
      return res;
    }
}
// INPUT
char frontChar;
void popChar()
{
  import core.stdc.stdio;
  frontChar = cast(char) getchar;
  if (feof(stdin)) frontChar = ' ';
}
auto makeArray(T, S...)(S s)
{
  enum brackets = () {
    string res;
    foreach(i; 0 .. s.length)
      res ~= "[]";
    return res;
  } ();
  mixin(q{alias Type = T}, brackets, q{;});
  return new Type(s);
}
template isNumberLike(T)
{
  enum isNumberLike = is(typeof((){T test; test = test + test * test; test *= test;}()));
}
void popWhite()
{
  import std.ascii;
  while (frontChar.isWhite) popChar;
}
void print(T...)(T t)
{
  static foreach(ti; t)
    {
      static if (is(typeof(ti) == string))
	{
	  write(ti, " ");
	}
      else static if (isArray!(typeof(ti)))
	{
	  foreach(e; ti) print(e);
	}
      else static if (isTuple!(typeof(ti)))
	{
	  static foreach(i; ti.length) writesp(ti[i]);
	}
      else
	{
	  write(ti, " ");
	}
    }
}
void println(T...)(T t)
{
  static if (t.length == 0)
    writeln;
  static foreach(ti; t)
    {
      print(ti);
      writeln;
    }
}
auto next(alias T, S...)(S s)
{
  pragma(inline, true);
  static if (s.length > 0)
    {
      auto res = makeArray!(typeof(next!T()))(s);
      S t;
      enum loops = () {
	string res;
	foreach(i; 0 .. s.length)
	  {
	    auto ti = text(q{t[}, i, q{]});
	    res ~= text(q{for(}, ti, q{ = 0;}, ti , q{ < s[}, i, q{];}, ti, q{++)});
	  }
	return res;
      } ();
      enum indexing = () {
	string res = "res";
	foreach(i; 0 .. s.length)
	  res ~= text(q{[t[}, i, q{]]});
	return res;
      } ();
      mixin(loops, indexing, q{ = next!T;});
      return res;
    }
  else
    {
      static if (isNumberLike!T)
	{
	  import std.ascii: isDigit;
	  T res;
	  while(frontChar.isWhite) popChar;
	  T multiplier = T(1);
	  if (frontChar == '-')
	    {
	      multiplier = T(-1);
	      popChar;
	    }
	  else if (frontChar == '+')
	    {
	      popChar;
	    }
	  debug assert(frontChar.isDigit);
	  do
	    {
	      res = res * T(10) + T(frontChar - '0');
	      popChar;
	    }
	  while(frontChar.isDigit);
	  return multiplier * res;
	}
      else static if (is(T == string))
	{
	  import std.ascii: isWhite;
	  string res;
	  while(frontChar.isWhite)
	    popChar;
	  while(!frontChar.isWhite)
	    {
	      res ~= frontChar;
	      popChar;
	    }
	  return res;
	}
      else static if (is(T == char))
	{
	  while(frontChar.isWhite) popChar;
	  auto res = frontChar;
	  popChar;
	  return res;
	}
      else
	{
	  return T.read;
	}
    }
}

import std.algorithm;
import std.container;
import std.conv;
import std.math;
import std.range;
import std.stdio;
import std.string;
import std.typecons;

void main ()
{
	int n, m;
	while (readf !(" %s %s") (n, m) > 0)
	{
		alias Point = Tuple !(int, q{x}, int, q{y}, int, q{id});
		Point s, f;
		readf !(" %s %s") (s.x, s.y);
		s.id = m;
		readf !(" %s %s") (f.x, f.y);
		f.id = m + 1;
		auto p = new Point [m];
		foreach (int i, ref c; p)
		{
			readf !(" %s %s") (c.x, c.y);
			c.id = i;
		}
		p ~= s;
		auto tx = redBlackTree !(Point) ();
		auto ty = redBlackTree !((p, q) =>
		    p.y < q.y || (p.y == q.y && (p.x < q.x ||
		    (p.x == q.x && p.id < q.id))), Point);
		foreach (ref c; p)
		{
			tx.insert (c);
			ty.insert (c);
		}

		long res = abs (s.x - f.x) + abs (s.y - f.y);
		alias Pair = Tuple !(long, q{dist}, int, q{id});
		auto q = redBlackTree !(Pair) ();
		q.insert (Pair (0, m));
		while (!q.empty)
		{
			auto cur = q.front.dist;
			auto id = q.front.id;
			q.removeFront ();
			res = min (res, cur + abs (p[id].x - f.x) +
			    abs (p[id].y - f.y));

			auto x = tx.equalRange (p[id]);
			if (!x.empty)
			{
				auto lox = tx.lowerBound (p[id]);
				if (!lox.empty)
				{
					auto v = lox.back;
					q.insert (Pair (cur +
					    abs (v.x - p[id].x), v.id));
				}
				auto hix = tx.upperBound (p[id]);
				if (!hix.empty)
				{
					auto v = hix.front;
					q.insert (Pair (cur +
					    abs (v.x - p[id].x), v.id));
				}
				tx.removeKey (p[id]);
			}

			auto y = ty.equalRange (p[id]);
			if (!y.empty)
			{
				auto loy = ty.lowerBound (p[id]);
				if (!loy.empty)
				{
					auto v = loy.back;
					q.insert (Pair (cur +
					    abs (v.y - p[id].y), v.id));
				}
				auto hiy = ty.upperBound (p[id]);
				if (!hiy.empty)
				{
					auto v = hiy.front;
					q.insert (Pair (cur +
					    abs (v.y - p[id].y), v.id));
				}
				ty.removeKey (p[id]);
			}
		}
		writeln (res);
	}
}

import std.stdio;
import std.uni;
import std.conv;
import std.container;
import std.functional;
import std.algorithm;
import std.array;
import std.typecons;
import std.range;
import std.numeric;
import std.traits;
import std.math;

void main(string[] args)
{
  auto n = next!long;
  auto m = next!int;
  long[2] s, f;
  s[0] = next!long; s[1] = next!long;
  f[0] = next!long; f[1] = next!long;
  long[2][] points = new long[2][](m);
  foreach(ref point; points)
    {
      point[0] = next!long; point[1] = next!long;
    }
  auto adj = new Tuple!(int, long)[][](m + 2);
  auto ix = iota(0, m).array.sort!((i, j) => points[i][0] < points[i][0]).array;
  auto iy = iota(0, m).array.sort!((i, j) => points[i][1] < points[i][1]).array;
  foreach(k, i; ix)
    {
      if (k >= 1)
	{
	  adj[i] ~= tuple(ix[k - 1], abs(points[i][0] - points[ix[k - 1]][0]));
	}
      if (k + 1 < ix.length)
	{
	  adj[i] ~= tuple(ix[k + 1], abs(points[i][0] - points[ix[k + 1]][0]));
	}
    }
  foreach(k, i; iy)
    {
      if (k >= 1)
	adj[i] ~= tuple(iy[k - 1], abs(points[i][1] - points[iy[k - 1]][1]));
      if (k + 1 < iy.length)
	adj[i] ~= tuple(iy[k + 1], abs(points[i][1] - points[iy[k + 1]][1]));
    }
  foreach(i; 0 .. m)
    {
      auto cost = min(abs(s[0] - points[i][0]), abs(s[1] - points[i][1]));
      adj[m] ~= tuple(i, cost);
      adj[i] ~= tuple(m, cost);
    }
  foreach(i; 0 .. m)
    {
      auto cost = abs(f[0] - points[i][0]) + abs(f[1] - points[i][1]);
      adj[m + 1] ~= tuple(i, cost);
      adj[i] ~= tuple(m + 1, cost);
    }
  adj[m] ~= tuple(m + 1, abs(s[0] - f[0]) + abs(s[1] - f[1]));
  auto pq = redBlackTree!(Tuple!(long, int))();
  auto distance = new long[](m + 2);
  distance[] = long.max;
  pq.insert(tuple(cast(long)0, m));
  distance[m] = 0;
  while(!pq.empty)
    {
      auto nextnode = pq.front;
      pq.removeFront;
      debug writeln("doing node ", nextnode);
      if (nextnode[0] > distance[nextnode[1]]) continue;
      foreach(nei; adj[nextnode[1]])
	{
	  debug writeln("\t with adj ", nei);
	  if (distance[nextnode[1]] + nei[1] < distance[nei[0]])
	    {
	      distance[nei[0]] = distance[nextnode[1]] + nei[1];
	      pq.insert(tuple(distance[nei[0]], nei[0]));
	    }
	}
    }
  writeln(distance[0], " ", distance[1], " ", distance[2]);
  distance[m + 1].writeln;
}

static this()
{
  popChar;
}

struct Any(T)
{
  static auto read()
  {
    static if (is(T == char))
      {
	auto res = frontChar;
	popChar;
	return res;
      }
  }
}

struct Unsigned(T)
{
  auto read()
  {
    auto res = T(0);
    while(!frontChar.isDigit) popChar;
    do
      {
	res = res * T(10) + T(frontChar - '0');
	popChar;
      }
    while(frontChar.isDigit);
    return res;
  }
}

struct Matrix(T, alias rows, alias cols)
{
  T[][] _cell;
  alias _cell this;
  // Ring constructor
  this(int n)
  {
    final switch(n)
      {
      case 0:
	_cell = new T[][](rows, cols);
	break;
      case 1:
	debug assert(rows == cols);
	_cell = new T[][](rows, cols);
	foreach(i; 0 .. rows)
	  _cell[i][i] = T(1);
	break;
      }
  }
  // Copy constructor
  this(Matrix!(T, rows, cols) other)
  {
    _cell = new T[][](rows, cols);
    foreach(i; 0 .. rows)
      _cell[i][] = other[i][];
  }
  auto opBinary(string op)(Matrix!(T, rows, cols) other)
       if (op == "+" || op == "-")
	 {
	   auto res = Matrix!(T, rows, cols)(0);
	   foreach(i; 0 .. rows)
	     foreach(j; 0 .. cols)
	       res[i][j] = mixin(q{this[i][j]}, op, q{other[i][j]});
	   return res;
	 }
  auto opBinary(string op, alias otherRows, alias otherCols)(Matrix!(T, otherRows, otherCols) other)
       if (op == "*")
	 {
	   debug assert(cols == otherRows);
	   auto res = Matrix!(T, rows, otherCols)(0);
	   foreach(i; 0 .. rows)
	     foreach(k; 0 .. cols)
	       foreach(j; 0 .. otherCols)
		 res[i][j] += this[i][k] * other[k][j];
	   return res;
	 }
  ref auto opOpAssign(string op)(Matrix!(T, rows, cols) other)
  {
    static if (op == "*")
      {
	debug assert(rows == cols);
	alias n = rows;
	auto res = Matrix!(T, n, n)(0);
	T factor;
	foreach(i; 0 .. n)
	  foreach(k; 0 .. n)
	    foreach(j; 0 .. n)
	      res[i][j] += this[i][k] * other[k][j];
	foreach(i; 0 .. n)
	  this[i][] = res[i][];
      }
    else
      {
	foreach(i; 0 .. rows)
	  foreach(j; 0 .. cols)
	    mixin(q{this[i][j] }, text(op, q{=}), q{ other[i][j];});
      }
    return this;
  }
  mixin powMethod;
}

struct Mod(T, alias mod)
{
  alias This = Mod!(T, mod);
  T _rep;
  this(T t)
  {
    _rep = t % mod;
    if (_rep < 0) _rep += mod;
  }
  static auto plain(T t)
  {
    auto res = Mod!(T, mod)();
    res._rep = t;
    return res;
  }
  static auto fromPositive(T t)
  {
    pragma(inline, true);
    return Mod!(T, mod).plain(t % mod);
  }
  static auto fromNegative(T t)
  {
    pragma(inline, true);
    return Mod!(T, mod).plain(t % mod + mod);
  }
  string toString()
  {
    return to!string(_rep);
  }
  debug invariant
  {
    assert(_rep >= 0 && _rep < mod);
  }
  auto opBinary(string op)(This b)
  {
    static if (op == "+")
      {
	T resrep = _rep + b._rep;
	if (resrep >= mod) resrep -= mod;
	return This.plain(resrep);
      }
    else static if (op == "-")
      {
	T resrep = _rep - b._rep;
	if (resrep < 0) resrep += mod;
	return This.plain(resrep);
      }
    else static if (op == "*")
      {
	return This.fromPositive(_rep * b._rep);
      }
  }
  auto opOpAssign(string op)(This b)
  {
    mixin(q{_rep }, text(op, "="), q{b._rep;});
    static if (op == "+")
      {
	if (_rep >= mod) _rep -= mod;
      }
    else static if (op == "-")
      {
	if (_rep < 0) _rep += mod;
      }
    else static if (op == "*")
      {
	_rep %= mod;
      }
    return this;
  }

  auto opBinary(string op)(long exp)
       if (op == "^^")
	 {
	   return pow(exp);
	 }
  mixin powMethod;
}

mixin template powMethod()
{
  auto pow(this ThisType)(long exp)
    {
      auto res = ThisType(1);
      auto pow = ThisType(this);
      while(exp)
	{
	  if (exp & 1) res *= pow;
	  pow *= pow;
	  exp >>= 1;
	}
      return res;
    }
}
// INPUT
char frontChar;
void popChar()
{
  import core.stdc.stdio;
  frontChar = cast(char) getchar;
  if (feof(stdin)) frontChar = ' ';
}
auto makeArray(T, S...)(S s)
{
  enum brackets = () {
    string res;
    foreach(i; 0 .. s.length)
      res ~= "[]";
    return res;
  } ();
  mixin(q{alias Type = T}, brackets, q{;});
  return new Type(s);
}
template isNumberLike(T)
{
  enum isNumberLike = is(typeof((){T test; test = test + test * test; test *= test;}()));
}
void popWhite()
{
  import std.ascii;
  while (frontChar.isWhite) popChar;
}
void print(T...)(T t)
{
  static foreach(ti; t)
    {
      static if (is(typeof(ti) == string))
	{
	  write(ti, " ");
	}
      else static if (isArray!(typeof(ti)))
	{
	  foreach(e; ti) print(e);
	}
      else static if (isTuple!(typeof(ti)))
	{
	  static foreach(i; ti.length) writesp(ti[i]);
	}
      else
	{
	  write(ti, " ");
	}
    }
}
void println(T...)(T t)
{
  static if (t.length == 0)
    writeln;
  static foreach(ti; t)
    {
      print(ti);
      writeln;
    }
}
auto next(alias T, S...)(S s)
{
  pragma(inline, true);
  static if (s.length > 0)
    {
      auto res = makeArray!(typeof(next!T()))(s);
      S t;
      enum loops = () {
	string res;
	foreach(i; 0 .. s.length)
	  {
	    auto ti = text(q{t[}, i, q{]});
	    res ~= text(q{for(}, ti, q{ = 0;}, ti , q{ < s[}, i, q{];}, ti, q{++)});
	  }
	return res;
      } ();
      enum indexing = () {
	string res = "res";
	foreach(i; 0 .. s.length)
	  res ~= text(q{[t[}, i, q{]]});
	return res;
      } ();
      mixin(loops, indexing, q{ = next!T;});
      return res;
    }
  else
    {
      static if (isNumberLike!T)
	{
	  import std.ascii: isDigit;
	  T res;
	  while(frontChar.isWhite) popChar;
	  T multiplier = T(1);
	  if (frontChar == '-')
	    {
	      multiplier = T(-1);
	      popChar;
	    }
	  else if (frontChar == '+')
	    {
	      popChar;
	    }
	  debug assert(frontChar.isDigit);
	  do
	    {
	      res = res * T(10) + T(frontChar - '0');
	      popChar;
	    }
	  while(frontChar.isDigit);
	  return multiplier * res;
	}
      else static if (is(T == string))
	{
	  import std.ascii: isWhite;
	  string res;
	  while(frontChar.isWhite)
	    popChar;
	  while(!frontChar.isWhite)
	    {
	      res ~= frontChar;
	      popChar;
	    }
	  return res;
	}
      else static if (is(T == char))
	{
	  while(frontChar.isWhite) popChar;
	  auto res = frontChar;
	  popChar;
	  return res;
	}
      else
	{
	  return T.read;
	}
    }
}

import std.stdio;
import std.uni;
import std.conv;
import std.container;
import std.functional;
import std.algorithm;
import std.array;
import std.typecons;
import std.range;
import std.numeric;
import std.traits;
import std.math;

void main(string[] args)
{
  auto n = next!long;
  auto m = next!int;
  long[2] s, f;
  s[0] = next!long; s[1] = next!long;
  f[0] = next!long; f[1] = next!long;
  long[2][] points = new long[2][](m);
  foreach(ref point; points)
    {
      point[0] = next!long; point[1] = next!long;
    }
  auto adj = new Tuple!(int, long)[][](m + 2);
  auto ix = iota(0, m).array.sort!((i, j) => points[i][0] < points[i][0]).array;
  auto iy = iota(0, m).array.sort!((i, j) => points[i][1] < points[i][1]).array;
  foreach(k, i; ix)
    {
      if (k >= 1)
	{
	  adj[i] ~= tuple(ix[k - 1], abs(points[i][0] - points[ix[k - 1]][0]));
	}
      if (k + 1 < ix.length)
	{
	  adj[i] ~= tuple(ix[k + 1], abs(points[i][0] - points[ix[k + 1]][0]));
	}
    }
  foreach(k, i; iy)
    {
      if (k >= 1)
	adj[i] ~= tuple(iy[k - 1], abs(points[i][1] - points[iy[k - 1]][1]));
      if (k + 1 < iy.length)
	adj[i] ~= tuple(iy[k + 1], abs(points[i][1] - points[iy[k + 1]][1]));
    }
  foreach(i; 0 .. m)
    {
      auto cost = min(abs(s[0] - points[i][0]), abs(s[1] - points[i][1]));
      adj[m] ~= tuple(i, cost);
      adj[i] ~= tuple(m, cost);
    }
  foreach(i; 0 .. m)
    {
      auto cost = abs(f[0] - points[i][0]) + abs(f[1] - points[i][1]);
      adj[m + 1] ~= tuple(i, cost);
      adj[i] ~= tuple(m + 1, cost);
    }
  adj[m] ~= tuple(m + 1, abs(s[0] - f[0]) + abs(s[1] - f[1]));
  auto pq = redBlackTree!(Tuple!(long, int))();
  auto distance = new long[](m + 2);
  distance[] = long.max;
  pq.insert(tuple(cast(long)0, m));
  distance[m] = 0;
  while(!pq.empty)
    {
      auto nextnode = pq.front;
      pq.removeFront;
      debug writeln("doing node ", nextnode);
      if (nextnode[0] > distance[nextnode[1]]) continue;
      foreach(nei; adj[nextnode[1]])
	{
	  debug writeln("\t with adj ", nei);
	  if (distance[nextnode[1]] + nei[1] < distance[nei[0]])
	    {
	      distance[nei[0]] = distance[nextnode[1]] + nei[1];
	      pq.insert(tuple(distance[nei[0]], nei[0]));
	    }
	}
    }
  distance[m + 1].writeln;
}

static this()
{
  popChar;
}

struct Any(T)
{
  static auto read()
  {
    static if (is(T == char))
      {
	auto res = frontChar;
	popChar;
	return res;
      }
  }
}

struct Unsigned(T)
{
  auto read()
  {
    auto res = T(0);
    while(!frontChar.isDigit) popChar;
    do
      {
	res = res * T(10) + T(frontChar - '0');
	popChar;
      }
    while(frontChar.isDigit);
    return res;
  }
}

struct Matrix(T, alias rows, alias cols)
{
  T[][] _cell;
  alias _cell this;
  // Ring constructor
  this(int n)
  {
    final switch(n)
      {
      case 0:
	_cell = new T[][](rows, cols);
	break;
      case 1:
	debug assert(rows == cols);
	_cell = new T[][](rows, cols);
	foreach(i; 0 .. rows)
	  _cell[i][i] = T(1);
	break;
      }
  }
  // Copy constructor
  this(Matrix!(T, rows, cols) other)
  {
    _cell = new T[][](rows, cols);
    foreach(i; 0 .. rows)
      _cell[i][] = other[i][];
  }
  auto opBinary(string op)(Matrix!(T, rows, cols) other)
       if (op == "+" || op == "-")
	 {
	   auto res = Matrix!(T, rows, cols)(0);
	   foreach(i; 0 .. rows)
	     foreach(j; 0 .. cols)
	       res[i][j] = mixin(q{this[i][j]}, op, q{other[i][j]});
	   return res;
	 }
  auto opBinary(string op, alias otherRows, alias otherCols)(Matrix!(T, otherRows, otherCols) other)
       if (op == "*")
	 {
	   debug assert(cols == otherRows);
	   auto res = Matrix!(T, rows, otherCols)(0);
	   foreach(i; 0 .. rows)
	     foreach(k; 0 .. cols)
	       foreach(j; 0 .. otherCols)
		 res[i][j] += this[i][k] * other[k][j];
	   return res;
	 }
  ref auto opOpAssign(string op)(Matrix!(T, rows, cols) other)
  {
    static if (op == "*")
      {
	debug assert(rows == cols);
	alias n = rows;
	auto res = Matrix!(T, n, n)(0);
	T factor;
	foreach(i; 0 .. n)
	  foreach(k; 0 .. n)
	    foreach(j; 0 .. n)
	      res[i][j] += this[i][k] * other[k][j];
	foreach(i; 0 .. n)
	  this[i][] = res[i][];
      }
    else
      {
	foreach(i; 0 .. rows)
	  foreach(j; 0 .. cols)
	    mixin(q{this[i][j] }, text(op, q{=}), q{ other[i][j];});
      }
    return this;
  }
  mixin powMethod;
}

struct Mod(T, alias mod)
{
  alias This = Mod!(T, mod);
  T _rep;
  this(T t)
  {
    _rep = t % mod;
    if (_rep < 0) _rep += mod;
  }
  static auto plain(T t)
  {
    auto res = Mod!(T, mod)();
    res._rep = t;
    return res;
  }
  static auto fromPositive(T t)
  {
    pragma(inline, true);
    return Mod!(T, mod).plain(t % mod);
  }
  static auto fromNegative(T t)
  {
    pragma(inline, true);
    return Mod!(T, mod).plain(t % mod + mod);
  }
  string toString()
  {
    return to!string(_rep);
  }
  debug invariant
  {
    assert(_rep >= 0 && _rep < mod);
  }
  auto opBinary(string op)(This b)
  {
    static if (op == "+")
      {
	T resrep = _rep + b._rep;
	if (resrep >= mod) resrep -= mod;
	return This.plain(resrep);
      }
    else static if (op == "-")
      {
	T resrep = _rep - b._rep;
	if (resrep < 0) resrep += mod;
	return This.plain(resrep);
      }
    else static if (op == "*")
      {
	return This.fromPositive(_rep * b._rep);
      }
  }
  auto opOpAssign(string op)(This b)
  {
    mixin(q{_rep }, text(op, "="), q{b._rep;});
    static if (op == "+")
      {
	if (_rep >= mod) _rep -= mod;
      }
    else static if (op == "-")
      {
	if (_rep < 0) _rep += mod;
      }
    else static if (op == "*")
      {
	_rep %= mod;
      }
    return this;
  }

  auto opBinary(string op)(long exp)
       if (op == "^^")
	 {
	   return pow(exp);
	 }
  mixin powMethod;
}

mixin template powMethod()
{
  auto pow(this ThisType)(long exp)
    {
      auto res = ThisType(1);
      auto pow = ThisType(this);
      while(exp)
	{
	  if (exp & 1) res *= pow;
	  pow *= pow;
	  exp >>= 1;
	}
      return res;
    }
}
// INPUT
char frontChar;
void popChar()
{
  import core.stdc.stdio;
  frontChar = cast(char) getchar;
  if (feof(stdin)) frontChar = ' ';
}
auto makeArray(T, S...)(S s)
{
  enum brackets = () {
    string res;
    foreach(i; 0 .. s.length)
      res ~= "[]";
    return res;
  } ();
  mixin(q{alias Type = T}, brackets, q{;});
  return new Type(s);
}
template isNumberLike(T)
{
  enum isNumberLike = is(typeof((){T test; test = test + test * test; test *= test;}()));
}
void popWhite()
{
  import std.ascii;
  while (frontChar.isWhite) popChar;
}
void print(T...)(T t)
{
  static foreach(ti; t)
    {
      static if (is(typeof(ti) == string))
	{
	  write(ti, " ");
	}
      else static if (isArray!(typeof(ti)))
	{
	  foreach(e; ti) print(e);
	}
      else static if (isTuple!(typeof(ti)))
	{
	  static foreach(i; ti.length) writesp(ti[i]);
	}
      else
	{
	  write(ti, " ");
	}
    }
}
void println(T...)(T t)
{
  static if (t.length == 0)
    writeln;
  static foreach(ti; t)
    {
      print(ti);
      writeln;
    }
}
auto next(alias T, S...)(S s)
{
  pragma(inline, true);
  static if (s.length > 0)
    {
      auto res = makeArray!(typeof(next!T()))(s);
      S t;
      enum loops = () {
	string res;
	foreach(i; 0 .. s.length)
	  {
	    auto ti = text(q{t[}, i, q{]});
	    res ~= text(q{for(}, ti, q{ = 0;}, ti , q{ < s[}, i, q{];}, ti, q{++)});
	  }
	return res;
      } ();
      enum indexing = () {
	string res = "res";
	foreach(i; 0 .. s.length)
	  res ~= text(q{[t[}, i, q{]]});
	return res;
      } ();
      mixin(loops, indexing, q{ = next!T;});
      return res;
    }
  else
    {
      static if (isNumberLike!T)
	{
	  import std.ascii: isDigit;
	  T res;
	  while(frontChar.isWhite) popChar;
	  T multiplier = T(1);
	  if (frontChar == '-')
	    {
	      multiplier = T(-1);
	      popChar;
	    }
	  else if (frontChar == '+')
	    {
	      popChar;
	    }
	  debug assert(frontChar.isDigit);
	  do
	    {
	      res = res * T(10) + T(frontChar - '0');
	      popChar;
	    }
	  while(frontChar.isDigit);
	  return multiplier * res;
	}
      else static if (is(T == string))
	{
	  import std.ascii: isWhite;
	  string res;
	  while(frontChar.isWhite)
	    popChar;
	  while(!frontChar.isWhite)
	    {
	      res ~= frontChar;
	      popChar;
	    }
	  return res;
	}
      else static if (is(T == char))
	{
	  while(frontChar.isWhite) popChar;
	  auto res = frontChar;
	  popChar;
	  return res;
	}
      else
	{
	  return T.read;
	}
    }
}


// Vicfred
// https://codeforces.com/contest/1550/problem/A
//
import std.stdio;

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

while(t--) {
    int s;
    readf("%s\n", &s);

    int ans = 1;

    while(ans * ans < s) {
        ans += 1;
    }

    ans.writeln;
}
}

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 s;
    readf!" %d "(s);
    int[] a;
    int x = 1;
    int sum = 0;
    int result = 0;
    while (true) {
      a ~= x;
      sum += x;
      result += 1;
      x += 2;
      if (sum >= s) {
        break;
      }
    }
    writeln(result);
  }
}

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 long[](t);
	foreach (ti; 0..t)
	{
		auto s = RD-1;

		++ans[ti];
		long x = 1;
		while (s != 0)
		{
			++ans[ti];
			x += 2;
			s = max(0, s-x);
		}
	}

	foreach (e; ans)
	{
		writeln(e);
	}
	stdout.flush;
	debug readln;
}


//ahmat
import std.stdio,std.string,std.math,std.algorithm,
std.array,std.container,std.algorithm,std.numeric,std.bitmanip,
std.range,std.random,std.complex,std.functional,std.typecons,
std.format,std.bigint,core.vararg,core.bitop,std.conv;
int sz(T)(ref T a){return cast(int)a.length;}
alias rbt=RedBlackTree;
alias deq=DList;
alias heap=BinaryHeap;
const long mod=1000_000_007;

void main(){
    int n;
    readf("%d ",&n);
    int[] a=readln.splitter.map!(to!int).array;
    bool[int] set;
    foreach(int i;1..n+1) set[i]=true;
    foreach(int x;a) set.remove(x);
    writeln(set.byKey.array[0]);
}

import core.thread;
import std.conv, std.stdio, std.string;
import std.algorithm, std.array, std.bigint, std.container, std.math, std.range, std.regex;

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

//	chmin/chmax
void chmin(T)(ref T t, in T f) { if (t > f) t = f; }
void chmax(T)(ref T t, in T f) { if (t < f) t = f; }

//	Pair
struct Pair(S, T) {
	S x; T y;
	int opCmp(    const Pair p) const { return (x < p.x) ? -1 : (x > p.x) ? +1 : (y < p.y) ? -1 : (y > p.y) ? +1 : 0; }
	int opCmp(ref const Pair p) const { return (x < p.x) ? -1 : (x > p.x) ? +1 : (y < p.y) ? -1 : (y > p.y) ? +1 : 0; }
	string toString() const { return "(" ~ to!string(x) ~ ", " ~ to!string(y) ~ ")"; }
}
auto pair(S, T)(inout(S) x, inout(T) y) { return Pair!(S, T)(x, y); }

//	Array
int binarySearch(T)(in T[] as, in bool delegate(T) test) { int low = -1, upp = as.length; for (; low + 1 < upp; ) { int mid = (low + upp) >> 1; (test(as[mid]) ? low : upp) = mid; } return upp; }
int lowerBound(T)(in T[] as, in T val) { return as.binarySearch((T a) { return (a <  val); }); }
int upperBound(T)(in T[] as, in T val) { return as.binarySearch((T a) { return (a <= val); }); }
T[] unique(T)(in T[] as) { T[] bs; foreach (a; as) if (bs.empty || bs[$ - 1] != a) bs ~= a; return bs; }

int N;
int[] A;

void main(string[] args) {
	try {
	for (; ; ) {
		N = readInt;
		A = new int[N - 1];
		foreach (i; 0 .. N - 1) {
			A[i] = readInt;
		}

		bool[] app = new bool[N + 1];
		foreach (a; A) {
			app[a] = true;
		}
		foreach (a; 1 .. N + 1) {
			if (!app[a]) {
				writeln(a);
			}
		}

	}
	} catch (EOFException) {}
}

import std.stdio, std.string;

void solve(int[] arr)
{
    bool[] flag = new bool[arr.length + 10];
    foreach (i, ref val; arr)
    {
        flag[val] = true;
    }
    foreach (i, ref val; flag)
    {
        if (i > 0 && val == false)
        {
            writeln(i);
            return;
        }
    }
}

void main(string[] args)
{
    int n;
    while (scanf("%d", &n) == 1)
    {
        int[] arr = new int[n - 1];
        foreach (int i; 0 .. n - 1)
        {
            scanf("%d", &arr[i]);
        }
        solve(arr);
    }
}


module main;
import std.bigint,std.container,std.array,std.algorithm,std.conv,
	std.functional,std.math,std.numeric,std.string,std.range,std.complex,
	std.typecons,std.regex,std.random,std.uni,std.traits,std.variant,
	std.stdio,std.bitmanip;
import core.stdc.stdio : freopen;
alias RedBlackTree Rbt;
alias redBlackTree rbt;
alias BigInt big;
alias pair!(int,int) pii;
alias pair!(long,long) pll;
alias boyerMooreFinder strfind;
alias make_pair mp;
alias binary_search bins;
alias pair(X,Y)=Tuple!(X,q{fi},Y,q{se});
pair!(X,Y) make_pair(X,Y)(in X x_,in Y y_)
{
	pair!(X,Y) pp;
	pp.fi=x_;
	pp.se=y_;
	return pp;
}
immutable int mod=10^^9+7;
immutable long hashmod=10L^^18+3;
pure nothrow
{
	T lcm (T)(auto ref T a,auto ref T b)
	{
		return a/gcd(a,b)*b;
	}
	@property X sqr(X)(in X a_) {return a_*a_;}
	@property X cub(X)(in X a_) {return a_*a_*a_;}
	size_t lowb(T,X)(in T a,auto ref X g)
		if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(!(a[m]<g))r=m;
			else l=m;
		}
		return (!(a[l]<g))?l:r;
	}
	size_t upb(T,X)(in T a,auto ref X g)
		if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(g<a[m])r=m;
			else l=m;
		}
		return (g<a[l])?l:r;
	}
	size_t binf(T,X)(in T a,auto ref X g)
		if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(!(a[m]<g))r=m;
			else l=m;
		}
		return (g==a[l])?l:a.length;
	}
	bool binary_search(T,X)(in T a,auto ref X g)
		if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		return binf(a,g)!=a.length;
	}
}
void putarr(X)(in X a,in char ch=' '){foreach(const ref i;a)write(i,ch);}
void putarr(X)(in X a,in size_t n,in size_t m) if(isRandomAccessRange!X)
{
	foreach(i;0..n)
	{
		foreach(j;0..m)write(a[i][j],' ');
		writeln;
	}
}
bool getarr(X)(X a,in size_t n) if(hasSlicing!X)
{bool b=1; foreach(ref i;a[0..n])b=input(&i);return b;}
bool input(T...)(T ptrs) if (ptrs.length > 0)
{return readf(replicate(" %s", ptrs.length), ptrs)==ptrs.length;}
bool read(T...)(T ptrs) if (ptrs.length > 0)
{return readf(replicate(" %s", ptrs.length)~'\n', ptrs)==ptrs.length;}
nothrow void inf(in char* name) {freopen(name,"r",core.stdc.stdio.stdin);}
nothrow void ouf(in char* name) {freopen(name,"w",core.stdc.stdio.stdout);}
@property auto arread(T)(){return readln.splitter.map!(to!(T)).array;}
//split strip isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold schwartzSort multiSort partialSort heapify join filter countUntil
//---------------------------------------------------------------program beginning-----------------------------------------------------------------
void main()
{
	/*int n;
	loop:while(read(&n))
	{

	}*/
	string name=readln.strip;
	int n;
	read(&n);
	auto r1=regex(`(\w+) posted on (\w+)\'s wall`),
		r2=regex(`(\w+) commented on (\w+)\'s post`),
		r3=regex(`(\w+) likes (\w+)\'s post`);
	int[string] q;
	foreach(i;0..n)
	{
		auto s=readln.strip;
		if(auto c=matchFirst(s,r1))
		{
			if(c[1]==name)
			{
				q[c[2]]+=15;
			}
			else if(c[2]==name)
			{
				q[c[1]]+=15;
			}
			else
			{
				q[c[1]]+=0;
				q[c[2]]+=0;
			}
		}
		else if(auto c=matchFirst(s,r2))
		{
			if(c[1]==name)
			{
				q[c[2]]+=10;
			}
			else if(c[2]==name)
			{
				q[c[1]]+=10;
			}
			else
			{
				q[c[1]]+=0;
				q[c[2]]+=0;
			}
		}
		else if(auto c=matchFirst(s,r3))
		{
			if(c[1]==name)
			{
				q[c[2]]+=5;
			}
			else if(c[2]==name)
			{
				q[c[1]]+=5;
			}
			else
			{
				q[c[1]]+=0;
				q[c[2]]+=0;
			}
		}
	}
	pair!(int,string) a[];
	foreach(i,j;q)a~=mp(j,i);
	bool cmp(ref const pair!(int,string) x,ref const pair!(int,string) y)
	{
		return x.fi>y.fi || (x.fi==y.fi && x.se<y.se);
	}
	sort!cmp(a);
	foreach(i;a)writeln(i.se);
}

module main;
import std.bigint,std.container,std.array,std.algorithm,std.conv,
	std.functional,std.math,std.numeric,std.string,std.range,std.complex,
	std.typecons,std.regex,std.random,std.uni,std.traits,std.variant,
	std.stdio,std.bitmanip;
import core.stdc.stdio : freopen;
alias RedBlackTree Rbt;
alias redBlackTree rbt;
alias BigInt big;
alias pair!(int,int) pii;
alias pair!(long,long) pll;
alias boyerMooreFinder strfind;
alias make_pair mp;
alias binary_search bins;
alias pair(X,Y)=Tuple!(X,q{fi},Y,q{se});
pair!(X,Y) make_pair(X,Y)(in X x_,in Y y_)
{
	pair!(X,Y) pp;
	pp.fi=x_;
	pp.se=y_;
	return pp;
}
immutable int mod=10^^9+7;
immutable long hashmod=10L^^18+3;
pure nothrow
{
	T lcm (T)(auto ref T a,auto ref T b)
	{
		return a/gcd(a,b)*b;
	}
	@property X sqr(X)(in X a_) {return a_*a_;}
	@property X cub(X)(in X a_) {return a_*a_*a_;}
	size_t lowb(T,X)(in T a,auto ref X g)
		if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(!(a[m]<g))r=m;
			else l=m;
		}
		return (!(a[l]<g))?l:r;
	}
	size_t upb(T,X)(in T a,auto ref X g)
		if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(g<a[m])r=m;
			else l=m;
		}
		return (g<a[l])?l:r;
	}
	size_t binf(T,X)(in T a,auto ref X g)
		if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		size_t l=0,r=a.length;
		while(r-l>1)
		{
			auto m=(l+r)>>1;
			if(!(a[m]<g))r=m;
			else l=m;
		}
		return (g==a[l])?l:a.length;
	}
	bool binary_search(T,X)(in T a,auto ref X g)
		if(isRandomAccessRange!T && hasLength!T && is(typeof(g<a[0])==bool))
	{
		return binf(a,g)!=a.length;
	}
}
void putarr(X)(in X a,in char ch=' '){foreach(const ref i;a)write(i,ch);}
void putarr(X)(in X a,in size_t n,in size_t m) if(isRandomAccessRange!X)
{
	foreach(i;0..n)
	{
		foreach(j;0..m)write(a[i][j],' ');
		writeln;
	}
}
bool getarr(X)(X a,in size_t n) if(hasSlicing!X)
{bool b=1; foreach(ref i;a[0..n])b=input(&i);return b;}
bool input(T...)(T ptrs) if (ptrs.length > 0)
{return readf(replicate(" %s", ptrs.length), ptrs)==ptrs.length;}
bool read(T...)(T ptrs) if (ptrs.length > 0)
{return readf(replicate(" %s", ptrs.length)~'\n', ptrs)==ptrs.length;}
nothrow void inf(in char* name) {freopen(name,"r",core.stdc.stdio.stdin);}
nothrow void ouf(in char* name) {freopen(name,"w",core.stdc.stdio.stdout);}
@property auto arread(T)(){return readln.splitter.map!(to!(T)).array;}
//split strip isAlpha isNumber isWhite isLower isUpper toLower toUpper mixin
//cumulativeFold schwartzSort multiSort partialSort heapify join filter countUntil
//---------------------------------------------------------------program beginning-----------------------------------------------------------------
void main()
{
	/*int n;
	loop:while(read(&n))
	{

	}*/
	string name=readln.strip;
	int n;
	read(&n);
	auto r1=ctRegex!(`(\w+) posted on (\w+)\'s wall`),
		r2=ctRegex!(`(\w+) commented on (\w+)\'s post`),
		r3=ctRegex!(`(\w+) likes (\w+)\'s post`);
	int[string] q;
	foreach(i;0..n)
	{
		auto s=readln.strip;
		if(auto c=matchFirst(s,r1))
		{
			if(c[1]==name)
			{
				q[c[2]]+=15;
			}
			else if(c[2]==name)
			{
				q[c[1]]+=15;
			}
			else
			{
				q[c[1]]+=0;
				q[c[2]]+=0;
			}
		}
		else if(auto c=matchFirst(s,r2))
		{
			if(c[1]==name)
			{
				q[c[2]]+=10;
			}
			else if(c[2]==name)
			{
				q[c[1]]+=10;
			}
			else
			{
				q[c[1]]+=0;
				q[c[2]]+=0;
			}
		}
		else if(auto c=matchFirst(s,r3))
		{
			if(c[1]==name)
			{
				q[c[2]]+=5;
			}
			else if(c[2]==name)
			{
				q[c[1]]+=5;
			}
			else
			{
				q[c[1]]+=0;
				q[c[2]]+=0;
			}
		}
	}
	pair!(int,string) a[];
	foreach(i,j;q)a~=mp(j,i);
	bool cmp(ref const pair!(int,string) x,ref const pair!(int,string) y)
	{
		return x.fi>y.fi || (x.fi==y.fi && x.se<y.se);
	}
	sort!cmp(a);
	foreach(i;a)writeln(i.se);
}


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 n = RD!int;
		auto abc = new int[][](3);
		abc[0] = RDA!int;
		abc[1] = RDA!int;
		abc[2] = RDA!int;

		int pos;
		int last = -1;
		foreach (i; 0..n)
		{
			if (last == abc[pos][i])
				pos = (pos+1) % 3;

			ans[ti] ~= abc[pos][i];
			last = ans[ti][$-1];
		}
		if (ans[ti][0] == ans[ti][$-1])
		{
			pos = (pos+1) % 3;
			ans[ti][$-1] = abc[pos][$-1];
		}
		if (ans[ti][$-2] == ans[ti][$-1])
		{
			pos = (pos+1) % 3;
			ans[ti][$-1] = abc[pos][$-1];
		}
	}

	foreach (e; ans)
	{
		e.map!(to!string).join(" ").writeln;
	}
	stdout.flush;
	debug readln;
}

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)); }

void main() {
  try {
    for (; ; ) {
      const numCases = readInt();
      foreach (caseId; 0 .. numCases) {
        const N = readInt();
        auto A = new int[][](N, 3);
        foreach (j; 0 .. 3) {
          foreach (i; 0 .. N) {
            A[i][j] = readInt();
          }
        }

        auto ans = new int[N];
        foreach (i; 0 .. N) {
          foreach (j; 0 .. 3) {
            bool ok = true;
            if (i >= 1) {
              ok = ok && (ans[i - 1] != A[i][j]);
            }
            if (i == N - 1) {
              ok = ok && (ans[0] != A[i][j]);
            }
            if (ok) {
              ans[i] = A[i][j];
              break;
            }
          }
        }
        foreach (i; 0 .. N) {
          if (i > 0) write(" ");
          write(ans[i]);
        }
        writeln;
      }
    }
  } 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; }
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 n = RD!int;
		auto abc = new int[][](3);
		abc[0] = RDA!int;
		abc[1] = RDA!int;
		abc[2] = RDA!int;

		int pos;
		int last = -1;
		foreach (i; 0..n)
		{
			if (last == abc[pos][i])
				pos = (pos+1) % 3;

			ans[ti] ~= abc[pos][i];
			last = ans[ti][$-1];
		}
	}

	foreach (e; ans)
	{
		e.map!(to!string).join(" ").writeln;
	}
	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; }
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 n = RD!int;
		auto abc = new int[][](3);
		abc[0] = RDA!int;
		abc[1] = RDA!int;
		abc[2] = RDA!int;

		int pos;
		int last = -1;
		foreach (i; 0..n)
		{
			if (last == abc[pos][i])
				pos = (pos+1) % 3;

			ans[ti] ~= abc[pos][i];
			last = ans[ti][$-1];
		}
		if (ans[ti][0] == ans[ti][$-1])
		{
			pos = (pos+1) % 3;
			ans[ti][$-1] = abc[pos][$-1];
		}
	}

	foreach (e; ans)
	{
		e.map!(to!string).join(" ").writeln;
	}
	stdout.flush;
	debug readln;
}


// Vicfred
// https://codeforces.com/contest/1398/problem/B
// greedy
import std.algorithm;
import std.array;
import std.conv;
import std.stdio;
import std.string;

void main() {
    long t = readln.chomp.to!long;
    while(t--) {
        string s = readln.strip;

        int[] moves;
        for(int i = 0; i < s.length; ++i) {
            if(s[i] == '1') {
                int j = i;
                while(j + 1 < s.length && s[j + 1] == '1')
                    ++j;
                moves ~= j - i + 1;
                i = j;
            }
        }

        moves.sort!("a > b");

        int ans = 0;
        for(int i = 0; i < moves.length; i += 2)
            ans += moves[i];
        ans.writeln;
    }
}

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 s = readln.strip;
		auto g = s.group.array;
		auto sizes = g.filter !(q{a[0] == '1'}).map !(q{a[1]}).array;
		sort !(q{a > b}) (sizes);
		writeln (sizes.stride (2).sum);
	}
}

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 s = RD!string;
		int cnt;
		int[] list;
		foreach (i; 0..s.length)
		{
			if (s[i] == '1')
			{
				++cnt;
			}
			else
			{
				if (cnt != 0)
					list ~= cnt;
				cnt = 0;
			}
		}
		if (cnt != 0)
			list ~= cnt;
		list.sort!"a > b";
		int i;
		while (!list.empty)
		{
			if (i % 2 == 0)
				ans[ti] += list.front;
			list.popFront;
			++i;
		}
	}

	foreach (e; ans)
	{
		writeln(e);
	}
	stdout.flush;
	debug readln;
}


import std.stdio;

void main()
{
    uint numTasks;
    readf("%d\n", &numTasks);

    uint time, numMessages;
    uint queue, maxQueue = 0;
    uint lastTime;

    foreach(i;0..numTasks)
    {
        readf("%d %d\n", &time, &numMessages);
        if (queue > 0)
        {
            uint timeDiff = time - lastTime;
            if (queue > timeDiff)
            {
                queue -= timeDiff;
            }
            else
            {
                queue = 0;
            }
        }
        lastTime = time;
        queue += numMessages;
        if (queue > maxQueue) maxQueue = queue;
    }
    writeln(lastTime + queue, " ", maxQueue);
}

import std.algorithm;
import std.container;
import std.exception;
import std.format;
import std.math;
import std.range;
import std.stdio;
import std.string;
import std.typecons;

void main ()
{
	int n;
	while (readf (" %s", &n) > 0)
	{
		int m = 0, c = 0, t = 0;
		foreach (i; 0..n)
		{
			int r, k;
			readf (" %s %s", &r, &k);
			c = max (0, c - (r - t));
			c += k;
			m = max (m, c);
			t = r;
		}
		writefln ("%s %s", t + c, m);
	}
}

module sigod.codeforces.p292A;

import std.stdio;

void main()
{
	int n;
	stdin.readf(" %s", &n);

	int[] t = new int[n];
	int[] c = new int[n];

	foreach (i; 0 .. n) {
		stdin.readf(" %s %s", &t[i], &c[i]);
	}

	int x, y;
	solve(t, c, x, y);

	stdout.writeln(x, " ", y);
}

void solve(int[] time, int[] count, out int last_send_time, out int max_queue_size)
{
	max_queue_size = int.min;

	int queue_size = 0;
	int current_time = 0;

	foreach (i; 0 .. time.length) {
		queue_size = max(queue_size - (time[i] - current_time), 0) + count[i];

		current_time = time[i];

		if (max_queue_size < queue_size) max_queue_size = queue_size;

		version (unittest) {
			stdout.writeln("queue_size: ", queue_size,
				"; current_time: ", current_time);
		}
	}

	last_send_time = current_time + queue_size;

	if (max_queue_size < queue_size) max_queue_size = queue_size;
}

unittest {
	import std.string;

	int x, y;

	solve([1, 2], [1, 1], x, y);
	assert(x == 3 && y == 1, format("x: %s, y: %s", x, y));

	solve([1000000], [10], x, y);
	assert(x == 1000010 && y == 10, format("x: %s, y: %s", x, y));

	solve([3, 4, 5], [3, 3, 3], x, y);
	assert(x == 12 && y == 7, format("x: %s, y: %s", x, y));
}

private pure
int max(int a, int b)
{
	if (a > b) return a;
	else return b;
}