import java.util.*;

public class Euler289 {
    static final long MOD = 10000000000L;

    static class Pair {
        int first, second;

        Pair(int f, int s) {
            first = f;
            second = s;
        }
    }

    static void generatePairingsRec(List<Integer> indices, List<List<Pair>> out) {
        if (indices.isEmpty()) {
            out.add(new ArrayList<>());
            return;
        }
        int first = indices.get(0);
        for (int k = 1; k < indices.size(); k += 2) {
            int second = indices.get(k);
            List<Integer> left = indices.subList(1, k);
            List<Integer> right = indices.subList(k + 1, indices.size());

            List<List<Pair>> leftPairings = new ArrayList<>();
            List<List<Pair>> rightPairings = new ArrayList<>();
            generatePairingsRec(left, leftPairings);
            generatePairingsRec(right, rightPairings);

            for (List<Pair> lp : leftPairings) {
                for (List<Pair> rp : rightPairings) {
                    List<Pair> combined = new ArrayList<>();
                    combined.add(new Pair(first, second));
                    combined.addAll(lp);
                    combined.addAll(rp);
                    out.add(combined);
                }
            }
        }
    }

    static List<List<Pair>> generatePairings(int count) {
        List<List<Pair>> out = new ArrayList<>();
        if (count == 0) {
            out.add(new ArrayList<>());
            return out;
        }
        List<Integer> indices = new ArrayList<>();
        for (int i = 0; i < count; ++i)
            indices.add(i);
        generatePairingsRec(indices, out);
        return out;
    }

    static class PairingCache {
        List<List<Pair>> p2;
        List<List<Pair>> p4;
        List<List<Pair>> p8;

        PairingCache() {
            p2 = generatePairings(2);
            p4 = generatePairings(4);
            p8 = generatePairings(8);
        }

        List<List<Pair>> get(int count) {
            if (count == 2)
                return p2;
            if (count == 4)
                return p4;
            return p8;
        }
    }

    static final int E_L = 0, E_U = 1, N_R = 2, N_L = 3, W_U = 4, W_L = 5, S_L = 6, S_R = 7;

    static class ApplyResult {
        boolean valid;
        int closed;

        ApplyResult(boolean v, int c) {
            valid = v;
            closed = c;
        }
    }

    static ApplyResult applyPair(int a, int b, int oldCount, int[] partner) {
        boolean aOld = (a < oldCount);
        boolean bOld = (b < oldCount);

        if (aOld && bOld) {
            int pa = partner[a];
            int pb = partner[b];
            if (pa < 0 || pb < 0)
                return new ApplyResult(false, 0);
            if (pa == b) {
                partner[a] = -1;
                partner[b] = -1;
                return new ApplyResult(true, 1);
            }
            partner[a] = -1;
            partner[pa] = -1;
            partner[b] = -1;
            partner[pb] = -1;
            partner[pa] = pb;
            partner[pb] = pa;
            return new ApplyResult(true, 0);
        }

        if (aOld != bOld) {
            int oldNum = aOld ? a : b;
            int neuNum = aOld ? b : a;
            int pold = partner[oldNum];
            if (pold < 0)
                return new ApplyResult(false, 0);
            partner[oldNum] = -1;
            partner[pold] = -1;
            partner[pold] = neuNum;
            partner[neuNum] = pold;
            return new ApplyResult(true, 0);
        }

        if (partner[a] != -1 || partner[b] != -1)
            return new ApplyResult(false, 0);
        partner[a] = b;
        partner[b] = a;
        return new ApplyResult(true, 0);
    }

    static class StateWrapper {
        byte[] arr;
        int hash;

        StateWrapper(byte[] a) {
            arr = a;
            hash = Arrays.hashCode(arr);
        }

        @Override
        public int hashCode() {
            return hash;
        }

        @Override
        public boolean equals(Object o) {
            return Arrays.equals(arr, ((StateWrapper) o).arr);
        }
    }

    static long computeL(int m, int n) {
        if (n > m) {
            int t = n;
            n = m;
            m = t;
        }
        PairingCache cache = new PairingCache();

        int[] rowWires = new int[n + 1];
        for (int k = 0; k <= n; ++k)
            rowWires[k] = (k > 0 ? 1 : 0) + (k < n ? 1 : 0);

        int[] prefix = new int[n + 2];
        for (int k = 0; k <= n; ++k)
            prefix[k + 1] = prefix[k] + rowWires[k];
        int totalRowWires = prefix[n + 1];

        Map<StateWrapper, Long> dp = new HashMap<>();
        dp.put(new StateWrapper(new byte[0]), 1L);

        for (int c = 0; c <= m; ++c) {
            for (int r = 0; r <= n; ++r) {
                boolean cNe = (c < m && r < n);
                boolean cNw = (c > 0 && r < n);
                boolean cSe = (c < m && r > 0);
                boolean cSw = (c > 0 && r > 0);

                List<Integer> activePorts = new ArrayList<>();
                if (cSe)
                    activePorts.add(E_L);
                if (cNe)
                    activePorts.add(E_U);
                if (cNe)
                    activePorts.add(N_R);
                if (cNw)
                    activePorts.add(N_L);
                if (cNw)
                    activePorts.add(W_U);
                if (cSw)
                    activePorts.add(W_L);
                if (cSw)
                    activePorts.add(S_L);
                if (cSe)
                    activePorts.add(S_R);

                List<List<Pair>> localPairings = cache.get(activePorts.size());

                int sumRight = (c < m) ? prefix[r] : 0;
                int numBottom = (r > 0) ? ((c < m ? 1 : 0) + (c > 0 ? 1 : 0)) : 0;
                int numLeft = (c > 0) ? ((r > 0 ? 1 : 0) + (r < n ? 1 : 0)) : 0;
                int sumLeft = (c > 0) ? (totalRowWires - prefix[r]) : 0;
                int expectedB = sumRight + numBottom + sumLeft;
                int offset = sumRight;

                List<Integer> outgoingPorts = new ArrayList<>();
                if (cSe)
                    outgoingPorts.add(E_L);
                if (cNe)
                    outgoingPorts.add(E_U);
                if (cNe)
                    outgoingPorts.add(N_R);
                if (cNw)
                    outgoingPorts.add(N_L);

                int numOut = outgoingPorts.size();
                int totalLabels = expectedB + numOut;

                int[] portLabel = new int[8];
                Arrays.fill(portLabel, -1);

                int idx = offset;
                if (cSe)
                    portLabel[S_R] = idx++;
                if (cSw)
                    portLabel[S_L] = idx++;

                idx = offset + numBottom;
                if (cSw)
                    portLabel[W_L] = idx++;
                if (cNw)
                    portLabel[W_U] = idx++;

                for (int i = 0; i < numOut; ++i) {
                    portLabel[outgoingPorts.get(i)] = expectedB + i;
                }

                List<Integer> newLabels = new ArrayList<>();
                for (int i = 0; i < offset; ++i)
                    newLabels.add(i);
                for (int p : outgoingPorts)
                    newLabels.add(portLabel[p]);
                int removeEnd = offset + numBottom + numLeft;
                for (int i = removeEnd; i < expectedB; ++i)
                    newLabels.add(i);

                int[] labelPos = new int[totalLabels];
                Arrays.fill(labelPos, -1);
                for (int i = 0; i < newLabels.size(); ++i)
                    labelPos[newLabels.get(i)] = i;

                boolean isFinal = (c == m && r == n);
                Map<StateWrapper, Long> nextDp = new HashMap<>();

                for (Map.Entry<StateWrapper, Long> entry : dp.entrySet()) {
                    byte[] state = entry.getKey().arr;
                    long count = entry.getValue();
                    if (state.length != expectedB)
                        continue;

                    int[] basePartner = new int[totalLabels];
                    Arrays.fill(basePartner, -1);
                    for (int i = 0; i < expectedB; ++i)
                        basePartner[i] = state[i];

                    for (List<Pair> pairing : localPairings) {
                        int[] partner = basePartner.clone();
                        int closed = 0;
                        boolean ok = true;

                        for (Pair pr : pairing) {
                            int portA = activePorts.get(pr.first);
                            int portB = activePorts.get(pr.second);
                            int la = portLabel[portA];
                            int lb = portLabel[portB];
                            if (la < 0 || lb < 0) {
                                ok = false;
                                break;
                            }

                            ApplyResult res = applyPair(la, lb, expectedB, partner);
                            if (!res.valid) {
                                ok = false;
                                break;
                            }
                            closed += res.closed;
                            if (closed > 1) {
                                ok = false;
                                break;
                            }
                        }
                        if (!ok)
                            continue;

                        if (isFinal) {
                            if (closed != 1 || !newLabels.isEmpty())
                                continue;
                            StateWrapper empty = new StateWrapper(new byte[0]);
                            nextDp.put(empty, (nextDp.getOrDefault(empty, 0L) + count) % MOD);
                            continue;
                        }
                        if (closed != 0)
                            continue;

                        boolean valid = true;
                        byte[] nextState = new byte[newLabels.size()];
                        for (int i = 0; i < newLabels.size(); ++i) {
                            int label = newLabels.get(i);
                            int pl = partner[label];
                            if (pl < 0) {
                                valid = false;
                                break;
                            }
                            int pos = labelPos[pl];
                            if (pos < 0) {
                                valid = false;
                                break;
                            }
                            nextState[i] = (byte) pos;
                        }
                        if (!valid)
                            continue;

                        StateWrapper nsw = new StateWrapper(nextState);
                        nextDp.put(nsw, (nextDp.getOrDefault(nsw, 0L) + count) % MOD);
                    }
                }
                dp = nextDp;
            }
        }
        return dp.getOrDefault(new StateWrapper(new byte[0]), 0L) % MOD;
    }

    public static String solve() {
        return String.valueOf(computeL(6, 10));
    }

    public static void main(String[] args) {
        System.out.println(solve());
    }
}
