import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.StringTokenizer;
import java.math.BigInteger;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        Parser in = new Parser(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskC {
    int mod = 1000000007;

    public void solve(int testNumber, Parser in, OutputWriter out) {
        long n = in.nextLong();
        int k = in.nextInt();

        long[][] pas = MathUtils.pas(41, mod);
        Matrix a = new Matrix(83);

        a.a[0][0] = 1;
        a.a[0][k+1] = 1;

        for (int pot = 0; pot <= 40; pot++) {
            for (int coef = 0; coef <= pot; coef++) {
                a.a[pot+1][coef+1] = pas[pot][coef];
                a.a[pot+1][coef+42] = (pas[pot][coef] * ((1L << (pot-coef)) % mod)) % mod;
            }
        }

        for (int pot = 0; pot <= 40; pot++) {
            a.a[pot+42][pot+1] = 1;
        }

        Matrix b = new Matrix(83);
        for (int i = 1; i <= 42; i++) b.a[i][0] = 1;

        a = a.modpow(n, mod);
        a = a.multiply(b, mod);
        /*for (int i = 0; i < 83; i++) {
            System.out.println("i " + i + " elem: " + a.a[i][0]);
        }*/

        out.println(a.a[0][0]);
    }
}

class Parser
{
    private BufferedReader din;
    private StringTokenizer tokenizer;

    public Parser(InputStream in)
    {
        din = new BufferedReader(new InputStreamReader(in));
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(din.readLine());
            } catch (Exception e) {
                throw new UnknownError();
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt()
    {
        return Integer.parseInt(next());
    }

    public long nextLong()
    {
        return Long.parseLong(next());
    }

    }

class OutputWriter extends PrintWriter {
    public OutputWriter(Writer out) {
        super(out);
    }

    public OutputWriter(OutputStream out) {
        super(out);
    }

    }

class MathUtils {

    public static long[][] pas(int n, int mod) {
        long[][] ret = new long[n+1][n+1];

        for (int i = 0; i <= n; i++) {
            ret[i][0] = 1;
            for (int j = 1; j <= i; j++) {
                ret[i][j] = (ret[i-1][j-1] + ret[i-1][j]) % mod;
            }
        }

        return ret;
    }

    }

class Matrix {
    int n;
    long a[][];

    public Matrix(int n) {
        this.n = n;
        a = new long[n][n];
    }

    public static Matrix identity(int n) {
        Matrix ret = new Matrix(n);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                ret.a[i][j] = 0;
            }
            ret.a[i][i] = 1;
        }

        return ret;
    }

    Matrix multiply(Matrix b, long mod) {
        Matrix resp = new Matrix(n);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                resp.a[i][j] = 0;
                for (int k = 0; k < n; k++) {
                    resp.a[i][j] = (resp.a[i][j] + a[i][k] * b.a[k][j]) % mod;
                }
            }
        }

        return resp;
    }

    Matrix modpow(long exp, long mod) {
        if (exp == 0) return identity(n);
        if (exp == 1) return this;

        Matrix h = modpow(exp/2, mod);
        h = h.multiply(h, mod);
        if (exp % 2 == 1) h = h.multiply(this, mod);

        return h;
    }

    }


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Deque;
import java.util.function.Supplier;
import java.io.OutputStreamWriter;
import java.io.OutputStream;
import java.util.Collection;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.function.Consumer;
import java.io.Closeable;
import java.io.Writer;
import java.util.ArrayDeque;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 27);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            CYetAnotherNumberSequence solver = new CYetAnotherNumberSequence();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class CYetAnotherNumberSequence {
        public void solve(int testNumber, FastInput in, FastOutput out) {
            int n = in.readInt();
            int k = in.readInt();

            Modular mod = new Modular(1000000007);
            Power power = new Power(mod);

            int[] fib = new int[200];
            fib[0] = 1;
            fib[1] = 2;
            int[] a = new int[200];
            for (int i = 2; i < 200; i++) {
                fib[i] = mod.plus(fib[i - 1], fib[i - 2]);
            }
            for (int i = 0; i < 200; i++) {
                a[i] = mod.mul(fib[i], power.pow(i + 1, k));
                if (i > 0) {
                    a[i] = mod.plus(a[i], a[i - 1]);
                }
            }

            IntegerList seq = new IntegerList();
            seq.addAll(a);
            LinearRecurrenceSolver solver = LinearRecurrenceSolver.newSolverFromSequence(seq, mod);
            int ans = solver.solve(n - 1, seq);

            out.println(ans);
        }

    }

    static class Modular {
        int m;

        public int getMod() {
            return m;
        }

        public Modular(int m) {
            this.m = m;
        }

        public Modular(long m) {
            this.m = (int) m;
            if (this.m != m) {
                throw new IllegalArgumentException();
            }
        }

        public Modular(double m) {
            this.m = (int) m;
            if (this.m != m) {
                throw new IllegalArgumentException();
            }
        }

        public int valueOf(int x) {
            x %= m;
            if (x < 0) {
                x += m;
            }
            return x;
        }

        public int valueOf(long x) {
            x %= m;
            if (x < 0) {
                x += m;
            }
            return (int) x;
        }

        public int mul(int x, int y) {
            return valueOf((long) x * y);
        }

        public int plus(int x, int y) {
            return valueOf(x + y);
        }

        public int subtract(int x, int y) {
            return valueOf(x - y);
        }

        public String toString() {
            return "mod " + m;
        }

    }

    static class IntegerList implements Cloneable {
        private int size;
        private int cap;
        private int[] data;
        private static final int[] EMPTY = new int[0];

        public int[] getData() {
            return data;
        }

        public IntegerList(int cap) {
            this.cap = cap;
            if (cap == 0) {
                data = EMPTY;
            } else {
                data = new int[cap];
            }
        }

        public IntegerList(IntegerList list) {
            this.size = list.size;
            this.cap = list.cap;
            this.data = Arrays.copyOf(list.data, size);
        }

        public IntegerList() {
            this(0);
        }

        public void ensureSpace(int req) {
            if (req > cap) {
                while (cap < req) {
                    cap = Math.max(cap + 10, 2 * cap);
                }
                data = Arrays.copyOf(data, cap);
            }
        }

        private void checkRange(int i) {
            if (i < 0 || i >= size) {
                throw new ArrayIndexOutOfBoundsException("index " + i + " out of range");
            }
        }

        public int get(int i) {
            checkRange(i);
            return data[i];
        }

        public void add(int x) {
            ensureSpace(size + 1);
            data[size++] = x;
        }

        public void addAll(int[] x) {
            addAll(x, 0, x.length);
        }

        public void addAll(int[] x, int offset, int len) {
            ensureSpace(size + len);
            System.arraycopy(x, offset, data, size, len);
            size += len;
        }

        public void addAll(IntegerList list) {
            addAll(list.data, 0, list.size);
        }

        public void expandWith(int x, int len) {
            ensureSpace(len);
            while (size < len) {
                data[size++] = x;
            }
        }

        public void retain(int n) {
            if (n < 0) {
                throw new IllegalArgumentException();
            }
            if (n >= size) {
                return;
            }
            size = n;
        }

        public void set(int i, int x) {
            checkRange(i);
            data[i] = x;
        }

        public int size() {
            return size;
        }

        public int[] toArray() {
            return Arrays.copyOf(data, size);
        }

        public void clear() {
            size = 0;
        }

        public String toString() {
            return Arrays.toString(toArray());
        }

        public boolean equals(Object obj) {
            if (!(obj instanceof IntegerList)) {
                return false;
            }
            IntegerList other = (IntegerList) obj;
            return SequenceUtils.equal(data, 0, size - 1, other.data, 0, other.size - 1);
        }

        public int hashCode() {
            int h = 1;
            for (int i = 0; i < size; i++) {
                h = h * 31 + Integer.hashCode(data[i]);
            }
            return h;
        }

        public IntegerList clone() {
            IntegerList ans = new IntegerList();
            ans.addAll(this);
            return ans;
        }

    }

    static class SequenceUtils {
        public static boolean equal(int[] a, int al, int ar, int[] b, int bl, int br) {
            if ((ar - al) != (br - bl)) {
                return false;
            }
            for (int i = al, j = bl; i <= ar; i++, j++) {
                if (a[i] != b[j]) {
                    return false;
                }
            }
            return true;
        }

    }

    static class ModLinearFeedbackShiftRegister {
        private IntegerList cm;
        int m = -1;
        int dm;
        private IntegerList cn;
        private IntegerList buf;
        private IntegerList seq;
        private Modular mod;
        private Power pow;

        public ModLinearFeedbackShiftRegister(Modular mod, int cap) {
            cm = new IntegerList(cap + 1);
            cn = new IntegerList(cap + 1);
            seq = new IntegerList(cap + 1);
            buf = new IntegerList(cap + 1);
            cn.add(1);

            this.mod = mod;
            this.pow = new Power(mod);
        }

        public ModLinearFeedbackShiftRegister(Modular mod) {
            this(mod, 0);
        }

        private int estimateDelta() {
            int n = seq.size() - 1;
            int ans = 0;
            int[] cnData = cn.getData();
            int[] seqData = seq.getData();
            for (int i = 0, until = cn.size(); i < until; i++) {
                ans = mod.plus(ans, mod.mul(cnData[i], seqData[n - i]));
            }
            return ans;
        }

        public void add(int x) {
            x = mod.valueOf(x);
            int n = seq.size();

            seq.add(x);
            int dn = estimateDelta();
            if (dn == 0) {
                return;
            }

            if (m < 0) {
                cm.clear();
                cm.addAll(cn);
                dm = dn;
                m = n;

                cn.expandWith(0, n + 2);
                return;
            }

            int ln = cn.size() - 1;
            int len = Math.max(ln, n + 1 - ln);
            buf.clear();
            buf.addAll(cn);
            buf.expandWith(0, len + 1);

            int factor = mod.mul(dn, pow.inverseByFermat(dm));

            int[] bufData = buf.getData();
            int[] cmData = cm.getData();
            for (int i = n - m, until = n - m + cm.size(); i < until; i++) {
                bufData[i] = mod.subtract(bufData[i], mod.mul(factor, cmData[i - (n - m)]));
            }

            if (cn.size() < buf.size()) {
                IntegerList tmp = cm;
                cm = cn;
                cn = tmp;
                m = n;
                dm = dn;
            }
            {
                IntegerList tmp = cn;
                cn = buf;
                buf = tmp;
            }

        }

        public int length() {
            return cn.size() - 1;
        }

        public String toString() {
            return cn.toString();
        }

        public int codeAt(int i) {
            return mod.valueOf(-cn.get(i));
        }

    }

    static class Buffer<T> {
        private Deque<T> deque;
        private Supplier<T> supplier;
        private Consumer<T> cleaner;

        public Buffer(Supplier<T> supplier) {
            this(supplier, (x) -> {
            });
        }

        public Buffer(Supplier<T> supplier, Consumer<T> cleaner) {
            this(supplier, cleaner, 0);
        }

        public Buffer(Supplier<T> supplier, Consumer<T> cleaner, int exp) {
            this.supplier = supplier;
            this.cleaner = cleaner;
            deque = new ArrayDeque<>(exp);
        }

        public T alloc() {
            return deque.isEmpty() ? supplier.get() : deque.removeFirst();
        }

        public void release(T e) {
            cleaner.accept(e);
            deque.addLast(e);
        }

    }

    static class FastOutput implements AutoCloseable, Closeable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput println(int c) {
            cache.append(c).append('\n');
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static class LinearRecurrenceSolver {
        Modular mod;
        IntegerList coe;
        IntegerList p;
        IntegerList remainder;
        Power pow;
        int n;

        private LinearRecurrenceSolver(IntegerList coe, Modular mod) {
            this.coe = coe;
            this.mod = mod;
            n = coe.size();
            pow = new Power(mod);
            remainder = new IntegerList(coe.size());
            p = new IntegerList(coe.size() + 1);
            for (int i = n - 1; i >= 0; i--) {
                p.add(mod.valueOf(-coe.get(i)));
            }
            p.add(1);
        }

        public static LinearRecurrenceSolver newSolverFromLinearRecurrence(IntegerList coe, Modular mod) {
            return new LinearRecurrenceSolver(coe, mod);
        }

        public static LinearRecurrenceSolver newSolverFromSequence(IntegerList seq, Modular mod) {
            ModLinearFeedbackShiftRegister lfsr = new ModLinearFeedbackShiftRegister(mod, seq.size());
            for (int i = 0; i < seq.size(); i++) {
                lfsr.add(seq.get(i));
            }
            IntegerList coes = new IntegerList(lfsr.length());
            for (int i = 1; i <= lfsr.length(); i++) {
                coes.add(lfsr.codeAt(i));
            }
            return newSolverFromLinearRecurrence(coes, mod);
        }

        private int solve(IntegerList a) {
            int ans = 0;
            remainder.expandWith(0, n);
            for (int i = 0; i < n; i++) {
                ans = mod.plus(ans, mod.mul(remainder.get(i), a.get(i)));
            }
            return ans;
        }

        public int solve(long k, IntegerList a) {
            if (k < a.size()) {
                return a.get((int) k);
            }
            Polynomials.module(k, p, remainder, pow);
            return solve(a);
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static class ExtGCD {
        private long x;
        private long y;
        private long g;

        public long getX() {
            return x;
        }

        public long extgcd(long a, long b) {
            if (a >= b) {
                g = extgcd0(a, b);
            } else {
                g = extgcd0(b, a);
                long tmp = x;
                x = y;
                y = tmp;
            }
            return g;
        }

        private long extgcd0(long a, long b) {
            if (b == 0) {
                x = 1;
                y = 0;
                return a;
            }
            long g = extgcd0(b, a % b);
            long n = x;
            long m = y;
            x = m;
            y = n - m * (a / b);
            return g;
        }

    }

    static class Polynomials {
        public static Buffer<IntegerList> listBuffer = new Buffer<>(IntegerList::new, list -> list.clear());
        private static ExtGCD extGCD = new ExtGCD();

        public static int rankOf(IntegerList p) {
            int[] data = p.getData();
            int r = p.size() - 1;
            while (r >= 0 && data[r] == 0) {
                r--;
            }
            return Math.max(0, r);
        }

        public static void normalize(IntegerList list) {
            list.retain(rankOf(list) + 1);
        }

        public static void mul(IntegerList a, IntegerList b, IntegerList c, Modular mod) {
            int rA = rankOf(a);
            int rB = rankOf(b);
            c.clear();
            c.expandWith(0, rA + rB + 1);
            int[] aData = a.getData();
            int[] bData = b.getData();
            int[] cData = c.getData();
            for (int i = 0; i <= rA; i++) {
                for (int j = 0; j <= rB; j++) {
                    cData[i + j] = mod.plus(cData[i + j], mod.mul(aData[i], bData[j]));
                }
            }
        }

        public static void divide(IntegerList a, IntegerList b, IntegerList c, IntegerList remainder, Power pow) {
            Modular mod = pow.getModular();
            int rA = rankOf(a);
            int rB = rankOf(b);

            if (rA < rB) {
                c.clear();
                c.add(0);
                remainder.clear();
                remainder.addAll(a);
                return;
            }

            int rC = Math.max(0, rA - rB);
            c.clear();
            c.expandWith(0, rC + 1);
            remainder.clear();
            remainder.addAll(a);

            int[] bData = b.getData();
            int[] cData = c.getData();
            int[] rData = remainder.getData();

            if (extGCD.extgcd(b.get(rB), mod.getMod()) != 1) {
                throw new IllegalArgumentException();
            }
            int inv = mod.valueOf(extGCD.getX());
            for (int i = rA, j = rC; i >= rB; i--, j--) {
                if (rData[i] == 0) {
                    continue;
                }
                int factor = mod.mul(-rData[i], inv);
                cData[j] = mod.valueOf(-factor);
                for (int k = rB; k >= 0; k--) {
                    rData[k + j] = mod.plus(rData[k + j], mod.mul(factor, bData[k]));
                }
            }

            normalize(remainder);
        }

        public static void module(long k, IntegerList p, IntegerList remainder, Power pow) {
            int rP = rankOf(p);
            if (rP == 0) {
                remainder.clear();
                remainder.add(0);
                return;
            }

            IntegerList a = listBuffer.alloc();
            IntegerList c = listBuffer.alloc();

            module(k, a, p, c, remainder, rP, pow);

            listBuffer.release(a);
            listBuffer.release(c);
        }

        private static void module(long k, IntegerList a, IntegerList b, IntegerList c, IntegerList remainder, int rb, Power pow) {
            Modular mod = pow.getModular();
            if (k < rb) {
                remainder.clear();
                remainder.expandWith(0, (int) k + 1);
                remainder.set((int) k, 1);
                return;
            }
            module(k / 2, a, b, c, remainder, rb, pow);
            mul(remainder, remainder, a, mod);
            if (k % 2 == 1) {
                int ra = rankOf(a);
                a.expandWith(0, ra + 2);
                int[] aData = a.getData();
                for (int i = ra; i >= 0; i--) {
                    aData[i + 1] = aData[i];
                }
                aData[0] = 0;
            }
            divide(a, b, c, remainder, pow);
        }

    }

    static class Power {
        final Modular modular;

        public Modular getModular() {
            return modular;
        }

        public Power(Modular modular) {
            this.modular = modular;
        }

        public int pow(int x, int n) {
            if (n == 0) {
                return modular.valueOf(1);
            }
            long r = pow(x, n >> 1);
            r = modular.valueOf(r * r);
            if ((n & 1) == 1) {
                r = modular.valueOf(r * x);
            }
            return (int) r;
        }

        public int inverseByFermat(int x) {
            return pow(x, modular.m - 2);
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Deque;
import java.util.function.Supplier;
import java.io.OutputStreamWriter;
import java.io.OutputStream;
import java.util.Collection;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.function.Consumer;
import java.io.Closeable;
import java.io.Writer;
import java.util.ArrayDeque;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 27);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            CYetAnotherNumberSequence solver = new CYetAnotherNumberSequence();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class CYetAnotherNumberSequence {
        public void solve(int testNumber, FastInput in, FastOutput out) {
            long n = in.readLong();
            int k = in.readInt();

            Modular mod = new Modular(1000000007);
            Power power = new Power(mod);

            int[] fib = new int[100];
            fib[0] = 1;
            fib[1] = 2;
            int[] a = new int[100];
            for (int i = 2; i < 100; i++) {
                fib[i] = mod.plus(fib[i - 1], fib[i - 2]);
            }
            for (int i = 0; i < 100; i++) {
                a[i] = mod.mul(fib[i], power.pow(i + 1, k));
                if (i > 0) {
                    a[i] = mod.plus(a[i], a[i - 1]);
                }
            }

            IntegerList seq = new IntegerList();
            seq.addAll(a);
            LinearRecurrenceSolver solver = LinearRecurrenceSolver.newSolverFromSequence(seq, mod);
            int ans = solver.solve(n - 1, seq);

            out.println(ans);
        }

    }

    static class Modular {
        int m;

        public int getMod() {
            return m;
        }

        public Modular(int m) {
            this.m = m;
        }

        public Modular(long m) {
            this.m = (int) m;
            if (this.m != m) {
                throw new IllegalArgumentException();
            }
        }

        public Modular(double m) {
            this.m = (int) m;
            if (this.m != m) {
                throw new IllegalArgumentException();
            }
        }

        public int valueOf(int x) {
            x %= m;
            if (x < 0) {
                x += m;
            }
            return x;
        }

        public int valueOf(long x) {
            x %= m;
            if (x < 0) {
                x += m;
            }
            return (int) x;
        }

        public int mul(int x, int y) {
            return valueOf((long) x * y);
        }

        public int plus(int x, int y) {
            return valueOf(x + y);
        }

        public int subtract(int x, int y) {
            return valueOf(x - y);
        }

        public String toString() {
            return "mod " + m;
        }

    }

    static class IntegerList implements Cloneable {
        private int size;
        private int cap;
        private int[] data;
        private static final int[] EMPTY = new int[0];

        public int[] getData() {
            return data;
        }

        public IntegerList(int cap) {
            this.cap = cap;
            if (cap == 0) {
                data = EMPTY;
            } else {
                data = new int[cap];
            }
        }

        public IntegerList(IntegerList list) {
            this.size = list.size;
            this.cap = list.cap;
            this.data = Arrays.copyOf(list.data, size);
        }

        public IntegerList() {
            this(0);
        }

        public void ensureSpace(int req) {
            if (req > cap) {
                while (cap < req) {
                    cap = Math.max(cap + 10, 2 * cap);
                }
                data = Arrays.copyOf(data, cap);
            }
        }

        private void checkRange(int i) {
            if (i < 0 || i >= size) {
                throw new ArrayIndexOutOfBoundsException("index " + i + " out of range");
            }
        }

        public int get(int i) {
            checkRange(i);
            return data[i];
        }

        public void add(int x) {
            ensureSpace(size + 1);
            data[size++] = x;
        }

        public void addAll(int[] x) {
            addAll(x, 0, x.length);
        }

        public void addAll(int[] x, int offset, int len) {
            ensureSpace(size + len);
            System.arraycopy(x, offset, data, size, len);
            size += len;
        }

        public void addAll(IntegerList list) {
            addAll(list.data, 0, list.size);
        }

        public void expandWith(int x, int len) {
            ensureSpace(len);
            while (size < len) {
                data[size++] = x;
            }
        }

        public void retain(int n) {
            if (n < 0) {
                throw new IllegalArgumentException();
            }
            if (n >= size) {
                return;
            }
            size = n;
        }

        public void set(int i, int x) {
            checkRange(i);
            data[i] = x;
        }

        public int size() {
            return size;
        }

        public int[] toArray() {
            return Arrays.copyOf(data, size);
        }

        public void clear() {
            size = 0;
        }

        public String toString() {
            return Arrays.toString(toArray());
        }

        public boolean equals(Object obj) {
            if (!(obj instanceof IntegerList)) {
                return false;
            }
            IntegerList other = (IntegerList) obj;
            return SequenceUtils.equal(data, 0, size - 1, other.data, 0, other.size - 1);
        }

        public int hashCode() {
            int h = 1;
            for (int i = 0; i < size; i++) {
                h = h * 31 + Integer.hashCode(data[i]);
            }
            return h;
        }

        public IntegerList clone() {
            IntegerList ans = new IntegerList();
            ans.addAll(this);
            return ans;
        }

    }

    static class SequenceUtils {
        public static boolean equal(int[] a, int al, int ar, int[] b, int bl, int br) {
            if ((ar - al) != (br - bl)) {
                return false;
            }
            for (int i = al, j = bl; i <= ar; i++, j++) {
                if (a[i] != b[j]) {
                    return false;
                }
            }
            return true;
        }

    }

    static class ModLinearFeedbackShiftRegister {
        private IntegerList cm;
        int m = -1;
        int dm;
        private IntegerList cn;
        private IntegerList buf;
        private IntegerList seq;
        private Modular mod;
        private Power pow;

        public ModLinearFeedbackShiftRegister(Modular mod, int cap) {
            cm = new IntegerList(cap + 1);
            cn = new IntegerList(cap + 1);
            seq = new IntegerList(cap + 1);
            buf = new IntegerList(cap + 1);
            cn.add(1);

            this.mod = mod;
            this.pow = new Power(mod);
        }

        public ModLinearFeedbackShiftRegister(Modular mod) {
            this(mod, 0);
        }

        private int estimateDelta() {
            int n = seq.size() - 1;
            int ans = 0;
            int[] cnData = cn.getData();
            int[] seqData = seq.getData();
            for (int i = 0, until = cn.size(); i < until; i++) {
                ans = mod.plus(ans, mod.mul(cnData[i], seqData[n - i]));
            }
            return ans;
        }

        public void add(int x) {
            x = mod.valueOf(x);
            int n = seq.size();

            seq.add(x);
            int dn = estimateDelta();
            if (dn == 0) {
                return;
            }

            if (m < 0) {
                cm.clear();
                cm.addAll(cn);
                dm = dn;
                m = n;

                cn.expandWith(0, n + 2);
                return;
            }

            int ln = cn.size() - 1;
            int len = Math.max(ln, n + 1 - ln);
            buf.clear();
            buf.addAll(cn);
            buf.expandWith(0, len + 1);

            int factor = mod.mul(dn, pow.inverseByFermat(dm));

            int[] bufData = buf.getData();
            int[] cmData = cm.getData();
            for (int i = n - m, until = n - m + cm.size(); i < until; i++) {
                bufData[i] = mod.subtract(bufData[i], mod.mul(factor, cmData[i - (n - m)]));
            }

            if (cn.size() < buf.size()) {
                IntegerList tmp = cm;
                cm = cn;
                cn = tmp;
                m = n;
                dm = dn;
            }
            {
                IntegerList tmp = cn;
                cn = buf;
                buf = tmp;
            }

        }

        public int length() {
            return cn.size() - 1;
        }

        public String toString() {
            return cn.toString();
        }

        public int codeAt(int i) {
            return mod.valueOf(-cn.get(i));
        }

    }

    static class Buffer<T> {
        private Deque<T> deque;
        private Supplier<T> supplier;
        private Consumer<T> cleaner;

        public Buffer(Supplier<T> supplier) {
            this(supplier, (x) -> {
            });
        }

        public Buffer(Supplier<T> supplier, Consumer<T> cleaner) {
            this(supplier, cleaner, 0);
        }

        public Buffer(Supplier<T> supplier, Consumer<T> cleaner, int exp) {
            this.supplier = supplier;
            this.cleaner = cleaner;
            deque = new ArrayDeque<>(exp);
        }

        public T alloc() {
            return deque.isEmpty() ? supplier.get() : deque.removeFirst();
        }

        public void release(T e) {
            cleaner.accept(e);
            deque.addLast(e);
        }

    }

    static class FastOutput implements AutoCloseable, Closeable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput println(int c) {
            cache.append(c).append('\n');
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static class LinearRecurrenceSolver {
        Modular mod;
        IntegerList coe;
        IntegerList p;
        IntegerList remainder;
        Power pow;
        int n;

        private LinearRecurrenceSolver(IntegerList coe, Modular mod) {
            this.coe = coe;
            this.mod = mod;
            n = coe.size();
            pow = new Power(mod);
            remainder = new IntegerList(coe.size());
            p = new IntegerList(coe.size() + 1);
            for (int i = n - 1; i >= 0; i--) {
                p.add(mod.valueOf(-coe.get(i)));
            }
            p.add(1);
        }

        public static LinearRecurrenceSolver newSolverFromLinearRecurrence(IntegerList coe, Modular mod) {
            return new LinearRecurrenceSolver(coe, mod);
        }

        public static LinearRecurrenceSolver newSolverFromSequence(IntegerList seq, Modular mod) {
            ModLinearFeedbackShiftRegister lfsr = new ModLinearFeedbackShiftRegister(mod, seq.size());
            for (int i = 0; i < seq.size(); i++) {
                lfsr.add(seq.get(i));
            }
            IntegerList coes = new IntegerList(lfsr.length());
            for (int i = 1; i <= lfsr.length(); i++) {
                coes.add(lfsr.codeAt(i));
            }
            return newSolverFromLinearRecurrence(coes, mod);
        }

        private int solve(IntegerList a) {
            int ans = 0;
            remainder.expandWith(0, n);
            for (int i = 0; i < n; i++) {
                ans = mod.plus(ans, mod.mul(remainder.get(i), a.get(i)));
            }
            return ans;
        }

        public int solve(long k, IntegerList a) {
            if (k < a.size()) {
                return a.get((int) k);
            }
            Polynomials.module(k, p, remainder, pow);
            return solve(a);
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

        public long readLong() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            long val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static class ExtGCD {
        private long x;
        private long y;
        private long g;

        public long getX() {
            return x;
        }

        public long extgcd(long a, long b) {
            if (a >= b) {
                g = extgcd0(a, b);
            } else {
                g = extgcd0(b, a);
                long tmp = x;
                x = y;
                y = tmp;
            }
            return g;
        }

        private long extgcd0(long a, long b) {
            if (b == 0) {
                x = 1;
                y = 0;
                return a;
            }
            long g = extgcd0(b, a % b);
            long n = x;
            long m = y;
            x = m;
            y = n - m * (a / b);
            return g;
        }

    }

    static class Polynomials {
        public static Buffer<IntegerList> listBuffer = new Buffer<>(IntegerList::new, list -> list.clear());
        private static ExtGCD extGCD = new ExtGCD();

        public static int rankOf(IntegerList p) {
            int[] data = p.getData();
            int r = p.size() - 1;
            while (r >= 0 && data[r] == 0) {
                r--;
            }
            return Math.max(0, r);
        }

        public static void normalize(IntegerList list) {
            list.retain(rankOf(list) + 1);
        }

        public static void mul(IntegerList a, IntegerList b, IntegerList c, Modular mod) {
            int rA = rankOf(a);
            int rB = rankOf(b);
            c.clear();
            c.expandWith(0, rA + rB + 1);
            int[] aData = a.getData();
            int[] bData = b.getData();
            int[] cData = c.getData();
            for (int i = 0; i <= rA; i++) {
                for (int j = 0; j <= rB; j++) {
                    cData[i + j] = mod.plus(cData[i + j], mod.mul(aData[i], bData[j]));
                }
            }
        }

        public static void divide(IntegerList a, IntegerList b, IntegerList c, IntegerList remainder, Power pow) {
            Modular mod = pow.getModular();
            int rA = rankOf(a);
            int rB = rankOf(b);

            if (rA < rB) {
                c.clear();
                c.add(0);
                remainder.clear();
                remainder.addAll(a);
                return;
            }

            int rC = Math.max(0, rA - rB);
            c.clear();
            c.expandWith(0, rC + 1);
            remainder.clear();
            remainder.addAll(a);

            int[] bData = b.getData();
            int[] cData = c.getData();
            int[] rData = remainder.getData();

            if (extGCD.extgcd(b.get(rB), mod.getMod()) != 1) {
                throw new IllegalArgumentException();
            }
            int inv = mod.valueOf(extGCD.getX());
            for (int i = rA, j = rC; i >= rB; i--, j--) {
                if (rData[i] == 0) {
                    continue;
                }
                int factor = mod.mul(-rData[i], inv);
                cData[j] = mod.valueOf(-factor);
                for (int k = rB; k >= 0; k--) {
                    rData[k + j] = mod.plus(rData[k + j], mod.mul(factor, bData[k]));
                }
            }

            normalize(remainder);
        }

        public static void module(long k, IntegerList p, IntegerList remainder, Power pow) {
            int rP = rankOf(p);
            if (rP == 0) {
                remainder.clear();
                remainder.add(0);
                return;
            }

            IntegerList a = listBuffer.alloc();
            IntegerList c = listBuffer.alloc();

            module(k, a, p, c, remainder, rP, pow);

            listBuffer.release(a);
            listBuffer.release(c);
        }

        private static void module(long k, IntegerList a, IntegerList b, IntegerList c, IntegerList remainder, int rb, Power pow) {
            Modular mod = pow.getModular();
            if (k < rb) {
                remainder.clear();
                remainder.expandWith(0, (int) k + 1);
                remainder.set((int) k, 1);
                return;
            }
            module(k / 2, a, b, c, remainder, rb, pow);
            mul(remainder, remainder, a, mod);
            if (k % 2 == 1) {
                int ra = rankOf(a);
                a.expandWith(0, ra + 2);
                int[] aData = a.getData();
                for (int i = ra; i >= 0; i--) {
                    aData[i + 1] = aData[i];
                }
                aData[0] = 0;
            }
            divide(a, b, c, remainder, pow);
        }

    }

    static class Power {
        final Modular modular;

        public Modular getModular() {
            return modular;
        }

        public Power(Modular modular) {
            this.modular = modular;
        }

        public int pow(int x, int n) {
            if (n == 0) {
                return modular.valueOf(1);
            }
            long r = pow(x, n >> 1);
            r = modular.valueOf(r * r);
            if ((n & 1) == 1) {
                r = modular.valueOf(r * x);
            }
            return (int) r;
        }

        public int inverseByFermat(int x) {
            return pow(x, modular.m - 2);
        }

    }
}


import java.lang.*;
import java.math.*;
import java.util.*;
import java.io.*;

public class Main {

   void solve(){
       long n=nl();
        int k=ni();
        if(n==1){
            pw.println("1");
            return;
        }
        precompute(k+2);
        sz=k+1+k+1+1;
        long Mat[][]=new long[sz][sz];
        for(int i=0;i<=k;i++){
            Mat[k+1+i][i]=1;
        }
        for(int c=0;c<=k;c++){
            for(int r=0;r<=c;r++){
                Mat[r][k+1+c]=mul(ncr(c,r),pow[c-r],M);
                Mat[k+1+r][k+1+c]=ncr(c,r);
            }
        }
        for(int i=0;i<=2*k+1;i++) Mat[i][2*k+2]=Mat[i][2*k+1];
        Mat[sz-1][sz-1]=1;

        Mat=pow(Mat,n-2);
        long arr[]=new long[sz];
        for(int i=0;i<=k;i++) arr[i]=1;
        for(int i=k+1;i<=2*k+1;i++) arr[i]=pow[i-k];
        arr[sz-1]=1;
        arr[sz-1]=add(arr[sz-1],pow[k+1],M);
//        for(int i=0;i<sz;i++){
//            for(int j=0;j<sz;j++) pw.print(Mat[i][j]+" ");
//            pw.println("");
//        }
        long ans=0;
        for(int i=0;i<sz;i++){
            ans=add(ans,mul(arr[i],Mat[i][sz-1],M),M);
        }
        pw.println(ans);

    }
    int sz;
    long [][] pow(long A[][],long x){
        if(x==0){
            long C[][]=new long[sz][sz];
            for(int i=0;i<sz;i++) C[i][i]=1;
            return C;
        }else if(x==1){
            return A;
        }
        long C[][]=pow(A,x/2);
        C=mul(C,C);
        if((x&1)>0) return mul(A,C);
        return C;

    }
    long [][] mul(long A[][],long B[][]){
        long C[][]=new long[sz][sz];
        for(int i=0;i<sz;i++){
            for(int j=0;j<sz;j++){
                for(int k=0;k<sz;k++){
                    C[i][j]=(C[i][j]+(A[i][k]%M * B[k][j]%M)%M)%M;
                }
            }
        }
        return C;
    }

    long ncr(int n,int r) {
        long ans = fact[n];
        ans=mul(ans,inv[n-r],M);
        ans=mul(ans,inv[r],M);
        return ans;
    }
    long fact[];
    long inv[];
    long pow[];
    void precompute(int n){
       fact=new long[n+1];
       inv=new long[n+1];
       pow=new long[n+1];
       pow[0]=1;
       fact[0]=1;
       for(int i=1;i<=n;i++){
           pow[i]=(pow[i-1]*2)%M;
           fact[i]=(fact[i-1]*i)%M;
       }
       inv[n]=modInverse(fact[n],M);
        for(int i=n-1;i>=0;i--) inv[i]=(inv[i+1]*(i+1))%M;

    }
    long add(long x,long y,long M){
        x+=y;
        if(x>=M) x-=M;
        return x;
    }
    long sub(long x,long y,long M){
        x-=y;
        if(x<0) x+=M;
        return x;
    }
    long mul(long x,long y,long M){
        x*=y;
        if(x>=M) x%=M;
        return x;
    }
    long modpow(long a, long b,long M)
    {
        long r=1;
        while(b>0)
        {
            if((b&1)>0) r=mul(r,a,M);
            a=mul(a,a,M);
            b>>=1;
        }
        return r;
    }

    long modInverse(long A, long M)
    {

        return modpow(A,M-2,M);
    }

    long M= (long)1e9+7;
    InputStream is;
    PrintWriter pw;
    String INPUT = "";
    void run() throws Exception {
        is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        pw = new PrintWriter(System.out);
        long s = System.currentTimeMillis();
        solve();
        pw.flush();
        if(!INPUT.isEmpty())tr(System.currentTimeMillis()-s+"ms");

    }
    public static void main(String[] args) throws Exception { new Main().run(); }

    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte() {
        if(lenbuf == -1)throw new InputMismatchException();
        if(ptrbuf >= lenbuf){
            ptrbuf = 0;
            try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
            if(lenbuf <= 0)return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
    private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

    private double nd() { return Double.parseDouble(ns()); }
    private char nc() { return (char)skip(); }

    private String ns() {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n) {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while(p < n && !(isSpaceChar(b))){
            buf[p++] = (char)b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m) {
        char[][] map = new char[n][];
        for(int i = 0;i < n;i++)map[i] = ns(m);
        return map;
    }

    private int[] na(int n) {
        int[] a = new int[n];
        for(int i = 0;i < n;i++)a[i] = ni();
        return a;
    }

    private int ni() {
        int num = 0, b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl() {
        long num = 0;
        int b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }
    private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
    private void tr(Object... o) { if(INPUT.length() > 0)System.out.println(Arrays.deepToString(o)); }

}


import java.util.*;

public class D {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int x = sc.nextInt();
		int y = sc.nextInt();
		int z = sc.nextInt();

		int x1 = sc.nextInt();
		int y1 = sc.nextInt();
		int z1 = sc.nextInt();

		int[] numbers = new int[6];
		for (int i=0; i<numbers.length; i++) {
			numbers[i] = sc.nextInt();
		}

		boolean a1 = true,a2 = true,a3 = true,a4 = true,a5 = true,a6 = true;

		if (x > x1) {
			a5 = false;
		} else if (x < 0) {
			a6 = false;
		} else if (x >=0 && x<= x1) {
			a5 = false;
			a6 = false;
		}

		if (y > y1) {
			a1 = false;
		} else if (y < 0) {
			a2 = false;
		} else if (y >=0 && y <= y1) {
			a1 = false;
			a2 = false;
		}

		if (z > z1) {
			a3 = false;
		} else if (y < 0) {
			a4 = false;
		} else if (y >=0 && y <= y1) {
			a3 = false;
			a4 = false;
		}

		long ans = 0;
		if (a1) {
			ans += numbers[0];
		}
		if (a2) {
			ans += numbers[1];
		}
		if (a3) {
			ans += numbers[2];
		}
		if (a4) {
			ans += numbers[3];
		}
		if (a5) {
			ans += numbers[4];
		}
		if (a6) {
			ans += numbers[5];
		}

		System.out.println(ans);
		sc.close();
	}
}


import java.util.Scanner;

public class ProblemC {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int kx = in.nextInt();
		int ky = in.nextInt();
		int kz = in.nextInt();

		int x = in.nextInt();
		int y = in.nextInt();
		int z = in.nextInt();

		int a0 = in.nextInt();
		int a1 = in.nextInt();
		int a2 = in.nextInt();

		int a3 = in.nextInt();
		int a4 = in.nextInt();
		int a5 = in.nextInt();

		int sum = 0;
		//FROM BOTTOM
		if ( ky < 0 ) {
			sum += a0;
		}
		//FROM TOP
		if ( ky > y ) {
			sum += a1;
		}

		//TWO SIDES
		if ( kx < 0 && kz < 0 ) {
			sum += a2+a4;
		}
		//TWO SIDES
		if ( kx < 0 && kz > z ) {
			sum += a3+a4;
		}
		//TWO SIDES
		if ( kx > x && kz > z ) {
			sum += a3+a5;
		}
		//TWO SIDES
		if ( kx > x && kz < 0 ) {
			sum += a2+a5;
		}

		//one SIDE
		if ( (kx >= 0 && kx <= x) && kz < 0 ) {
			sum += a2;
		}
		//one SIDES
		if ( (kx >= 0 && kx <= x) && kz > z ) {
			sum += a3;
		}
		//one SIDES
		if ( kx > x && (kz >= 0 && kz <= z) ) {
			sum += a5;
		}
		//TWO SIDES
		if ( kx > 0 && (kz >= 0 && kz <= z) ) {
			sum += a4;
		}

		System.out.println(sum);

	}

}


import java.io.*;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int[] p = sc.nextIntArray(3);
        int[] b = sc.nextIntArray(3);
        int[] a = sc.nextIntArray(6);
        int ans = 0;
        if (p[0] < 0 && between(p[1], 0, b[1])) ans += a[4];
        if (p[1] < 0 && between(p[2], 0, b[2])) ans += a[0];
        if (p[2] < 0 && between(p[1], 0, b[1])) ans += a[2];
        if (p[0] >= b[0]) ans += a[5];
        if (p[1] >= b[1]) ans += a[1];
        if (p[2] >= b[2]) ans += a[3];

        out.println(ans);
        out.flush();
        out.close();
    }

    static boolean between(int x, int x2, int x3) {
        return x >= x2 && x <= x3;
    }

    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

        public Scanner(InputStream system) {
            br = new BufferedReader(new InputStreamReader(system));
        }

        public Scanner(String s) throws FileNotFoundException {

            br = new BufferedReader(new FileReader(new File(s)));
        }

        public String next() throws IOException {
            while (st == null || !st.hasMoreTokens()) st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }

        public String nextLine() throws IOException {
            return br.readLine();
        }

        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        public double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }

        public char nextChar() throws IOException {
            return next().charAt(0);
        }

        public Long nextLong() throws IOException {
            return Long.parseLong(next());
        }

        public boolean ready() throws IOException {
            return br.ready();
        }

        public int[] nextIntArray(int n) throws IOException {
            int[] a = new int[n];
            for (int i = 0; i < n; i++)
                a[i] = nextInt();
            return a;
        }

        public long[] nextLongArray(int n) throws IOException {
            long[] a = new long[n];
            for (int i = 0; i < n; i++)
                a[i] = nextLong();
            return a;
        }

        public Integer[] nextIntegerArray(int n) throws IOException {
            Integer[] a = new Integer[n];
            for (int i = 0; i < n; i++)
                a[i] = nextInt();
            return a;
        }

        public double[] nextDoubleArray(int n) throws IOException {
            double[] ans = new double[n];
            for (int i = 0; i < n; i++)
                ans[i] = nextDouble();
            return ans;
        }

        public short nextShort() throws IOException {
            return Short.parseShort(next());
        }

    }

}


import java.util.*;
import java.io.*;
public class MagicBox {

    /************************ SOLUTION STARTS HERE ************************/

    static final double EPS = 1e-9;
    static class Plane {
        double pt[];
        int fixed;  // This coordinate is constant for this particular plane
        double boundry[];
        Plane(double p[] , double b[] , int f) {
            pt = p;
            boundry = b;
            fixed = f;
        }
        boolean parallel(double line[][]) {
            return line[0][fixed] == 0;
        }
        boolean intersect(double line[][]) {   // line[0] = direction vector   line[1] = point in line
            double lambda = (double)(boundry[fixed] - line[1][fixed]) / line[0][fixed];
            double intersect[] = new double[3];
            for(int i = 0; i < 3; i++)
                intersect[i] = lambda * line[0][i] + line[1][i];

            boolean flag = true;
            // System.out.println("intersection " + Arrays.toString(intersect));

            for(int i = 0; i < 3; i++) {
                if(i == fixed)
                    flag &= intersect[i] == boundry[fixed];
                else
                    flag &= intersect[i] >= 0.0 && intersect[i] <= boundry[i];
            }

            return flag;
        }

        double distSq(double line[][]) {
            double lambda = (double)(boundry[fixed] - line[1][fixed]) / line[0][fixed];
            double intersect[] = new double[3];
            double dSq = 0;
            for(int i = 0; i < 3; i++) {
                intersect[i] = lambda * line[0][i] + line[1][i];
                dSq += Math.pow(intersect[i] - line[1][i], 2);
            }

            return dSq;
        }

    }

    private static void solve() {

        double curr[] = new double[3];
        for(int i = 0; i < 3; i++) curr[i] = nextDouble();

        double box[] = new double[3];
        for(int i = 0; i < 3; i++) box[i] = nextDouble();

        int A[] = nextIntArray(6);
        int perm[] = {1 ,2 ,0};
        int score = 0;

        Plane planes[] = new Plane[6];
        for(int i = 0; i < 6; i++) {
            double pt[] = new double[3];
            double b[] = new double[3];
            for(int j = 0; j < 3; j++) {
                if(j != perm[i / 2]) {
                    pt[j] = box[j] / 2.0;
                    b[j] = box[j];
                }
                else if(i % 2 == 1)
                    pt[j] = b[j] = box[j];
            }
            planes[i] = new Plane(pt, b, perm[i / 2]);
        }

        double payload[][] = new double[2][];

        for(int i = 0; i < 6; i++) {
            boolean flag = true;
            double dir[] = new double[3];
            for(int j = 0; j < 3; j++)
                dir[j] = curr[j] - planes[i].pt[j];

            payload[0] = dir;
            payload[1] = curr;
            if(!planes[i].parallel(payload)) {
                double thresh = planes[i].distSq(payload);
                for(int j = 0; j < 6; j++)
                    if(i != j && !planes[j].parallel(payload) && planes[j].intersect(payload))
                        flag &= planes[j].distSq(payload) >= thresh;

                score += flag ? A[i] : 0;
            }
        }

        println(score);
    }

    /************************ SOLUTION ENDS HERE ************************/

    /************************ TEMPLATE STARTS HERE **********************/

    public static void main(String[] args) throws IOException {
        reader = new BufferedReader(new InputStreamReader(System.in));
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)), false);
        st     = null;
        solve();
        reader.close();
        writer.close();
    }

    static BufferedReader reader;
    static PrintWriter    writer;
    static StringTokenizer st;

    static String next()
    {while(st == null || !st.hasMoreTokens()){try{String line = reader.readLine();if(line == null){return null;}
    st = new StringTokenizer(line);}catch (Exception e){throw new RuntimeException();}}return st.nextToken();}
    static String nextLine()  {String s=null;try{s=reader.readLine();}catch(IOException e){e.printStackTrace();}return s;}
    static int    nextInt()   {return Integer.parseInt(next());}
    static long   nextLong()  {return Long.parseLong(next());}
    static double nextDouble(){return Double.parseDouble(next());}
    static char   nextChar()  {return next().charAt(0);}
    static int[]  nextIntArray(int n)         {int[] a= new int[n];   int i=0;while(i<n){a[i++]=nextInt();}  return a;}
    static long[] nextLongArray(int n)        {long[]a= new long[n];  int i=0;while(i<n){a[i++]=nextLong();} return a;}
    static int[]  nextIntArrayOneBased(int n) {int[] a= new int[n+1]; int i=1;while(i<=n){a[i++]=nextInt();} return a;}
    static long[] nextLongArrayOneBased(int n){long[]a= new long[n+1];int i=1;while(i<=n){a[i++]=nextLong();}return a;}
    static void   print(Object o)  { writer.print(o);  }
    static void   println(Object o){ writer.println(o);}

    /************************ TEMPLATE ENDS HERE ************************/

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class MikeAndFrog {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        int m = Integer.parseInt(br.readLine());
        st = new StringTokenizer(br.readLine());
        int h1 = Integer.parseInt(st.nextToken()), a1 = Integer.parseInt(st.nextToken());
        st = new StringTokenizer(br.readLine());
        int x1 = Integer.parseInt(st.nextToken()), y1 = Integer.parseInt(st.nextToken());
        st = new StringTokenizer(br.readLine());
        int h2 = Integer.parseInt(st.nextToken()), a2 = Integer.parseInt(st.nextToken());
        st = new StringTokenizer(br.readLine());
        int x2 = Integer.parseInt(st.nextToken()), y2 = Integer.parseInt(st.nextToken());

        int start = h1, current = h1;
        boolean flag1 = false;
        ArrayList<Integer> frog = new ArrayList<Integer>();
        do {
            frog.add(current);
            current = (x1 * current + y1) % m;
            if (current == a1) {
                flag1 = true;
            }

        } while (current != start);

        start = h2; current = h2;
        boolean flag2 = false;
        ArrayList<Integer> flower = new ArrayList<Integer>();
        do {
            flower.add(current);
            current = (x2 * current + y2) % m;
            if (current == a2) {
                flag2 = true;
            }

        } while (current != start);

        int l1 = frog.size(), l2 = flower.size();
        if (l1 == 1 || l2 == 1 || !flag1 || !flag2) {
            System.out.println(-1);
            return;
        }

        int seconds = 0;
        for (int i = 0; i < l1; i++) {
            if (frog.get(i) == a1) {
                break;
            }
            seconds++;
        }

        int position = seconds % l2;
        current = flower.get(position);
        boolean[] visited = new boolean[m];
        while (!visited[current]) {
            if (current == a2) {
                System.out.println(seconds);
                return;
            }
            visited[current] = true;

            seconds += l1;
            position += l1;
            position %= l2;
            current = flower.get(position);
        }

        System.out.println(-1);
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Codeforces548C {
	public static int newHeight(int x1, int y1, int m, int oldH)
	{
		long result = ((long) x1)*oldH + y1;
		return (int) (result%m);
	}
	public static int numStepsToGetTo(int x1, int y1, int m, int start, int end)
	{
		int steps = 0;
		int initial = start;
		boolean[] visited = new boolean[m];
		while(initial != end && !visited[initial])
		{
			steps++;
			visited[initial] = true;
			initial = newHeight(x1, y1, m, initial);
		}
		if(initial != end)
			return -1;
		else
			return steps;
	}
	public static void main(String[] args) {
		try
		{
			BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
			int m = Integer.parseInt(f.readLine());
			StringTokenizer st = new StringTokenizer(f.readLine());
			int h1 = Integer.parseInt(st.nextToken());
			int a1 = Integer.parseInt(st.nextToken());
			st = new StringTokenizer(f.readLine());
			int x1 = Integer.parseInt(st.nextToken());
			int y1 = Integer.parseInt(st.nextToken());
			st = new StringTokenizer(f.readLine());
			int h2 = Integer.parseInt(st.nextToken());
			int a2 = Integer.parseInt(st.nextToken());
			st = new StringTokenizer(f.readLine());
			int x2 = Integer.parseInt(st.nextToken());
			int y2 = Integer.parseInt(st.nextToken());
			f.close();
			int h1ToA1 = numStepsToGetTo(x1, y1, m, h1, a1);
			int h2ToA2 = numStepsToGetTo(x2, y2, m, h2, a2);
			if(h1ToA1 == -1 || h2ToA2 == -1)
				System.out.println(-1);
			else
			{
				 if((h1ToA1 == h2ToA2) && (h1ToA1 != 0))
					System.out.println(h1ToA1);

				else
				{
					int period1 = 1 + numStepsToGetTo(x1, y1, m, newHeight(x1, y1, m, a1), (int) a1);
					int period2 = 1 + numStepsToGetTo(x2, y2, m, newHeight(x2, y2, m, a2), (int) a2);
					long result = h1ToA1;
					boolean found = false;
					for(int i = 0; i < period2; i++)
					{
						if(result%period2 == h2ToA2)
						{
							found = true;
							break;
						}
						result += period1;
					}
					if(found)
						System.out.println(result);
					else
						System.out.println(-1);
				//}
			}
		}
		catch(IOException e)
		{
			System.out.println(e);
		}

	}

}


//package codeforces;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Scanner;

public class MikeAndFrog {

	public static void main(String[] args) {

		Scanner scanner = new Scanner(System.in);

		long m = scanner.nextLong();

		long h1 = scanner.nextLong();
		long a1 = scanner.nextLong();
		long x1 = scanner.nextLong();
		long y1 = scanner.nextLong();

		long h2 = scanner.nextLong();
		long a2 = scanner.nextLong();
		long x2 = scanner.nextLong();
		long y2 = scanner.nextLong();

		ArrayList<Long> list1 = new ArrayList<Long>();
		ArrayList<Long> list2 = new ArrayList<Long>();

		for (long i = 1; i <= 3 * m; ++i) {

			h1 = (x1 * h1 + y1) % m;
			h2 = (x2 * h2 + y2) % m;

			if (h1 == a1)
				list1.add(i);

			if (h2 == a2)
				list2.add(i);

			if (list1.size() >= 2 && list2.size() >= 2)
				break;

		}

		if (list1.isEmpty() || list2.isEmpty()) {
			System.out.println(-1);
			return;
		}

		long n1 = list1.get(0);
		long n2 = list2.get(0);

		if (n1 == n2) {
			System.out.println(n1);
			return;
		}

		if (list1.size() == 1 && list2.size() == 1) {
			System.out.println(-1);
			return;
		}

		if (list1.size() == 1)
			if ((n1 - n2) % (list2.get(1) - list2.get(0)) == 0) {
				System.out.println(n1);
				return;
			} else {
				System.out.println(-1);
				return;
			}

		if (list2.size() == 1)
//			if ((n2 - n1) % (list1.get(1) - list1.get(0)) == 0) {
//				System.out.println(n2);
//				return;
//			} else {
				System.out.println(-1);
				return;
			//}

		long l1 = list1.get(1) - list1.get(0);
		long l2 = list2.get(1) - list2.get(0);

		for (long i = 0; i < 5000000; ++i) {
			if (n1 == n2) {
				System.out.println(n1);
				return;
			}
			if (n2 < n1)
				n2 += l2;
			else
				n1 += l1;

		}
		System.out.println(-1);

	}

}


//package codeforces;

import java.math.BigLongeger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Scanner;

public class MikeAndFrog {

	public static void main(String[] args) {

		Scanner scanner = new Scanner(System.in);

		long m = scanner.nextLong();

		long h1 = scanner.nextLong();
		long a1 = scanner.nextLong();
		long x1 = scanner.nextLong();
		long y1 = scanner.nextLong();

		long h2 = scanner.nextLong();
		long a2 = scanner.nextLong();
		long x2 = scanner.nextLong();
		long y2 = scanner.nextLong();

		long res1 = h1, res2 = h2;
		long n = 1;
		long pw = 0;

		HashSet<String> set= new HashSet<String>();

		while (true) {

			pw = (long) Math.pow(x1, n);

			if (x1 == 1)
				res1 = (pw * res1 + y1 * n) % m;
			else
				res1 = (pw * res1 + y1 * ((1 - pw) / (1 - x1))) % m;

			pw = (long) Math.pow(x2, n);
			if (x2 == 1)
				res2 = (pw * res2 + y2 * n) % m;
			else
				res2 = (pw * res2 + y2 * ((1 - pw) / (1 - x2))) % m;

			if (res1 == a1 && res2 == a2) {
				System.out.println(n+1);
				return;
			}

			if (set.contains(res1+""+res2)){
				System.out.println(-1);
				return;
			}
			else
				set.add(res1+""+res2);

			n++;

		}

	}

}


import java.io.*;
import java.util.*;

public class Test {
	static BufferedReader reader;
	static StringTokenizer tokenizer;
	static PrintWriter writer;

	static int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	static long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	static double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}

	static String nextToken() throws IOException {
		while (tokenizer == null || !tokenizer.hasMoreTokens()) {
			tokenizer = new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}

	public static void main(String[] args) throws IOException {
		reader = new BufferedReader(new InputStreamReader(System.in));
		boolean oj = System.getProperty("ONLINE_JUDGE") != null;
		if (!oj) {
			File file = new File("inn.txt");
			if (file.exists() && file.canRead()) {
				reader = new BufferedReader(new InputStreamReader(
						new FileInputStream(file)));
			}
		}
		tokenizer = null;
		writer = new PrintWriter(System.out);
		banana();
		reader.close();
		writer.close();
	}

	static boolean check(int n, int x, int y, int[][] coord) {
		for (int i = 0; i < n; i++) {
			if (x >= coord[0][i] && x <= coord[2][i] && y >= coord[1][i]
					&& y <= coord[3][i]) {
				return true;
			}
		}
		return false;
	}

	private static void banana() throws IOException {
		int n = nextInt();
		int[][] coord = new int[4][n];

		for (int i = 0; i < n; i++) {
			for (int t = 0; t < 4; t++) {
				coord[t][i] = nextInt();
			}
		}

		int minx = 1000000;
		int miny = 1000000;
		int maxx = -1;
		int maxy = -1;

		for (int i = 0; i < n; i++) {
			if (coord[0][i] < minx)
				minx = coord[0][i];
			if (coord[2][i] > maxx)
				maxx = coord[2][i];
			if (coord[1][i] < miny)
				miny = coord[1][i];
			if (coord[3][i] > maxy)
				maxy = coord[3][i];
		}

		if (maxx - minx != maxy - miny) {
			writer.println("NO");
			return;
		}

		int[][] newcoord = new int[2][2 * n];
		for (int i = 0; i < n; i++) {
			newcoord[0][i] = coord[0][i];
		}
		for (int i = 0; i < n; i++) {
			newcoord[0][n + i] = coord[2][i];
		}
		for (int i = 0; i < n; i++) {
			newcoord[1][i] = coord[1][i];
		}
		for (int i = 0; i < n; i++) {
			newcoord[1][n + i] = coord[3][i];
		}

		for (int t = 0; t < 2; t++) {
			Arrays.sort(newcoord[t]);
		}

		for (int t = 0; t < 4; t++) {
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < 2 * n; j++) {
					if (coord[t][i] == newcoord[t % 2][j]) {
						coord[t][i] = 2 * j;
						break;
					}
				}
			}
		}

		minx = 1000000;
		miny = 1000000;
		maxx = -1;
		maxy = -1;

		for (int i = 0; i < n; i++) {
			if (coord[0][i] < minx)
				minx = coord[0][i];
			if (coord[2][i] > maxx)
				maxx = coord[2][i];
			if (coord[1][i] < miny)
				miny = coord[1][i];
			if (coord[3][i] > maxy)
				maxy = coord[3][i];
		}

//		for (int i = 0; i < n; i++) {
//			for (int t = 0; t < 4; t++) {
//				writer.print(coord[t][i] + " ");
//			}
//			writer.println();
//		}

		for (int x = minx; x <= maxx; x++) {
			for (int y = miny; y <= maxy; y++) {
				//System.err.println(x + " " + y);
				if (check(n, x, y, coord) == false) {
					writer.println("NO");
					return;
				}
			}
		}
		writer.println("YES");
	}
}


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
import java.util.TreeSet;

/**
 * User: ������
 * Date: 13.07.2013
 * Time: 20:48:59
 */
public class MemSQL_Round1_A {
    Scanner scanner = new Scanner(System.in);
    BufferedReader buffered = new BufferedReader(new InputStreamReader(System.in));
    StreamTokenizer in = new StreamTokenizer(buffered);

    PrintWriter out = new PrintWriter(System.out);

    int nextInt() throws Exception {
        in.nextToken();
        return (int) in.nval;
    }

    void main() throws Exception {
        int n = nextInt();
        int[] x1 = new int[n];
        int[] y1 = new int[n];
        int[] x2 = new int[n];
        int[] y2 = new int[n];
        for (int i=0; i<n; i++) {
            x1[i] = nextInt();
            y1[i] = nextInt();
            x2[i] = nextInt()-1;
            y2[i] = nextInt()-1;
        }

        boolean bingo = true;
        TreeSet<Integer> xmin = new TreeSet<Integer>();
        TreeSet<Integer> xmax = new TreeSet<Integer>();
        Integer ymin = null;
        Integer ymax = null;
        for (int Y=0; Y<32000; Y++) {
            ArrayList<Integer> X1 = new ArrayList<Integer>();
            ArrayList<Integer> X2 = new ArrayList<Integer>();
            for (int i=0; i<n; i++) {
                if (y1[i] <= Y && y2[i] >= Y) {
                    X1.add(x1[i]);
                    X2.add(x2[i]);
                }
            }

            Collections.sort(X1);
            Collections.sort(X2);

            for (int i=1; i<X1.size(); i++) {
                if (!X1.get(i).equals(X2.get(i-1) + 1)) {
                    bingo = false;
                }
            }

            if (!X1.isEmpty()) {
                xmin.add(X1.get(0));
                xmax.add(X2.get(X2.size()-1));
                if (ymin == null) {
                    ymin = Y;
                }
                ymax = Y;
            }
        }

        if (bingo && xmin.size() == 1 && xmax.size() == 1 && (ymax-ymin) == (xmax.first() - xmin.first())) {
            out.println("YES");
        } else {
            out.println("NO");
        }
        out.flush();
        out.close();
    }

    public static void main(String[] args) throws Exception {
        new MemSQL_Round1_A().main();
    }
}


//package codeforces.train;
import java.io.*;

public class ProblemA {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    PrintWriter writer = new PrintWriter(new OutputStreamWriter(System.out));

    int[] readInts() throws IOException {
        String[] strings = reader.readLine().split(" ");
        int[] ints = new int[strings.length];
        for(int i = 0; i < ints.length; i++) {
            ints[i] = Integer.parseInt(strings[i]);
        }
        return ints;
    }

    long[] ttl = null;
    int txl = 0;
    long readLong() throws IOException {
        if(ttl == null || txl >= ttl.length) {
            ttl = readLongs();
            txl = 0;
        }
        return ttl[txl++];
    }

    long[] readLongs() throws IOException {
        String[] strings = reader.readLine().split(" ");
        long[] longs = new long[strings.length];
        for(int i = 0; i < longs.length; i++) {
            longs[i] = Long.parseLong(strings[i]);
        }
        return longs;
    }

    int[] tt = null;
    int tx = 0;
    int readInt() throws IOException {
        if(tt == null || tx >= tt.length) {
            tt = readInts();
            tx = 0;
        }
        return tt[tx++];
    }

    void solve() throws IOException {
        int n = readInt();
        int[] x1 = new int[n];
        int[] x2 = new int[n];
        int[] y1 = new int[n];
        int[] y2 = new int[n];
        for(int i = 0; i < n; i++) {
            x1[i] = readInt();
            y1[i] = readInt();
            x2[i] = readInt();
            y2[i] = readInt();
        }
        for(int i = 1; i < 1 << n; i++) {
            int minx = Integer.MAX_VALUE;
            int miny = Integer.MAX_VALUE;
            int maxx = 0, maxy = 0;
            int s = 0;
            for(int j = 0; j < n; j++) {
                if(((i >> j) & 1) > 0) {
                    minx = Math.min(minx, x1[j]);
                    maxx = Math.max(maxx, x2[j]);
                    miny = Math.min(miny, y1[j]);
                    maxy = Math.max(maxy, y2[j]);
                    s += (x2[j] - x1[j]) * (y2[j] - y1[j]);
                }
            }
            if(maxx - minx == maxy - miny && (maxy - miny) * (maxx - minx) == s) {
                writer.println("YES");
                writer.flush();
                return;
            }
        }
        writer.println("NO");

        writer.flush();
    }

    void multiSolve() throws IOException {
        int n = readInts()[0];
        for(int i = 0; i < n; i++) {
            if(i > 0) writer.println();
            solve();
        }
    }

    public static void main(String[] args) throws IOException{
        new ProblemA().solve();
    }
}


import java.util.*;
import java.math.*;
import java.io.*;

public class Main
	{
	/*
	 * Simple bitmask code for boolean isset, int set and int clr
	 */
	public static boolean isset(int n,int i) //returns 1 if the ith bit (from left) of n is set
		{
		return ((n>>i)&1)==1;
		}
	public static void main(String args[]) throws IOException
		{
		InputReader in=new InputReader(System.in);
		PrintWriter out=new PrintWriter(System.out);
		int n=in.readInt();
		Rectangle R[]=new Rectangle[n];
		for(int i=0;i<n;i++)
			R[i]=new Rectangle(in.readInt(),in.readInt(),in.readInt(),in.readInt());

		for(int i=1;i<(1<<n);i++)
			{
			LinkedList<Rectangle> L=new LinkedList<Rectangle>();
			for(int j=0;j<n;j++)
				{
				if(isset(i,j))
					L.add(R[j]);
				}
			int num=L.size();
			Rectangle RT[]=new Rectangle[num];
			for(int j=0;j<num;j++)
				RT[j]=L.pollFirst();
			if(check(RT))
				{
				System.out.println("YES");
				return;
				}
			}
		System.out.println("NO");
		out.close();
		}

	private static boolean check(Rectangle[] RT)
		{
		/*System.out.println("For ");
		for(Rectangle r:RT)
			System.out.println("\t"+r.x1+" "+r.y1+" "+r.x2+" "+r.y2);*/
		long totArea=0;
		for(Rectangle r:RT)
			totArea+=(r.x2-r.x1)*(r.y2-r.y1);
		int upperCornerIndex=-1,lowerCornerIndex=-1;
		int N=RT.length;

		//upper right
		for(int i=0;i<N;i++)
			{
			boolean valid=true;
			for(int j=0;j<N;j++)
				{
				if(RT[i].x2>=RT[j].x2&&RT[i].y2>=RT[j].y2)
					continue;
				else
					valid=false;
				}
			if(valid)
				upperCornerIndex=i;
			}

		//bottom left
		for(int i=0;i<N;i++)
			{
			boolean valid=true;
			for(int j=0;j<N;j++)
				{
				if(RT[i].x1<=RT[j].x1&&RT[i].y1<=RT[j].y1)
					continue;
				else
					valid=false;
				}
			if(valid)
				lowerCornerIndex=i;
			}
		if(upperCornerIndex==-1||lowerCornerIndex==-1)
			return false;
		//System.out.println("\tIndices: "+upperCornerIndex+" "+lowerCornerIndex);
		long yLen=RT[upperCornerIndex].y2-RT[lowerCornerIndex].y1;
		long xLen=RT[upperCornerIndex].x2-RT[lowerCornerIndex].x1;
		if(xLen != yLen)
			return false;
		if(xLen*yLen!=totArea)
			return false;
		/*System.out.println("True for ");
		for(Rectangle r:RT)
			System.out.println("\t"+r.x1+" "+r.y1+" "+r.x2+" "+r.y2);*/
		return true;
		}
	}

class Rectangle
	{
	long x1,y1,x2,y2;

	public Rectangle(int x1,int y1,int x2,int y2)
		{
		this.x1=x1;
		this.y1=y1;
		this.x2=x2;
		this.y2=y2;
		}

	}
class InputReader
	{
	private InputStream stream;
	private byte[] buf=new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

	public InputReader(InputStream stream)
		{
		this.stream=stream;
		}

	public int read()
		{
		if(numChars==-1)
			throw new InputMismatchException();
		if(curChar>=numChars)
			{
			curChar=0;
			try
				{
				numChars=stream.read(buf);
				} catch (IOException e)
				{
				throw new InputMismatchException();
				}
			if(numChars<=0)
				return -1;
			}
		return buf[curChar++];
		}

	public int readInt()
		{
		int c=read();
		while (isSpaceChar(c))
			c=read();
		int sgn=1;
		if(c=='-')
			{
			sgn=-1;
			c=read();
			}
		int res=0;
		do
			{
			if(c<'0'||c>'9')
				throw new InputMismatchException();
			res*=10;
			res+=c-'0';
			c=read();
			} while (!isSpaceChar(c));
		return res*sgn;
		}

	public boolean isSpaceChar(int c)
		{
		if(filter!=null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
		}

	public static boolean isWhitespace(int c)
		{
		return c==' '||c=='\n'||c=='\r'||c=='\t'||c==-1;
		}

	public char readCharacter()
		{
		int c=read();
		while (isSpaceChar(c))
			c=read();
		return (char) c;
		}

	public interface SpaceCharFilter
		{
		public boolean isSpaceChar(int ch);
		}
	}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.IOException;
import java.util.HashMap;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Map;
import java.io.BufferedReader;
import java.util.Collections;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		FastScanner in = new FastScanner(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskE solver = new TaskE();
		int testCount = Integer.parseInt(in.next());
		for (int i = 1; i <= testCount; i++)
			solver.solve(i, in, out);
		out.close();
	}

	static class TaskE {
		final double eps = 1e-8;
		final long MAX_COORD = (int) 1e6;
		long MIN_X;
		long MIN_Y;
		long MAX_X;
		long MAX_Y;

		public void solve(int testNumber, FastScanner in, PrintWriter out) {
			int n = in.nextInt() - 1;
			long x0 = in.nextLong();
			long y0 = in.nextLong();
			MIN_X = -MAX_COORD - x0;
			MAX_X = +MAX_COORD - x0;
			MIN_Y = -MAX_COORD - y0;
			MAX_Y = +MAX_COORD - y0;
			PointLong[] p = new PointLong[n];
			for (int i = 0; i < n; i++) {
				long x = in.nextLong() - x0;
				long y = in.nextLong() - y0;
				p[i] = new PointLong(x, y);
			}
			Arrays.sort(p, (a, b) -> {
				boolean au = a.y > 0 || a.y == 0 && a.x > 0;
				boolean bu = b.y > 0 || b.y == 0 && b.x > 0;
				if (au != bu) {
					return au ? 1 : -1;
				}
				return -Long.signum(cross(a, b));
			});

			{
				int j = 0;
				for (int i = 0; i < n; i++) {
					j = Math.max(j, i + 1);
					while (cross(p[i], p[j % n]) > 0) {
						++j;
					}
					if (i != j % n && cross(p[i], p[j % n]) == 0) {
						out.println(0);
						return;
					}
					if (i != (i + 1) % n && cross(p[i], p[(i + 1) % n]) == 0) {
						out.println(0);
						return;
					}
				}
			}

			List<Line> lines = new ArrayList<>();
			{
				int j = 0;
				int best = -1;
				for (int i = 0; i < n; i++) {
					if (best >= 0 && cross(p[i], p[best]) <= 0) {
						best = -1;
					}
					if (i == j) {
						++j;
						if (j == n) j = 0;
					}
					while (cross(p[i], p[j]) > 0) {
						if (best < 0 || cross(p[best].sub(p[i]), p[j].sub(p[i])) > 0) {
							best = j;
						}
						++j;
						if (j == n) j = 0;
					}
					while (cross(p[i], p[j]) < 0) {
						--j;
						if (j < 0) j = n - 1;
					}
					if (best >= 0) {
						lines.add(new Line(p[i].toDoublePoint(), p[best].toDoublePoint()));
					}
				}
			}
			{
				int j = 0;
				for (int i = 0; i < n; i++) {
					++j;
					if (j == n) j = 0;
					if (cross(p[i], p[j]) > 0) {
						lines.add(new Line(p[i].toDoublePoint(), p[j].toDoublePoint()));
					}
				}
			}

//		List<Line> lines = new ArrayList<>();
//		for (int i = 0; i < n; i++) {
//			for (int j = 0; j < n; j++) {
//				if (cross(p[i], p[j]) > 0) {
//					lines.add(new Line(p[i].toDoublePoint(), p[j].toDoublePoint()));
//				}
//			}
//		}

			out.printf("%.15f\n", area(intersectSemiplanes(lines.toArray(new Line[0]))));
		}

		private double area(Point[] p) {
			if (p == null) {
				return 0;
			}
			double res = 0;
			for (int i = 0; i < p.length; i++) {
				int j = (i + 1) % p.length;
				res += (p[j].x - p[i].x) * (p[i].y + p[j].y);
			}
			return 0.5 * Math.abs(res);
		}

		private int compare(double a, double b) {
			if (Math.abs(a - b) < eps) {
				return 0;
			}
			return Double.compare(a, b);
		}

		private int sign(double x) {
			return compare(x, 0);
		}

		private double side(Point p, Line L) {
			return compare(p.x * L.a + p.y * L.b + L.c, 0);
		}

		private Point intersect(Line L1, Line L2) {
			double det = L1.a * L2.b - L2.a * L1.b;
			if (compare(det, 0) == 0) {
				return null;
			}
			double x = -(L1.c * L2.b - L2.c * L1.b) / det;
			double y = -(L1.a * L2.c - L2.a * L1.c) / det;
			return new Point(x, y);
		}

		private Point[] intersectSemiplanes(Line[] input) {
			List<Line> correctedInput = new ArrayList<>();
			for (Line L : input) {
				correctedInput.add(L);
			}
			Point[] corners = new Point[4];
			corners[0] = new Point(MIN_X, MIN_Y);
			corners[1] = new Point(MAX_X, MIN_Y);
			corners[2] = new Point(MAX_X, MAX_Y);
			corners[3] = new Point(MIN_X, MAX_Y);
			for (int i = 0; i < 4; i++) {
				correctedInput.add(new Line(corners[i], corners[(i + 1) % 4]));
			}

			Collections.sort(correctedInput, (L1, L2) -> {
				double ax = -L1.b, ay = L1.a;
				double bx = -L2.b, by = L2.a;
				boolean au = ay > 0 || (Math.abs(ay) < eps && ax > 0);
				boolean bu = by > 0 || (Math.abs(by) < eps && bx > 0);
				if (au != bu) {
					return au ? 1 : -1;
				}
				int s = -sign(ax * by - ay * bx);
				if (s != 0) {
					return s;
				}
				Point test = L1.anyPoint();
				return side(test, L2) > 0 ? -1 : 1;
			});

			for (int i = correctedInput.size() - 1; i > 0; i--) {
				Line L1 = correctedInput.get(i);
				Line L2 = correctedInput.get(i - 1);
				double ax = -L1.b, ay = L1.a;
				double bx = -L2.b, by = L2.a;
				int d = sign(ax * bx + ay * by);
				int s = -sign(ax * by - ay * bx);
				if (d >= 0 && s == 0) {
					correctedInput.remove(i);
				}
			}

			Line[] borders = correctedInput.toArray(new Line[0]);
			List<Object> list = new ArrayList<>();
			list.add(borders[0]);
			list.add(intersect(borders[0], borders[1]));
			list.add(borders[1]);

			for (int i = 2; i < 2 * borders.length; i++) {
				Line L = borders[i % borders.length];
				while (list.size() >= 2) {
					Object o1 = list.get(list.size() - 2);
					Object o2 = list.get(list.size() - 1);
					if ((o1 instanceof Point) && (o2 instanceof Line)) {
						Point p = (Point) o1;
						if (side(p, L) > 0) {
							break;
						}
						list.remove(list.size() - 1);
						list.remove(list.size() - 1);
					} else {
						throw new AssertionError();
					}
				}
				Object obj = list.get(list.size() - 1);
				if (obj instanceof Line) {
					Line v = (Line) obj;
					if (sign(v.a * L.b - v.b * L.a) <= 0) {
						return null;
					}
					Point p = intersect(v, L);
					list.add(p);
					list.add(L);
				} else {
					throw new AssertionError();
				}
			}

			Map<Line, Integer> where = new HashMap<>();
			List<Line> allLines = new ArrayList<>();
			List<Point> res = new ArrayList<>();
			for (int i = 0; i < list.size(); i += 2) {
				Line L = (Line) list.get(i);
				allLines.add(L);
				if (where.containsKey(L)) {
					for (int j = where.get(L); j < allLines.size() - 1; j++) {
						res.add(intersect(allLines.get(j), allLines.get(j + 1)));
					}
					break;
				}
				where.put(L, i / 2);
			}
			return res.toArray(new Point[0]);
		}

		private long cross(PointLong a, PointLong b) {
			return a.x * b.y - a.y * b.x;
		}

		class Point {
			double x;
			double y;

			Point(double x, double y) {
				this.x = x;
				this.y = y;
			}

			public String toString() {
				return "(" + x + " " + y + ")";
				//return String.format("(%.4f %.4f)", x, y);
			}

		}

		class Line {
			double a;
			double b;
			double c;
			Point anyPoint;

			Line(double a, double b, double c) {
				this.a = a;
				this.b = b;
				this.c = c;
			}

			Line(Point p1, Point p2) {
				a = p1.y - p2.y;
				b = p2.x - p1.x;
				c = -a * p1.x - b * p1.y;
				double len = Math.sqrt(a * a + b * b);
				a /= len;
				b /= len;
				c /= len;
				anyPoint = p1;
			}

			Point anyPoint() {
				if (anyPoint != null) {
					return anyPoint;
				}
				if (Math.abs(b) < eps) {
					if (Math.abs(a) < eps) {
						throw new AssertionError();
					}
					return new Point(-c / a, 0);
				}
				return new Point(0, -c / b);
			}

			public String toString() {
				return a + " " + b + " " + c;
			}

		}

		class PointLong {
			long x;
			long y;

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

			PointLong sub(PointLong o) {
				return new PointLong(x - o.x, y - o.y);
			}

			Point toDoublePoint() {
				return new Point(x, y);
			}

			public String toString() {
				return "(" + x + " " + y + ")";
			}

		}

	}

	static class FastScanner {
		private BufferedReader in;
		private StringTokenizer st;

		public FastScanner(InputStream stream) {
			in = new BufferedReader(new InputStreamReader(stream));
		}

		public String next() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(in.readLine());
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
			return st.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.IOException;
import java.util.HashMap;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Map;
import java.io.BufferedReader;
import java.util.Collections;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		FastScanner in = new FastScanner(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskE solver = new TaskE();
		int testCount = Integer.parseInt(in.next());
		for (int i = 1; i <= testCount; i++)
			solver.solve(i, in, out);
		out.close();
	}

	static class TaskE {
		final double eps = 1e-15;
		final long MAX_COORD = (int) 1e6;
		long MIN_X;
		long MIN_Y;
		long MAX_X;
		long MAX_Y;

		public void solve(int testNumber, FastScanner in, PrintWriter out) {
			int n = in.nextInt() - 1;
			long x0 = in.nextLong();
			long y0 = in.nextLong();
			MIN_X = -MAX_COORD - x0;
			MAX_X = +MAX_COORD - x0;
			MIN_Y = -MAX_COORD - y0;
			MAX_Y = +MAX_COORD - y0;
			PointLong[] p = new PointLong[n];
			for (int i = 0; i < n; i++) {
				long x = in.nextLong() - x0;
				long y = in.nextLong() - y0;
				p[i] = new PointLong(x, y);
			}
			Arrays.sort(p, (a, b) -> {
				boolean au = a.y > 0 || a.y == 0 && a.x > 0;
				boolean bu = b.y > 0 || b.y == 0 && b.x > 0;
				if (au != bu) {
					return au ? 1 : -1;
				}
				return -Long.signum(cross(a, b));
			});

			{
				int j = 0;
				for (int i = 0; i < n; i++) {
					j = Math.max(j, i + 1);
					while (cross(p[i], p[j % n]) > 0) {
						++j;
					}
					if (i != j % n && cross(p[i], p[j % n]) == 0) {
						out.println(0);
						return;
					}
					if (i != (i + 1) % n && cross(p[i], p[(i + 1) % n]) == 0) {
						out.println(0);
						return;
					}
				}
			}

			List<Line> lines = new ArrayList<>();
			{
				int j = 0;
				int best = -1;
				for (int i = 0; i < n; i++) {
					if (best >= 0 && cross(p[i], p[best]) <= 0) {
						best = -1;
					}
					if (i == j) {
						++j;
						if (j == n) j = 0;
					}
					while (cross(p[i], p[j]) > 0) {
						if (best < 0 || cross(p[best].sub(p[i]), p[j].sub(p[i])) > 0) {
							best = j;
						}
						++j;
						if (j == n) j = 0;
					}
					while (cross(p[i], p[j]) < 0) {
						--j;
						if (j < 0) j = n - 1;
					}
					if (best >= 0) {
						lines.add(new Line(p[i].toDoublePoint(), p[best].toDoublePoint()));
					}
				}
			}
			{
				int j = 0;
				for (int i = 0; i < n; i++) {
					++j;
					if (j == n) j = 0;
					if (cross(p[i], p[j]) > 0) {
						lines.add(new Line(p[i].toDoublePoint(), p[j].toDoublePoint()));
					}
				}
			}

//		List<Line> lines = new ArrayList<>();
//		for (int i = 0; i < n; i++) {
//			for (int j = 0; j < n; j++) {
//				if (cross(p[i], p[j]) > 0) {
//					lines.add(new Line(p[i].toDoublePoint(), p[j].toDoublePoint()));
//				}
//			}
//		}

			out.printf("%.15f\n", area(intersectSemiplanes(lines.toArray(new Line[0]))));
		}

		private double area(Point[] p) {
			if (p == null) {
				return 0;
			}
			double res = 0;
			for (int i = 0; i < p.length; i++) {
				int j = (i + 1) % p.length;
				res += (p[j].x - p[i].x) * (p[i].y + p[j].y);
			}
			return 0.5 * Math.abs(res);
		}

		private int compare(double a, double b) {
			if (Math.abs(a - b) < eps) {
				return 0;
			}
			return Double.compare(a, b);
		}

		private int sign(double x) {
			return compare(x, 0);
		}

		private double side(Point p, Line L) {
			return compare(p.x * L.a + p.y * L.b + L.c, 0);
		}

		private Point intersect(Line L1, Line L2) {
			double det = L1.a * L2.b - L2.a * L1.b;
			if (compare(det, 0) == 0) {
				return null;
			}
			double x = -(L1.c * L2.b - L2.c * L1.b) / det;
			double y = -(L1.a * L2.c - L2.a * L1.c) / det;
			return new Point(x, y);
		}

		private Point[] intersectSemiplanes(Line[] input) {
			List<Line> correctedInput = new ArrayList<>();
			for (Line L : input) {
				correctedInput.add(L);
			}
			Point[] corners = new Point[4];
			corners[0] = new Point(MIN_X, MIN_Y);
			corners[1] = new Point(MAX_X, MIN_Y);
			corners[2] = new Point(MAX_X, MAX_Y);
			corners[3] = new Point(MIN_X, MAX_Y);
			for (int i = 0; i < 4; i++) {
				correctedInput.add(new Line(corners[i], corners[(i + 1) % 4]));
			}

			Collections.sort(correctedInput, (L1, L2) -> {
				double ax = -L1.b, ay = L1.a;
				double bx = -L2.b, by = L2.a;
				boolean au = ay > 0 || (Math.abs(ay) < eps && ax > 0);
				boolean bu = by > 0 || (Math.abs(by) < eps && bx > 0);
				if (au != bu) {
					return au ? 1 : -1;
				}
				int s = -sign(ax * by - ay * bx);
				if (s != 0) {
					return s;
				}
				Point test = L1.anyPoint();
				return side(test, L2) > 0 ? -1 : 1;
			});

			for (int i = correctedInput.size() - 1; i > 0; i--) {
				Line L1 = correctedInput.get(i);
				Line L2 = correctedInput.get(i - 1);
				double ax = -L1.b, ay = L1.a;
				double bx = -L2.b, by = L2.a;
				int d = sign(ax * bx + ay * by);
				int s = -sign(ax * by - ay * bx);
				if (d >= 0 && s == 0) {
					correctedInput.remove(i);
				}
			}

			Line[] borders = correctedInput.toArray(new Line[0]);
			List<Object> list = new ArrayList<>();
			list.add(borders[0]);
			list.add(intersect(borders[0], borders[1]));
			list.add(borders[1]);

			for (int i = 2; i < 2 * borders.length; i++) {
				Line L = borders[i % borders.length];
				while (list.size() >= 2) {
					Object o1 = list.get(list.size() - 2);
					Object o2 = list.get(list.size() - 1);
					if ((o1 instanceof Point) && (o2 instanceof Line)) {
						Point p = (Point) o1;
						if (side(p, L) > 0) {
							break;
						}
						list.remove(list.size() - 1);
						list.remove(list.size() - 1);
					} else {
						throw new AssertionError();
					}
				}
				Object obj = list.get(list.size() - 1);
				if (obj instanceof Line) {
					Line v = (Line) obj;
					if (sign(v.a * L.b - v.b * L.a) <= 0) {
						return null;
					}
					Point p = intersect(v, L);
					list.add(p);
					list.add(L);
				} else {
					throw new AssertionError();
				}
			}

			Map<Line, Integer> where = new HashMap<>();
			List<Line> allLines = new ArrayList<>();
			List<Point> res = new ArrayList<>();
			for (int i = 0; i < list.size(); i += 2) {
				Line L = (Line) list.get(i);
				allLines.add(L);
				if (where.containsKey(L)) {
					for (int j = where.get(L); j < allLines.size() - 1; j++) {
						res.add(intersect(allLines.get(j), allLines.get(j + 1)));
					}
					break;
				}
				where.put(L, i / 2);
			}
			return res.toArray(new Point[0]);
		}

		private long cross(PointLong a, PointLong b) {
			return a.x * b.y - a.y * b.x;
		}

		class Point {
			double x;
			double y;

			Point(double x, double y) {
				this.x = x;
				this.y = y;
			}

			public String toString() {
				return "(" + x + " " + y + ")";
				//return String.format("(%.4f %.4f)", x, y);
			}

		}

		class Line {
			double a;
			double b;
			double c;
			Point anyPoint;

			Line(double a, double b, double c) {
				this.a = a;
				this.b = b;
				this.c = c;
			}

			Line(Point p1, Point p2) {
				a = p1.y - p2.y;
				b = p2.x - p1.x;
				c = -a * p1.x - b * p1.y;
				double len = Math.sqrt(a * a + b * b);
				a /= len;
				b /= len;
				c /= len;
				anyPoint = p1;
			}

			Point anyPoint() {
				if (anyPoint != null) {
					return anyPoint;
				}
				if (Math.abs(b) < eps) {
					if (Math.abs(a) < eps) {
						throw new AssertionError();
					}
					return new Point(-c / a, 0);
				}
				return new Point(0, -c / b);
			}

			public String toString() {
				return a + " " + b + " " + c;
			}

		}

		class PointLong {
			long x;
			long y;

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

			PointLong sub(PointLong o) {
				return new PointLong(x - o.x, y - o.y);
			}

			Point toDoublePoint() {
				return new Point(x, y);
			}

			public String toString() {
				return "(" + x + " " + y + ")";
			}

		}

	}

	static class FastScanner {
		private BufferedReader in;
		private StringTokenizer st;

		public FastScanner(InputStream stream) {
			in = new BufferedReader(new InputStreamReader(stream));
		}

		public String next() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(in.readLine());
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
			return st.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

	}
}