import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Euler393 {

    enum MoveType {
        FILLED, HORIZONTAL, VERTICAL
    }

    static class Move {
        MoveType type;
        int occAdd;
        int outAdd;

        Move(MoveType t, int occ, int out) {
            this.type = t;
            this.occAdd = occ;
            this.outAdd = out;
        }
    }

    static class Transition {
        int outState;
        int ways;

        Transition(int s, int w) {
            outState = s;
            ways = w;
        }
    }

    static int n = 10;
    static int bitMask = (1 << n) - 1;
    static Map<Integer, List<Transition>> transitionCache = new HashMap<>();

    static List<Move> optionsForCell(int c, int occ, boolean lastRow) {
        List<Move> options = new ArrayList<>(3);
        int bit = 1 << c;
        if ((occ & bit) != 0) {
            options.add(new Move(MoveType.FILLED, 0, 0));
            return options;
        }

        if (c + 1 < n && (occ & (1 << (c + 1))) == 0) {
            options.add(new Move(MoveType.HORIZONTAL, bit | (1 << (c + 1)), 0));
        }
        if (!lastRow) {
            options.add(new Move(MoveType.VERTICAL, bit, bit));
        }

        return options;
    }

    static void dfs(int c, int occ1, int occ2, int out1, int out2, boolean lastRow, Map<Integer, Integer> accum) {
        if (c == n) {
            int outState = out1 | (out2 << n);
            accum.put(outState, accum.getOrDefault(outState, 0) + 1);
            return;
        }

        List<Move> ops1 = optionsForCell(c, occ1, lastRow);
        List<Move> ops2 = optionsForCell(c, occ2, lastRow);

        for (Move m1 : ops1) {
            for (Move m2 : ops2) {
                if (m1.type == MoveType.HORIZONTAL && m2.type == MoveType.HORIZONTAL)
                    continue;
                if (m1.type == MoveType.VERTICAL && m2.type == MoveType.VERTICAL)
                    continue;

                dfs(c + 1, occ1 | m1.occAdd, occ2 | m2.occAdd, out1 | m1.outAdd, out2 | m2.outAdd, lastRow, accum);
            }
        }
    }

    static List<Transition> getTransitions(int in1, int in2, boolean lastRow) {
        int key = in1 | (in2 << n) | ((lastRow ? 1 : 0) << 24);
        List<Transition> cached = transitionCache.get(key);
        if (cached != null)
            return cached;

        Map<Integer, Integer> accum = new HashMap<>();
        dfs(0, in1, in2, 0, 0, lastRow, accum);

        List<Transition> packed = new ArrayList<>(accum.size());
        for (Map.Entry<Integer, Integer> e : accum.entrySet()) {
            packed.add(new Transition(e.getKey(), e.getValue()));
        }

        transitionCache.put(key, packed);
        return packed;
    }

    static String solve() {
        Map<Integer, BigInteger> dp = new HashMap<>();
        dp.put(0, BigInteger.ONE);

        for (int row = 0; row < n; ++row) {
            boolean lastRow = (row == n - 1);
            Map<Integer, BigInteger> nextDp = new HashMap<>();

            for (Map.Entry<Integer, BigInteger> entry : dp.entrySet()) {
                int state = entry.getKey();
                BigInteger ways = entry.getValue();

                int in1 = state & bitMask;
                int in2 = (state >> n) & bitMask;

                List<Transition> transitions = getTransitions(in1, in2, lastRow);
                for (Transition tr : transitions) {
                    BigInteger add = ways.multiply(BigInteger.valueOf(tr.ways));
                    BigInteger current = nextDp.getOrDefault(tr.outState, BigInteger.ZERO);
                    nextDp.put(tr.outState, current.add(add));
                }
            }

            dp = nextDp;
        }

        BigInteger ans = dp.getOrDefault(0, BigInteger.ZERO);
        return ans.toString();
    }

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