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

public class C {

	BufferedReader br;
	PrintWriter out;
	StringTokenizer st;
	boolean eof;

	static class Pair {
		int r, b;

		public Pair(int r, int b) {
			this.r = r;
			this.b = b;
		}

		boolean worse(Pair o) {
			return r >= o.r && b >= o.b;
		}
	}

	static class Options {
		List<Pair> lst = new ArrayList<>();
		// r increasing, b decreasing

		void add(Pair p) {

			for (int i = 0; i < lst.size(); i++) {
				if (p.worse(lst.get(i))) {
					return;
				}
			}

			int idxL = 0;
			while (idxL < lst.size() && p.b <= lst.get(idxL).b) {
				idxL++;
			}

			int idxR = lst.size() - 1;
			while (idxR >= 0 && p.r <= lst.get(idxR).r) {
				idxR--;
			}

			// < idxL and > idxR must be removed
			for (int idx = idxL - 1; idx > idxR; idx--) {
				lst.remove(idx);
			}

			lst.add(idxR + 1, p);
		}
	}

	int solve(int n, char[] types, int[] rs, int[] bs) {
		Options[] dp = new Options[1 << n];
		for (int i = 0; i < 1 << n; i++) {
			dp[i] = new Options();
		}

		dp[0].add(new Pair(0, 0));

		int maskR = 0;
		int maskB = 0;
		for (int i = 0; i < n; i++) {
			if (types[i] == 'R') {
				maskR |= 1 << i;
			} else {
				maskB |= 1 << i;
			}
		}

		for (int mask = 0; mask < (1 << n); mask++) {

			int discR = Integer.bitCount(mask & maskR);
			int discB = Integer.bitCount(mask & maskB);

			for (Pair p : dp[mask].lst) {
				for (int nxt = 0; nxt < n; nxt++) {
					if (test(mask, nxt)) {
						continue;
					}
					int costR = Math.max(rs[nxt] - discR, 0);
					int costB = Math.max(bs[nxt] - discB, 0);

					dp[mask | (1 << nxt)].add(new Pair(p.r + costR, p.b + costB));
				}
			}
		}

		int ret = Integer.MAX_VALUE;
		for (Pair p : dp[(1 << n) - 1].lst) {
			ret = Math.min(ret, Math.max(p.r, p.b));
		}

		return ret + n;
	}

	boolean test(int mask, int i) {
		return ((mask >> i) & 1) == 1;
	}

	void submit() throws IOException {
		int n = nextInt();
		char[] types = new char[n];
		int[] rs = new int[n];
		int[] bs = new int[n];
		for (int i = 0; i < n; i++) {
			types[i] = nextToken().charAt(0);
			rs[i] = nextInt();
			bs[i] = nextInt();
		}
		out.println(solve(n, types, rs, bs));
	}

	Random rng = new Random();

	void testTime() {
		int n = 16;
		char[] types = new char[n];
		int[] rs = new int[n];
		int[] bs = new int[n];

		for (int i = 0; i < n; i++) {
			types[i] = "RB".charAt(rng.nextInt(2));
			rs[i] = rng.nextInt(5);
			bs[i] = rng.nextInt(5);
		}

		out.println(solve(n, types, rs, bs));
	}

	void testCorrectness(int n, int bound) {
		char[] types = new char[n];
		int[] rs = new int[n];
		int[] bs = new int[n];

		for (int i = 0; i < n; i++) {
			types[i] = "RB".charAt(rng.nextInt(2));
			rs[i] = rng.nextInt(bound);
			bs[i] = rng.nextInt(bound);
		}

		if (solve(n, types, rs, bs) != brute(n, types, rs, bs)) {
			System.err.println(n);
			System.err.println(Arrays.toString(rs));
			System.err.println(Arrays.toString(bs));
			throw new AssertionError();
		}
	}

	int brute(int n, char[] types, int[] rs, int[] bs) {
		int ret = Integer.MAX_VALUE;
		int[] perm = new int[n];
		for (int i = 0; i < n; i++) {
			perm[i] = i;
		}

		do {
			int totR = 0;
			int totB = 0;
			int cR = 0;
			int cB = 0;
			for (int idx : perm) {
				totR += Math.max(rs[idx] - cR, 0);
				totB += Math.max(bs[idx] - cB, 0);
				if (types[idx] == 'R') {
					cR++;
				} else {
					cB++;
				}
			}
			ret = Math.min(ret, Math.max(totR, totB));
		} while (nextPermutation(perm));

		return ret + n;
	}

	static boolean nextPermutation(int[] a) {
		int n = a.length;
		int ptr = n - 2;
		while (ptr >= 0 && a[ptr] > a[ptr + 1]) {
			ptr--;
		}
		if (ptr < 0) {
			return false;
		}

		for (int i = ptr + 1, j = n - 1; i < j; i++, j--) {
			int tmp = a[i];
			a[i] = a[j];
			a[j] = tmp;
		}

		for (int i = ptr + 1;; i++) {
			if (a[ptr] < a[i]) {
				int tmp = a[ptr];
				a[ptr] = a[i];
				a[i] = tmp;
				return true;
			}
		}
	}

	C() throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
//		testTime();
//		for (int tst = 0; tst < 10000; tst++) {
//			testCorrectness(5, 5);
//			System.err.println(tst);
//		}
		submit();
		out.close();
	}

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

	String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (Exception e) {
				eof = true;
				return null;
			}
		}
		return st.nextToken();
	}

	String nextString() {
		try {
			return br.readLine();
		} catch (IOException e) {
			eof = true;
			return null;
		}
	}

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

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

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


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.PrintStream;
import java.util.Arrays;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.InputStream;

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

    static class TaskE {
        int n;
        int[] r;
        int[] b;
        int[][][] dp;
        int[] numRedCards;
        int[] numBlueCards;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            n = in.nextInt();
            boolean[] isRed = new boolean[n];
            r = new int[n];
            b = new int[n];
            int extraRed = 0;
            int extraBlue = 0;
            for (int i = 0; i < n; i++) {
                if (in.next().charAt(0) == 'R') isRed[i] = true;
                r[i] = in.nextInt();
                if (r[i] > n) {
                    extraRed += r[i] - n;
                    r[i] = n;
                }
                b[i] = in.nextInt();
                if (b[i] > n) {
                    extraBlue += b[i] - n;
                    b[i] = n;
                }
            }
            int result = Math.max(extraBlue, extraRed);
            //System.out.println(result);
            dp = new int[1 << n][2][n * n + 1]; // bitmask, leftovers are red?, leftover coins
            for (int[][] x : dp) for (int[] y : x) Arrays.fill(y, -1);

            numRedCards = new int[1 << n];
            numBlueCards = new int[1 << n];
            for (int i = 0; i < 1 << n; i++) {
                for (int j = 0; j < n; j++) {
                    if (((i >> j) & 1) == 1) {
                        if (isRed[j]) numRedCards[i]++;
                        else numBlueCards[i]++;
                    }
                }
                //System.out.println(i + ": " + numRedCards[i] + ", " + numBlueCards[i]);
            }

            if (extraRed > extraBlue) {
                out.println(n + result + traverse(0, 0, extraRed - extraBlue));
            } else {
                out.println(n + result + traverse(0, 1, extraBlue - extraRed));
            }
        }

        public int traverse(int mask, int leftOverRed, int amount) {
            amount = Math.min(amount, n * n);
            if (mask == (1 << n) - 1) return 0;
            if (dp[mask][leftOverRed][amount] != -1) return dp[mask][leftOverRed][amount];

            int result = Integer.MAX_VALUE;
            for (int i = 0; i < n; i++) {
                if (((mask >> i) & 1) == 1) continue;
                int newMask = mask | (1 << i);
                int haveRed = leftOverRed == 1 ? amount : 0;
                int haveBlue = leftOverRed == 0 ? amount : 0;
                int needRed = Math.max(0, r[i] - numRedCards[mask] - haveRed);
                int needBlue = Math.max(0, b[i] - numBlueCards[mask] - haveBlue);
                int needMoves = Math.max(needRed, needBlue);

                if (needRed >= needBlue) { // wichtig dass 2 Mal >=, ansonsten funktioniert's nicht!
                    int amountNew = haveBlue + needRed - Math.max(0, b[i] - numBlueCards[mask]);
                    result = Math.min(result, needMoves + traverse(newMask, 0, amountNew));
                }
                if (needBlue >= needRed) {
                    int amountNew = haveRed + needBlue - Math.max(0, r[i] - numRedCards[mask]);
                    result = Math.min(result, needMoves + traverse(newMask, 1, amountNew));
                }
            }
            dp[mask][leftOverRed][amount] = result;
            return result;
        }

    }

    static class InputReader {
        private static BufferedReader in;
        private static StringTokenizer tok;

        public InputReader(InputStream in) {
            this.in = new BufferedReader(new InputStreamReader(in));
        }

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

        public String next() {
            try {
                while (tok == null || !tok.hasMoreTokens()) {
                    tok = new StringTokenizer(in.readLine());
                }
            } catch (IOException ex) {
                System.err.println("An IOException was caught :" + ex.getMessage());
            }
            return tok.nextToken();
        }

    }
}


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

public class Template implements Runnable {

    BufferedReader in;
    PrintWriter out;
    StringTokenizer tok = new StringTokenizer("");

    void init() throws FileNotFoundException {
        try {
            in = new BufferedReader(new FileReader("input.txt"));
            out = new PrintWriter("output.txt");
        } catch (Exception e) {
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
        }
    }

    String readString() throws IOException {
        while (!tok.hasMoreTokens()) {
            try {
                tok = new StringTokenizer(in.readLine(), " :");
            } catch (Exception e) {
                return null;
            }
        }
        return tok.nextToken();
    }

    int readInt() throws IOException {
        return Integer.parseInt(readString());
    }

    int[] readIntArray(int size) throws IOException {
        int[] res = new int[size];
        for (int i = 0; i < size; i++) {
            res[i] = readInt();
        }
        return res;
    }

    long readLong() throws IOException {
        return Long.parseLong(readString());
    }

    double readDouble() throws IOException {
        return Double.parseDouble(readString());
    }

    <T> List<T>[] createGraphList(int size) {
        List<T>[] list = new List[size];
        for (int i = 0; i < size; i++) {
            list[i] = new ArrayList<>();
        }
        return list;
    }

    public static void main(String[] args) {
        new Thread(null, new Template(), "", 1l * 200 * 1024 * 1024).start();
    }

    long timeBegin, timeEnd;

    void time() {
        timeEnd = System.currentTimeMillis();
        System.err.println("Time = " + (timeEnd - timeBegin));
    }

    long memoryTotal, memoryFree;

    void memory() {
        memoryFree = Runtime.getRuntime().freeMemory();
        System.err.println("Memory = " + ((memoryTotal - memoryFree) >> 10)
                + " KB");
    }

    public void run() {
        try {
            timeBegin = System.currentTimeMillis();
            memoryTotal = Runtime.getRuntime().freeMemory();
            init();
            solve();
            out.close();
            if (System.getProperty("ONLINE_JUDGE") == null) {
                time();
                memory();
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }
    }

    void solve() throws IOException {
        int n = readInt();
        char[] type = new char[n];
        int[] r = new int[n];
        int[] b = new int[n];
        for (int i = 0; i < n; i++) {
            type[i] = readString().charAt(0);
            r[i] = readInt();
            b[i] = readInt();
        }

        int max = 1 << n;
        int[] Rsum = new int[max];
        int[] Bsum = new int[max];
        int[] Rcnt = new int[max];
        int[] Bcnt = new int[max];
        for (int mask = 0; mask < max; mask++) {
            for (int j = 0; j < n; j++) {
                if (has(mask, j)) {
                    Rsum[mask] += r[j];
                    Bsum[mask] += b[j];

                    Rcnt[mask] += type[j] == 'R' ? 1 : 0;
                    Bcnt[mask] += type[j] == 'R' ? 0 : 1;
                }
            }
        }

        int MAX_DIFF = n + 1;

        _Ez_Int__Int_HashMap[] dp = new _Ez_Int__Int_HashMap[max];
        for (int i = 0; i < max; i++) {
            dp[i] = new _Ez_Int__Int_HashMap(16);
        }
        dp[0].put(0, 0);
        for (int mask = 0; mask < max; mask++) {
            for (int index = 0; index < dp[mask].status.length; index++) {
                if (dp[mask].status[index] == _Ez_Int__Int_HashMap.FILLED) {
                    int key = dp[mask].keys[index];
                    int value = dp[mask].values[index];
                    int rd = getA(key);
                    int bd = getB(key);

                    int nowR = value - (Rsum[mask] - rd);
                    int nowB = value - (Bsum[mask] - bd);

                    for (int next = 0; next < n; next++) {
                        if (has(mask, next)) continue;

                        int needR = Math.max(0, r[next] - Rcnt[mask]);
                        int needB = Math.max(0, b[next] - Bcnt[mask]);

                        int needBuy = Math.max(needR - nowR, needB - nowB);
                        int nextVal = value;
                        if (needBuy > 0) {
                            nextVal += needBuy;
                        }
                        int nextMask = mask | (1 << next);
                        int nrd = rd + r[next] - needR;
                        int nbd = bd + b[next] - needB;
                        dp[nextMask].put(comb(nrd, nbd), nextVal);
                    }
                }
            }
        }

        int min = Integer.MAX_VALUE;
        for (int index=0;index<dp[max-1].status.length;index++) {
            if (dp[max - 1].status[index] == _Ez_Int__Int_HashMap.FILLED) {
                min = Math.min(min, dp[max - 1].values[index]);
            }
        }
        out.println(min + n);
    }

    int comb(int a, int b) {
        return a * 16 + b;
    }

    int getA(int c) {
        return c / 16;
    }

    int getB(int c) {
        return c % 16;
    }

    boolean has(int mask, int bit) {
        return (mask & (1 << bit)) != 0;
    }

    static class _Ez_Int__Int_HashMap {
        private static final int DEFAULT_CAPACITY = 8;

        // There are three invariants for size, removedCount and arraysLength:
        // 1. size + removedCount <= 1/2 arraysLength
        // 2. size > 1/8 arraysLength
        // 3. size >= removedCount
        // arraysLength can be only multiplied by 2 and divided by 2.
        // Also, if it becomes >= 32, it can't become less anymore.
        private static final int REBUILD_LENGTH_THRESHOLD = 32;

        private static final int HASHCODE_INITIAL_VALUE = 0x811c9dc5;
        private static final int HASHCODE_MULTIPLIER = 0x01000193;

        private static final byte FREE = 0;
        private static final byte REMOVED = 1;
        private static final byte FILLED = 2;

        private static final /*V*/ int/*V*/ DEFAULT_NULL_VALUE = Integer.MIN_VALUE;

        private static final Random rnd = new Random();
        private static final int POS_RANDOM_SHIFT_1;
        private static final int POS_RANDOM_SHIFT_2;
        private static final int STEP_RANDOM_SHIFT_1;
        private static final int STEP_RANDOM_SHIFT_2;

        static {
            POS_RANDOM_SHIFT_1 = rnd.nextInt(10) + 11;
            POS_RANDOM_SHIFT_2 = rnd.nextInt(10) + 21;
            STEP_RANDOM_SHIFT_1 = rnd.nextInt(10) + 11;
            STEP_RANDOM_SHIFT_2 = rnd.nextInt(10) + 21;
        }

        private /*K*/ int/*K*/[] keys;
        private /*V*/ int/*V*/[] values;
        private byte[] status;
        private int size;
        private int removedCount;
        private int mask;
        private final int hashSeed;

        public _Ez_Int__Int_HashMap() {
            this(DEFAULT_CAPACITY);
        }

        public _Ez_Int__Int_HashMap(int capacity) {
            if (capacity < 0) {
                throw new IllegalArgumentException("Capacity must be non-negative");
            }
            // Actually we need 4x more memory
            int length = 4 * Math.max(1, capacity);
            if ((length & (length - 1)) != 0) {
                length = Integer.highestOneBit(length) << 1;
            }
            // Length is a power of 2 now
            initEmptyTable(length);
            hashSeed = rnd.nextInt();
        }

        private int getStartPos(int h) {
            h ^= hashSeed;
            h ^= (h >>> POS_RANDOM_SHIFT_1) ^ (h >>> POS_RANDOM_SHIFT_2);
            return h & mask;
        }

        private int getStep(int h) {
            h ^= hashSeed;
            h ^= (h >>> STEP_RANDOM_SHIFT_1) ^ (h >>> STEP_RANDOM_SHIFT_2);
            return ((h << 1) | 1) & mask;
        }

        public int size() {
            return size;
        }

        public /*V*/int/*V*/ get(/*K*/int/*K*/ key) {
            final int keyHash = key;
            int pos = getStartPos(keyHash);
            final int step = getStep(keyHash);
            for (; status[pos] != FREE; pos = (pos + step) & mask) {
                if (status[pos] == FILLED && keys[pos] == key) {
                    return values[pos];
                }
            }
            return DEFAULT_NULL_VALUE;
        }

        public /*V*/int/*V*/ put(/*K*/int/*K*/ key, /*V*/int/*V*/ value) {
            final int keyHash = key;
            int pos = getStartPos(keyHash);
            final int step = getStep(keyHash);
            for (; status[pos] == FILLED; pos = (pos + step) & mask) {
                if (keys[pos] == key) {
                    final /*V*/ int/*V*/ oldValue = values[pos];
                    values[pos] = value;
                    return oldValue;
                }
            }
            if (status[pos] == FREE) {
                status[pos] = FILLED;
                keys[pos] = key;
                values[pos] = value;
                size++;
                return DEFAULT_NULL_VALUE;
            }
            final int removedPos = pos;
            for (pos = (pos + step) & mask; status[pos] != FREE; pos = (pos + step) & mask) {
                if (status[pos] == FILLED && keys[pos] == key) {
                    final /*V*/ int/*V*/ oldValue = values[pos];
                    values[pos] = value;
                    return oldValue;
                }
            }
            status[removedPos] = FILLED;
            keys[removedPos] = key;
            values[removedPos] = value;
            size++;
            removedCount--;
            return DEFAULT_NULL_VALUE;
        }

        private void initEmptyTable(int length) {
            keys = new /*K*/int/*K*/[length];
            values = new /*V*/int/*V*/[length];
            status = new byte[length];
            size = 0;
            removedCount = 0;
            mask = length - 1;
        }

    }

}


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

/**
 * @author Don Li
 */
public class KuroAndTopologicalParity {

    int MOD = (int) 1e9 + 7;
    int N = 55;

    long[] p2 = new long[N];
    long[][] c = new long[N][N];
    long[][] cs = new long[N][2];

    long[][][][] dp = new long[N][N][N][N];

    {
        p2[0] = 1;
        for (int i = 1; i < N; i++) p2[i] = p2[i - 1] * 2 % MOD;

        for (int i = 0; i < N; i++) {
            c[i][0] = 1;
            for (int j = 1; j <= i; j++) c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % MOD;
        }

        for (int i = 0; i < N; i++) {
            for (int j = 0; j <= i; j++) {
                cs[i][j & 1] = (cs[i][j & 1] + c[i][j]) % MOD;
            }
        }
    }

    void solve() {
        int n = in.nextInt(), p = in.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) a[i] = in.nextInt();

        long ans = 0;
        dp[0][0][0][0] = 1;
        for (int i = 0; i < n; i++) {
            for (int ob = 0; ob <= i + 1; ob++) {
                for (int eb = 0; ob + eb <= i + 1; eb++) {
                    for (int ow = 0; ob + eb + ow <= i + 1; ow++) {
                        int ew = (i + 1) - (ob + eb + ow);
                        calc(a[i], ob, eb, ow, ew);
                        if (i + 1 == n && (ob + ow) % 2 == p) {
                            ans = (ans + dp[ob][eb][ow][ew]) % MOD;
                        }
                    }
                }
            }
        }
        out.println(ans);
    }

    void calc(int color, int ob, int eb, int ow, int ew) {
        if (color != 0 && ew > 0) {
            dp[ob][eb][ow][ew] += dp[ob][eb][ow][ew - 1] * p2[ow + ew + eb - 1] % MOD * cs[ob][1] % MOD;
        }
        if (color != 0 && ow > 0) {
            dp[ob][eb][ow][ew] += dp[ob][eb][ow - 1][ew] * p2[ow + ew + eb - 1] % MOD * cs[ob][0] % MOD;
        }
        if (color != 1 && eb > 0) {
            dp[ob][eb][ow][ew] += dp[ob][eb - 1][ow][ew] * p2[ob + eb + ew - 1] % MOD * cs[ow][1] % MOD;
        }
        if (color != 1 && ob > 0) {
            dp[ob][eb][ow][ew] += dp[ob - 1][eb][ow][ew] * p2[ob + eb + ew - 1] % MOD * cs[ow][0] % MOD;
        }
        dp[ob][eb][ow][ew] %= MOD;
    }

    public static void main(String[] args) {
        in = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
        new KuroAndTopologicalParity().solve();
        out.close();
    }

    static FastScanner in;
    static PrintWriter out;

    static class FastScanner {
        BufferedReader in;
        StringTokenizer st;

        public FastScanner(BufferedReader in) {
            this.in = in;
        }

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

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

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

        public double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }
}


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Div2_482E {

	static int nV;
	static int p;

	static int[] color;

	static long[] pow2;

	static long[][][][] dp;

	static long MOD = 1_000_000_007;

	public static void main(String[] args) throws IOException {
		pow2 = new long[500];
		pow2[0] = 1;
		for (int i = 1; i < 500; i++) {
			pow2[i] = pow2[i - 1] * 2 % MOD;
		}

		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter printer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		StringTokenizer inputData = new StringTokenizer(reader.readLine());
		nV = Integer.parseInt(inputData.nextToken());
		p = Integer.parseInt(inputData.nextToken());

		color = new int[nV];
		inputData = new StringTokenizer(reader.readLine());
		for (int i = 0; i < nV; i++) {
			color[i] = Integer.parseInt(inputData.nextToken());
		}

		dp = new long[nV + 1][nV + 1][nV + 1][nV + 1];
		dp[nV][0][0][0] = 1;
		pushDP(nV, 0, 0, 0);

		for (int cV = nV - 1; cV > 0; cV--) {
			for (int i = 0; i <= nV; i++) {
				for (int j = 0; j <= nV; j++) {
					for (int k = 0; k <= nV; k++) {
						int l = nV - cV - i - j - k;
						if (l >= 0 && dp[cV][i][j][k] != 0) {
							pushDP(cV, i, j, k);
						}
					}
				}
			}
		}
		long ans = 0;
		for (int wE = 0; wE <= nV; wE++) {
			for (int wO = 0; wO <= nV; wO++) {
				for (int bE = 0; bE <= nV; bE++) {
					int bO = nV - wE - wO - bE;

					if (((wO + bO) & 1) == p) {
						ans = (ans + dp[0][wE][wO][bE]) % MOD;
					}
				}
			}
		}
		printer.println(ans);
		printer.close();
	}

	static void pushDP(int cV, int wE, int wO, int bE) {
		int bO = nV - cV - wE - wO - bE;
		long cDP = dp[cV][wE][wO][bE];
		if (cDP == 0) {
			return;
		}

		// white
		if (color[cV - 1] == 0 || color[cV - 1] == -1) {
			if (bO != 0) {
				dp[cV - 1][wE + 1][wO][bE] = (dp[cV - 1][wE + 1][wO][bE] + pow2[wE + wO + bE + bO - 1] * cDP) % MOD;
				dp[cV - 1][wE][wO + 1][bE] = (dp[cV - 1][wE][wO + 1][bE] + pow2[wE + wO + bE + bO - 1] * cDP) % MOD;
			} else {
				dp[cV - 1][wE][wO + 1][bE] = (dp[cV - 1][wE][wO + 1][bE] + pow2[wE + wO + bO] * cDP) % MOD;
			}
		}
		// black
		if (color[cV - 1] == 1 || color[cV - 1] == -1) {
			if (wO != 0) {
				dp[cV - 1][wE][wO][bE + 1] = (dp[cV - 1][wE][wO][bE + 1] + pow2[wE + wO + bE + bO - 1] * cDP) % MOD;
				dp[cV - 1][wE][wO][bE] = (dp[cV - 1][wE][wO][bE] + pow2[wE + wO + bE + bO - 1] * cDP) % MOD;
			} else {
				dp[cV - 1][wE][wO][bE] = (dp[cV - 1][wE][wO][bE] + pow2[wO + bE + bO] * cDP) % MOD;
			}
		}
	}

}


import java.io.*;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by dalt on 2018/5/30.
 */
public class Contest472E {
    static final int INF = (int) 1e8;
    static final int MOD = (int) 1e9 + 7;
    public static BlockReader input;
    public static PrintStream output;
    public static Debug debug;

    public static void main(String[] args) throws FileNotFoundException {
        init();

        solve();

        destroy();
    }

    public static void init() throws FileNotFoundException {
        if (System.getProperty("ONLINE_JUDGE") == null) {
            input = new BlockReader(new FileInputStream("E:\\DATABASE\\TESTCASE\\codeforces\\Contest472E.in"));
            output = System.out;
        } else {
            input = new BlockReader(System.in);
            output = new PrintStream(new BufferedOutputStream(System.out), false);
        }

        debug = new Debug();
        debug.enter("main");
    }

    public static void solve() {
        int n = input.nextInteger();
        int p = input.nextInteger();

        long[][][] dp = new long[n][2][2];
        int[] c = new int[n];
        for (int i = 0; i < n; i++) {
            c[i] = input.nextInteger();
        }

        for (int i = n - 1; i >= 0; i--) {
            long[] cnt = new long[2];
            long[][] localDp = new long[2][2];

            if (c[i] == -1) {
                dp[i][0][1] = localDp[0][1] = 1;
                dp[i][1][1] = localDp[1][1] = 1;
            } else {
                dp[i][c[i]][1] = localDp[c[i]][1] = 1;
            }

            int num = n - 2 - i >= 0 ? Mathematics.pow(2,  (n - 2 - i), MOD) : 0;
            for (int j = i + 1; j < n; j++) {
                if (c[j] == -1 || c[j] == 0) {
                    dp[i][1][0] = (dp[i][1][0] + (localDp[1][0] * dp[j][0][0] + localDp[1][1] * dp[j][0][1]) * num) % MOD;
                    dp[i][1][1] = (dp[i][1][1] + (localDp[1][1] * dp[j][0][0] + localDp[1][0] * dp[j][0][1]) * num) % MOD;
                }
            }
            for (int j = i + 1; j < n; j++) {
                if (c[j] == -1 || c[j] == 1) {
                    dp[i][0][0] = (dp[i][0][0] + (localDp[0][0] * dp[j][1][0] + localDp[0][1] * dp[j][1][1]) * num) % MOD;
                    dp[i][0][1] = (dp[i][0][1] + (localDp[0][1] * dp[j][1][0] + localDp[0][0] * dp[j][1][1]) * num) % MOD;
                }
            }
        }

        long sum = 0;
        for (int i = 0; i < n; i++) {
            sum = sum + dp[i][0][p] + dp[i][1][p];
        }
        sum %= MOD;
        output.println(sum);
    }

    public static void destroy() {
        output.flush();
        debug.exit();
        debug.statistic();
    }

    public static class Debug {
        boolean debug = System.getProperty("ONLINE_JUDGE") == null;
        Deque<ModuleRecorder> stack = new ArrayDeque<>();
        Map<String, Module> fragmentMap = new HashMap<>();

        public void enter(String module) {
            if (debug) {
                stack.push(new ModuleRecorder(getModule(module)));
            }
        }

        public Module getModule(String moduleName) {
            Module module = fragmentMap.get(moduleName);
            if (module == null) {
                module = new Module(moduleName);
                fragmentMap.put(moduleName, module);
            }
            return module;
        }

        public void exit() {
            if (debug) {
                ModuleRecorder fragment = stack.pop();
                fragment.exit();
            }
        }

        public void statistic() {
            if (!debug) {
                return;
            }

            if (stack.size() > 0) {
                throw new RuntimeException("Exist unexited tag");
            }
            System.out.println("\n------------------------------------------");

            System.out.println("memory used " + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20) + "M");

            System.out.println("\n------------------------------------------");
            for (Module module : fragmentMap.values()) {
                System.out.println(String.format("Module %s : enter %d : cost %d", module.moduleName, module.enterTime, module.totaltime));
            }

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

        public static class ModuleRecorder {
            Module fragment;
            long time;

            public ModuleRecorder(Module fragment) {
                this.fragment = fragment;
                time = System.currentTimeMillis();
            }

            public void exit() {
                fragment.totaltime += System.currentTimeMillis() - time;
                fragment.enterTime++;
            }
        }

        public static class Module {
            String moduleName;
            long totaltime;
            long enterTime;

            public Module(String moduleName) {
                this.moduleName = moduleName;
            }
        }
    }

    public static class BlockReader {
        static final int EOF = -1;
        InputStream is;
        byte[] dBuf;
        int dPos, dSize, next;
        StringBuilder builder = new StringBuilder();

        public BlockReader(InputStream is) {
            this(is, 8192);
        }

        public BlockReader(InputStream is, int bufSize) {
            this.is = is;
            dBuf = new byte[bufSize];
            next = nextByte();
        }

        public int nextByte() {
            while (dPos >= dSize) {
                if (dSize == -1) {
                    return EOF;
                }
                dPos = 0;
                try {
                    dSize = is.read(dBuf);
                } catch (Exception e) {
                }
            }
            return dBuf[dPos++];
        }

        public String nextBlock() {
            builder.setLength(0);
            skipBlank();
            while (next != EOF && !Character.isWhitespace(next)) {
                builder.append((char) next);
                next = nextByte();
            }
            return builder.toString();
        }

        public void skipBlank() {
            while (Character.isWhitespace(next)) {
                next = nextByte();
            }
        }

        public int nextInteger() {
            skipBlank();
            int ret = 0;
            boolean rev = false;
            if (next == '+' || next == '-') {
                rev = next == '-';
                next = nextByte();
            }
            while (next >= '0' && next <= '9') {
                ret = (ret << 3) + (ret << 1) + next - '0';
                next = nextByte();
            }
            return rev ? -ret : ret;
        }

        public int nextBlock(char[] data, int offset) {
            skipBlank();
            int index = offset;
            int bound = data.length;
            while (next != EOF && index < bound && !Character.isWhitespace(next)) {
                data[index++] = (char) next;
                next = nextByte();
            }
            return index - offset;
        }

        public boolean hasMore() {
            skipBlank();
            return next != EOF;
        }
    }

    public static class Mathematics {
        public static int gcd(int a, int b) {
            return a >= b ? gcd0(a, b) : gcd0(b, a);
        }

        public static int gcd0(int a, int b) {
            return b == 0 ? a : gcd0(b, a % b);
        }

        public static long gcd(long a, long b) {
            return a >= b ? gcd0(a, b) : gcd0(b, a);
        }

        public static long gcd0(long a, long b) {
            return b == 0 ? a : gcd0(b, a % b);
        }

        public static int inverse(int x, int mod) {
            return pow(x, mod - 2, mod);
        }

        public static int pow(int x, int n, int mod) {
            n = mod(n, mod - 1);
            x = mod(x, mod);
            int bit = 31 - Integer.numberOfLeadingZeros(n);
            long product = 1;
            for (; bit >= 0; bit--) {
                product = product * product % mod;
                if (((1 << bit) & n) != 0) {
                    product = product * x % mod;
                }
            }
            return (int) product;
        }

        public static int mod(int x, int mod) {
            return x >= 0 ? x % mod : (((x % mod) + mod) % mod);
        }

        public static long cross(int x1, int y1, int x2, int y2) {
            return (long) x1 * y2 - (long) y1 * x2;
        }

        public static double cross(double x1, double y1, double x2, double y2) {
            return x1 * y2 - y1 * x2;
        }

        public static long permute(int n, int m) {
            return m == 0 ? 1 : n * permute(n - 1, m - 1);
        }

        public static int eulerSieve(int limit, int[] primes, int offset) {
            boolean[] isComp = new boolean[limit + 1];
            int wpos = offset;
            for (int i = 2; i <= limit; i++) {
                if (!isComp[i]) {
                    primes[wpos++] = i;
                }
                for (int j = offset, until = limit / i; j < wpos && primes[j] <= until; j++) {
                    int pi = primes[j] * i;
                    isComp[pi] = true;
                    if (i % primes[j] == 0) {
                        break;
                    }
                }
            }
            return wpos - offset;
        }
    }
}


package com.jardon.pg.algorithm.codeforce.r4xx.r482;

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

/**
 * @author Don Li
 */
public class KuroAndTopologicalParity2 {

    int MOD = (int) 1e9 + 7;
    int N = 55;

    long[] p2 = new long[N];
    long[][] c = new long[N][N];
    long[][] cs = new long[N][2];

    long[][][] dp = new long[N][N][N];

    {
        p2[0] = 1;
        for (int i = 1; i < N; i++) p2[i] = p2[i - 1] * 2 % MOD;

        for (int i = 0; i < N; i++) {
            c[i][0] = 1;
            for (int j = 1; j <= i; j++) c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % MOD;
        }

        for (int i = 0; i < N; i++) {
            for (int j = 0; j <= i; j++) {
                cs[i][j & 1] = (cs[i][j & 1] + c[i][j]) % MOD;
            }
        }
    }

    void solve() {
        int n = in.nextInt(), p = in.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) a[i] = in.nextInt();

        long ans = 0;
        dp[0][0][0] = 1;
        for (int i = 0; i < n; i++) {
            for (int ob = 0; ob <= i + 1; ob++) {
                for (int ow = 0; ob + ow <= i + 1; ow++) {
                    if (a[i] != 0 && i - ob >= 0) dp[i + 1][ob][ow] += dp[i][ob][ow] * p2[i - ob] * cs[ob][1];
                    if (a[i] != 0 && ow - 1 >= 0) dp[i + 1][ob][ow] += dp[i][ob][ow - 1] * p2[i - ob] * cs[ob][0];
                    if (a[i] != 1 && i - ow >= 0) dp[i + 1][ob][ow] += dp[i][ob][ow] * p2[i - ow] * cs[ow][1];
                    if (a[i] != 1 && ob - 1 >= 0) dp[i + 1][ob][ow] += dp[i][ob - 1][ow] * p2[i - ow] * cs[ow][0];
                    if (i + 1 == n && ((ob + ow) & 1) == p) ans += dp[i + 1][ob][ow];
                }
            }
        }
        out.println(ans);
    }

    public static void main(String[] args) {
        in = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
        new KuroAndTopologicalParity2().solve();
        out.close();
    }

    static FastScanner in;
    static PrintWriter out;

    static class FastScanner {
        BufferedReader in;
        StringTokenizer st;

        public FastScanner(BufferedReader in) {
            this.in = in;
        }

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

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

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

        public double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Iterator;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.NoSuchElementException;
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;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, OutputWriter out) {
            final int inf = 1000;
            int n, m;
            int[][] dist;
            IntArrayList[] gr;

//        n = in.readInt();
//        m = in.readInt();
            n = 400;

            dist = new int[n][n];
            ArrayUtils.fill(dist, inf);
            gr = new IntArrayList[n];
            for (int v = 0; v < n; v++) {
                dist[v][v] = 0;
                gr[v] = new IntArrayList();
            }

//        for (int iter = 0; iter < m; iter++) {
//            int a = in.readInt() - 1;
//            int b = in.readInt() - 1;
//            dist[a][b] = dist[b][a] = 1;
//            gr[a].add(b);
//            gr[b].add(a);
//        }
//
            for (int a = 0; a < n; a++) {
                for (int b = a + 1; b < n; b++) {
                    dist[a][b] = dist[b][a] = 1;
                    gr[a].add(b);
                    gr[b].add(a);
                }
            }

            for (int k = 0; k < n; k++) {
                for (int v = 0; v < n; v++) {
                    for (int to = 0; to < n; to++) {
                        dist[v][to] = Math.min(dist[v][to], dist[v][k] + dist[k][to]);
                    }
                }
            }

            boolean[] used = new boolean[n];
            IntArrayList citiesBear0 = new IntArrayList(n);
            IntArrayList citiesBear1 = new IntArrayList(n);

            double dp = 0;
            for (int v0 = 0; v0 < n; v0++) {
                double dp_V0 = 0;
                for (int d0 = 0; d0 < n; d0++) {

                    while (0 < citiesBear0.size()) {
                        citiesBear0.popLast();
                    }
                    while (0 < citiesBear1.size()) {
                        citiesBear1.popLast();
                    }
                    Arrays.fill(used, false);

                    for (int cityBear0 = 0; cityBear0 < n; cityBear0++) {
                        if (dist[v0][cityBear0] == d0) {
                            citiesBear0.add(cityBear0);
                            for (int cityBear1 : gr[cityBear0]) {
                                if (!used[cityBear1]) {
                                    used[cityBear1] = true;
                                    citiesBear1.add(cityBear1);
                                }
                            }
                        }
                    }

                    if (citiesBear0.size() == 0) {
                        continue;
                    }

                    double dp_V0_D0 = 0;
                    double coef = 1. / citiesBear0.size();
                    if (d0 != 0) {
                        double[] probV = new double[n];
                        for (int b0 : citiesBear0) {
                            int size = gr[b0].size();
                            for (int b1 : gr[b0]) {
                                probV[b1] += coef / size;
                            }
                        }

                        double[] probD = new double[n];
                        for (int v1 = 0; v1 < n; v1++) {
                            int[] dist_v1 = dist[v1];
//                    for (int b1 : citiesBear1) {
                            for (int i = 0, imax = citiesBear1.size(); i < imax; i++) {
                                int b1 = citiesBear1.get(i);
                                int d1 = dist_v1[b1];
                                probD[d1] = max(probD[d1], probV[b1]);
                            }
                            double dp_V0_D0_V1 = 0;
//                    for (int b1 : citiesBear1) {
                            for (int i = 0, imax = citiesBear1.size(); i < imax; i++) {
                                int b1 = citiesBear1.get(i);
                                int d1 = dist_v1[b1];
                                dp_V0_D0_V1 += probD[d1];
                                probD[d1] = 0;
                            }
                            dp_V0_D0 = max(dp_V0_D0, dp_V0_D0_V1);
                        }
                    }
                    dp_V0_D0 = max(dp_V0_D0, coef);

                    dp_V0 += ((double) citiesBear0.size() / n) * dp_V0_D0;
                }
                dp = max(dp, dp_V0);
            }
            out.printFormat("%.12f", dp);
            out.printLine();
        }

        private double max(double a, double b) {
            return a < b ? b : a;
        }

    }

    static interface IntStream extends Iterable<Integer>, Comparable<IntStream> {
        public IntIterator intIterator();

        default public Iterator<Integer> iterator() {
            return new Iterator<Integer>() {
                private IntIterator it = intIterator();

                public boolean hasNext() {
                    return it.isValid();
                }

                public Integer next() {
                    int result = it.value();
                    it.advance();
                    return result;
                }
            };
        }

        default public int compareTo(IntStream c) {
            IntIterator it = intIterator();
            IntIterator jt = c.intIterator();
            while (it.isValid() && jt.isValid()) {
                int i = it.value();
                int j = jt.value();
                if (i < j) {
                    return -1;
                } else if (i > j) {
                    return 1;
                }
                it.advance();
                jt.advance();
            }
            if (it.isValid()) {
                return 1;
            }
            if (jt.isValid()) {
                return -1;
            }
            return 0;
        }

    }

    static interface IntCollection extends IntStream {
        public int size();

        default public void add(int value) {
            throw new UnsupportedOperationException();
        }

        default public IntCollection addAll(IntStream values) {
            for (IntIterator it = values.intIterator(); it.isValid(); it.advance()) {
                add(it.value());
            }
            return this;
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void printLine() {
            writer.println();
        }

        public void printFormat(String format, Object... objects) {
            writer.printf(format, objects);
        }

        public void close() {
            writer.close();
        }

    }

    static class IntArrayList extends IntAbstractStream implements IntList {
        private int size;
        private int[] data;

        public IntArrayList() {
            this(3);
        }

        public IntArrayList(int capacity) {
            data = new int[capacity];
        }

        public IntArrayList(IntCollection c) {
            this(c.size());
            addAll(c);
        }

        public IntArrayList(IntStream c) {
            this();
            if (c instanceof IntCollection) {
                ensureCapacity(((IntCollection) c).size());
            }
            addAll(c);
        }

        public IntArrayList(IntArrayList c) {
            size = c.size();
            data = c.data.clone();
        }

        public IntArrayList(int[] arr) {
            size = arr.length;
            data = arr.clone();
        }

        public int size() {
            return size;
        }

        public int get(int at) {
            if (at >= size) {
                throw new IndexOutOfBoundsException("at = " + at + ", size = " + size);
            }
            return data[at];
        }

        private void ensureCapacity(int capacity) {
            if (data.length >= capacity) {
                return;
            }
            capacity = Math.max(2 * data.length, capacity);
            data = Arrays.copyOf(data, capacity);
        }

        public void addAt(int index, int value) {
            ensureCapacity(size + 1);
            if (index > size || index < 0) {
                throw new IndexOutOfBoundsException("at = " + index + ", size = " + size);
            }
            if (index != size) {
                System.arraycopy(data, index, data, index + 1, size - index);
            }
            data[index] = value;
            size++;
        }

        public void removeAt(int index) {
            if (index >= size || index < 0) {
                throw new IndexOutOfBoundsException("at = " + index + ", size = " + size);
            }
            if (index != size - 1) {
                System.arraycopy(data, index + 1, data, index, size - index - 1);
            }
            size--;
        }

    }

    static interface IntReversableCollection extends IntCollection {
    }

    static interface IntList extends IntReversableCollection {
        public abstract int get(int index);

        public abstract void addAt(int index, int value);

        public abstract void removeAt(int index);

        default public IntIterator intIterator() {
            return new IntIterator() {
                private int at;
                private boolean removed;

                public int value() {
                    if (removed) {
                        throw new IllegalStateException();
                    }
                    return get(at);
                }

                public boolean advance() {
                    at++;
                    removed = false;
                    return isValid();
                }

                public boolean isValid() {
                    return !removed && at < size();
                }

                public void remove() {
                    removeAt(at);
                    at--;
                    removed = true;
                }
            };
        }

        default public void add(int value) {
            addAt(size(), value);
        }

        default public void popLast() {
            removeAt(size() - 1);
        }

    }

    static class ArrayUtils {
        public static void fill(int[][] array, int value) {
            for (int[] row : array) {
                Arrays.fill(row, value);
            }
        }

    }

    static class InputReader {
        private InputStream stream;

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

    }

    static abstract class IntAbstractStream implements IntStream {

        public String toString() {
            StringBuilder builder = new StringBuilder();
            boolean first = true;
            for (IntIterator it = intIterator(); it.isValid(); it.advance()) {
                if (first) {
                    first = false;
                } else {
                    builder.append(' ');
                }
                builder.append(it.value());
            }
            return builder.toString();
        }

        public boolean equals(Object o) {
            if (!(o instanceof IntStream)) {
                return false;
            }
            IntStream c = (IntStream) o;
            IntIterator it = intIterator();
            IntIterator jt = c.intIterator();
            while (it.isValid() && jt.isValid()) {
                if (it.value() != jt.value()) {
                    return false;
                }
                it.advance();
                jt.advance();
            }
            return !it.isValid() && !jt.isValid();
        }

        public int hashCode() {
            int result = 0;
            for (IntIterator it = intIterator(); it.isValid(); it.advance()) {
                result *= 31;
                result += it.value();
            }
            return result;
        }

    }

    static interface IntIterator {
        public int value() throws NoSuchElementException;

        public boolean advance();

        public boolean isValid();

    }
}


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

public class CF {
	FastScanner in;
	PrintWriter out;

	final int TIMELIMIT = 6000;

	void solve() {
		long START = System.currentTimeMillis();
		int n = in.nextInt();
		int m = in.nextInt();
		final int[][] d = new int[n][n];
		for (int i = 0; i < n; i++) {
			Arrays.fill(d[i], Integer.MAX_VALUE / 3);
			d[i][i] = 0;
		}
		for (int i = 0; i < m; i++) {
			int fr = in.nextInt() - 1;
			int to = in.nextInt() - 1;
			d[fr][to] = d[to][fr] = 1;
		}
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				for (int k = 0; k < n; k++) {
					d[j][k] = Math.min(d[j][k], d[j][i] + d[i][k]);
				}
			}
		}
		Integer[][] g = new Integer[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				g[i][j] = j;
			}
			final int start = i;
			Arrays.sort(g[i], new Comparator<Integer>() {

				@Override
				public int compare(Integer o1, Integer o2) {
					return Integer.compare(d[start][o1], d[start][o2]);
				}
			});
		}
		double res = 0;
		double[] pr = new double[n];
		double p = 1. / n;
		int[] sz = new int[n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (d[i][j] == 1) {
					sz[i]++;
				}
			}
		}

		O[] a = new O[n];

		for (int start = 0; start < n; start++) {
			int val = 0;
			for (int posi = 0; posi < n;) {
				Arrays.fill(pr, 0);
				int posj = posi;
				while (posj != n
						&& d[start][g[start][posi]] == d[start][g[start][posj]]) {
					posj++;
				}
				val += (posj - posi) * (posj - posi);
				posi = posj;
			}
			a[start] = new O(start, val);
		}

		Arrays.sort(a);

		for (O o : a) {
			if (System.currentTimeMillis() - START > TIMELIMIT) {
				break;
			}
			int start = o.id;
			double cur = 0;
			for (int posi = 0; posi < n;) {
				Arrays.fill(pr, 0);
				int posj = posi;
				while (posj != n
						&& d[start][g[start][posi]] == d[start][g[start][posj]]) {
					posj++;
				}
				if (cur + p * (n - posi) < res) {
					break;
				}
				if (posj - posi == 1) {
					cur += p;
				} else {
					for (int ii = posi; ii < posj; ii++) {
						int v = g[start][ii];
						double add = p / sz[v];
						for (int j = 0; j < n; j++) {
							if (d[v][j] == 1) {
								pr[j] += add;
							}
						}
					}
					double tryThis = 0.0;
					for (O o2 : a) {
						int second = o2.id;
						double more = p;
						double myAns = 0.0;
						for (int tmpi = 0; tmpi < n;) {
							int tmpj = tmpi;
							while (tmpj != n
									&& d[second][g[second][tmpi]] == d[second][g[second][tmpj]]) {
								tmpj++;
							}
							double max = 0;
							for (int jj = tmpi; jj < tmpj; jj++) {
								int u = g[second][jj];
								max = Math.max(pr[u], max);
								more -= pr[u];
							}
							myAns += max;
							tmpi = tmpj;
							if (myAns + more <= tryThis) {
								break;
							}
						}
						tryThis = Math.max(tryThis, myAns);
					}
					cur += tryThis;
				}
				posi = posj;
			}
			res = Math.max(res, cur);
		}
		out.println(res);
	}

	class O implements Comparable<O> {
		int id, val;

		public O(int id, int val) {
			super();
			this.id = id;
			this.val = val;
		}

		@Override
		public int compareTo(O o) {
			return Integer.compare(val, o.val);
		}

	}

	void run() {
		try {
			in = new FastScanner(new File("object.in"));
			out = new PrintWriter(new File("object.out"));

			solve();

			out.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	void runIO() {

		in = new FastScanner(System.in);
		out = new PrintWriter(System.out);

		solve();

		out.close();
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		public FastScanner(File f) {
			try {
				br = new BufferedReader(new FileReader(f));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		public FastScanner(InputStream f) {
			br = new BufferedReader(new InputStreamReader(f));
		}

		String next() {
			while (st == null || !st.hasMoreTokens()) {
				String s = null;
				try {
					s = br.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (s == null)
					return null;
				st = new StringTokenizer(s);
			}
			return st.nextToken();
		}

		boolean hasMoreTokens() {
			while (st == null || !st.hasMoreTokens()) {
				String s = null;
				try {
					s = br.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (s == null)
					return false;
				st = new StringTokenizer(s);
			}
			return true;
		}

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

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

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

	public static void main(String[] args) {
		new CF().runIO();
	}
}


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

public class CF {
	FastScanner in;
	PrintWriter out;

	final int TIMELIMIT = 6000;

	void solve() {
		long START = System.currentTimeMillis();
		int n = in.nextInt();
		int m = in.nextInt();
		final int[][] d = new int[n][n];
		for (int i = 0; i < n; i++) {
			Arrays.fill(d[i], Integer.MAX_VALUE / 3);
			d[i][i] = 0;
		}
		for (int i = 0; i < m; i++) {
			int fr = in.nextInt() - 1;
			int to = in.nextInt() - 1;
			d[fr][to] = d[to][fr] = 1;
		}
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				for (int k = 0; k < n; k++) {
					d[j][k] = Math.min(d[j][k], d[j][i] + d[i][k]);
				}
			}
		}
		Integer[][] g = new Integer[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				g[i][j] = j;
			}
			final int start = i;
			Arrays.sort(g[i], new Comparator<Integer>() {

				@Override
				public int compare(Integer o1, Integer o2) {
					return Integer.compare(d[start][o1], d[start][o2]);
				}
			});
		}
		double res = 0;
		double[] pr = new double[n];
		double p = 1. / n;
		int[] sz = new int[n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (d[i][j] == 1) {
					sz[i]++;
				}
			}
		}

		O[] a = new O[n];

		for (int start = 0; start < n; start++) {
			int val = 0;
			for (int posi = 0; posi < n;) {
				Arrays.fill(pr, 0);
				int posj = posi;
				while (posj != n
						&& d[start][g[start][posi]] == d[start][g[start][posj]]) {
					posj++;
				}
				val += (posj - posi) * (posj - posi);
				posi = posj;
			}
			a[start] = new O(start, val);
		}

		Arrays.sort(a);

		for (O o : a) {
			if (System.currentTimeMillis() - START > TIMELIMIT) {
				break;
			}
			int start = o.id;
			double cur = 0;
			for (int posi = 0; posi < n;) {
				Arrays.fill(pr, 0);
				int posj = posi;
				while (posj != n
						&& d[start][g[start][posi]] == d[start][g[start][posj]]) {
					posj++;
				}
				if (cur + p * (n - posi) < res) {
					break;
				}
				if (posj - posi == 1) {
					cur += p;
				} else {
					for (int ii = posi; ii < posj; ii++) {
						int v = g[start][ii];
						double add = p / sz[v];
						for (int j = 0; j < n; j++) {
							if (d[v][j] == 1) {
								pr[j] += add;
							}
						}
					}
					double tryThis = p;
					for (O o2 : a) {
						int second = o2.id;
						double more = p * (posj - posi);
						double myAns = 0.0;
						for (int tmpi = 0; tmpi < n;) {
							int tmpj = tmpi;
							while (tmpj != n
									&& d[second][g[second][tmpi]] == d[second][g[second][tmpj]]) {
								tmpj++;
							}
							double max = 0;
							for (int jj = tmpi; jj < tmpj; jj++) {
								int u = g[second][jj];
								max = Math.max(pr[u], max);
								more -= pr[u];
							}
							myAns += max;
							tmpi = tmpj;
							if (myAns + more <= tryThis) {
								break;
							}
						}
						tryThis = Math.max(tryThis, myAns);
					}
					cur += tryThis;
				}
				posi = posj;
			}
			res = Math.max(res, cur);
		}
		out.println(res);
	}

	class O implements Comparable<O> {
		int id, val;

		public O(int id, int val) {
			super();
			this.id = id;
			this.val = val;
		}

		@Override
		public int compareTo(O o) {
			return Integer.compare(val, o.val);
		}

	}

	void run() {
		try {
			in = new FastScanner(new File("object.in"));
			out = new PrintWriter(new File("object.out"));

			solve();

			out.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	void runIO() {

		in = new FastScanner(System.in);
		out = new PrintWriter(System.out);

		solve();

		out.close();
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		public FastScanner(File f) {
			try {
				br = new BufferedReader(new FileReader(f));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		public FastScanner(InputStream f) {
			br = new BufferedReader(new InputStreamReader(f));
		}

		String next() {
			while (st == null || !st.hasMoreTokens()) {
				String s = null;
				try {
					s = br.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (s == null)
					return null;
				st = new StringTokenizer(s);
			}
			return st.nextToken();
		}

		boolean hasMoreTokens() {
			while (st == null || !st.hasMoreTokens()) {
				String s = null;
				try {
					s = br.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (s == null)
					return false;
				st = new StringTokenizer(s);
			}
			return true;
		}

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

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

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

	public static void main(String[] args) {
		new CF().runIO();
	}
}


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

public class CF {
	FastScanner in;
	PrintWriter out;

	final int TIMELIMIT = 6000;

	void solve() {
		long START = System.currentTimeMillis();
		int n = in.nextInt();
		int m = in.nextInt();
		final int[][] d = new int[n][n];
		for (int i = 0; i < n; i++) {
			Arrays.fill(d[i], Integer.MAX_VALUE / 3);
			d[i][i] = 0;
		}
		for (int i = 0; i < m; i++) {
			int fr = in.nextInt() - 1;
			int to = in.nextInt() - 1;
			d[fr][to] = d[to][fr] = 1;
		}
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				for (int k = 0; k < n; k++) {
					d[j][k] = Math.min(d[j][k], d[j][i] + d[i][k]);
				}
			}
		}
		Integer[][] g = new Integer[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				g[i][j] = j;
			}
			final int start = i;
			Arrays.sort(g[i], new Comparator<Integer>() {

				@Override
				public int compare(Integer o1, Integer o2) {
					return Integer.compare(d[start][o1], d[start][o2]);
				}
			});
		}
		double res = 0;
		double[] pr = new double[n];
		double p = 1. / n;
		int[] sz = new int[n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (d[i][j] == 1) {
					sz[i]++;
				}
			}
		}

		O[] a = new O[n];

		for (int start = 0; start < n; start++) {
			int val = 0;
			for (int posi = 0; posi < n;) {
				Arrays.fill(pr, 0);
				int posj = posi;
				while (posj != n
						&& d[start][g[start][posi]] == d[start][g[start][posj]]) {
					posj++;
				}
				val += (posj - posi) * (posj - posi);
				posi = posj;
			}
			a[start] = new O(start, val);
		}

		Arrays.sort(a);

		for (O o : a) {
			if (System.currentTimeMillis() - START > TIMELIMIT) {
				break;
			}
			int start = o.id;
			double cur = 0;
			for (int posi = 0; posi < n;) {
				Arrays.fill(pr, 0);
				int posj = posi;
				while (posj != n
						&& d[start][g[start][posi]] == d[start][g[start][posj]]) {
					posj++;
				}
				if (cur + p * (n - posi) < res) {
					break;
				}
				if (posj - posi == 1) {
					cur += p;
				} else {
					for (int ii = posi; ii < posj; ii++) {
						int v = g[start][ii];
						double add = p / sz[v];
						for (int j = 0; j < n; j++) {
							if (d[v][j] == 1) {
								pr[j] += add;
							}
						}
					}
					double tryThis = p;
					for (O o2 : a) {
						int second = o2.id;
						double more = p;
						double myAns = 0.0;
						for (int tmpi = 0; tmpi < n;) {
							int tmpj = tmpi;
							while (tmpj != n
									&& d[second][g[second][tmpi]] == d[second][g[second][tmpj]]) {
								tmpj++;
							}
							double max = 0;
							for (int jj = tmpi; jj < tmpj; jj++) {
								int u = g[second][jj];
								max = Math.max(pr[u], max);
								more -= pr[u];
							}
							myAns += max;
							tmpi = tmpj;
							if (myAns + more <= tryThis) {
								break;
							}
						}
						tryThis = Math.max(tryThis, myAns);
					}
					cur += tryThis;
				}
				posi = posj;
			}
			res = Math.max(res, cur);
		}
		out.println(res);
	}

	class O implements Comparable<O> {
		int id, val;

		public O(int id, int val) {
			super();
			this.id = id;
			this.val = val;
		}

		@Override
		public int compareTo(O o) {
			return Integer.compare(val, o.val);
		}

	}

	void run() {
		try {
			in = new FastScanner(new File("object.in"));
			out = new PrintWriter(new File("object.out"));

			solve();

			out.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	void runIO() {

		in = new FastScanner(System.in);
		out = new PrintWriter(System.out);

		solve();

		out.close();
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		public FastScanner(File f) {
			try {
				br = new BufferedReader(new FileReader(f));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		public FastScanner(InputStream f) {
			br = new BufferedReader(new InputStreamReader(f));
		}

		String next() {
			while (st == null || !st.hasMoreTokens()) {
				String s = null;
				try {
					s = br.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (s == null)
					return null;
				st = new StringTokenizer(s);
			}
			return st.nextToken();
		}

		boolean hasMoreTokens() {
			while (st == null || !st.hasMoreTokens()) {
				String s = null;
				try {
					s = br.readLine();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (s == null)
					return false;
				st = new StringTokenizer(s);
			}
			return true;
		}

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

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

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

	public static void main(String[] args) {
		new CF().runIO();
	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
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);
		TaskD solver = new TaskD();
		solver.solve(1, in, out);
		out.close();
	}

	static class TaskD {
		public void solve(int testNumber, FastScanner in, PrintWriter out) {
			long n = in.nextLong();
			long inputL = in.nextLong() - 1;
			long inputR = in.nextLong() - 1;
			long k = in.nextLong();
			long d = dist(inputL, inputR, n);

			final long BIG = (long) 3e5;
			long ans = -1;
//		if (n >= BIG) {
			if (true) {
//		if (false) {
				// c full circles.
				for (long c = 0; n * c <= k; c++) {
					long l = -1;
					long r = n + 1;
					while (r - l > 1) {
						long m = l + (r - l) / 2;
						if (canLB(n, k, d, c, m)) {
							l = m;
						} else {
							r = m;
						}
					}
					if (l >= 0 && canUB(n, k, d, c, l)) {
						ans = Math.max(ans, l);
					}
				}
			} else {
				// s sweet lovers.
				for (long s = 0; s <= n; s++) {
					long minC = 0;
					long maxC = 0;
					{
						long b = Math.min(d, n - s);
						long a = d - b;
						long p = k - a - d;
						if (a > 0) {
							++p;
						}
						if (p < 0) {
							continue;
						}
						maxC = p / (n + s);
					}
					{
						long a = Math.min(d, s);
						long b = d - a;
						long p = k - a - d;
						p += n + s - 1;
						if (p < 0) {
							continue;
						}
						minC = p / (n + s);
					}
					if (minC <= maxC) {
						ans = Math.max(ans, s);
					}
				}
			}
			out.println(ans);
		}

		private boolean canLB(long n, long k, long d, long c, long s) {
			long minK = -1;
			long b = Math.min(d, n - s);
			long a = d - b;
			minK = (n + s) * c + d + a;
			if (a > 0 && minK > 0) {
				// Last "a" takes one.
				--minK;
			}
			return k >= minK;
		}

		private boolean canUB(long n, long k, long d, long c, long s) {
			long maxK = -1;
			long a = Math.min(d, s);
			long b = d - a;
			maxK = (n + s) * c + d + a;
			return k <= maxK;
		}

		private long dist(long l, long r, long n) {
			while (r < l) {
				r += n;
			}
			return r - l + 1;
		}

	}

	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 {
					String rl = in.readLine();
					if (rl == null) {
						return null;
					}
					st = new StringTokenizer(rl);
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
			return st.nextToken();
		}

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

	}
}


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

/**
 * @author Don Li
 */
public class CandiesForChildren {

    long INF = (long) 1e18;

    void solve() {
        long n = in.nextLong(), l = in.nextLong() - 1, r = in.nextLong() - 1, k = in.nextLong();

        if (r < l) r += n;
        long a = r - l + 1, b = n - a;

        long ans = -1;
        if (n <= Math.cbrt(k)) {
            for (long x = 0; x <= a; x++) {
                for (long y = 0; y <= b; y++) {
                    long c = k - x - a;
                    if (c >= 0 && c % (x + y + n) == 0) ans = Math.max(ans, x + y);
                    if (c + 1 >= 0 && (c + 1) % (x + y + n) == 0 && x > 0) ans = Math.max(ans, x + y);
                }
            }
        } else {
            for (long t = 0; t <= k / n; t++) {
                long c = k - n * t - a;
                if (c >= 0) {
                    if (t == 0) {
                        if (c <= a) ans = Math.max(ans, c + b);
                    } else {
                        long x = c, y = -c;
                        long kl = -INF, kr = INF;

                        if (a - x >= 0) kr = Math.min(kr, (a - x) / t);
                        else kr = Math.min(kr, -((x - a + t - 1) / t));
                        if (x >= 0) kl = Math.max(kl, -x / t);
                        else kl = Math.max(kl, (-x + t - 1) / t);

                        if (y - b >= 0) kl = Math.max(kl, (y - b + t) / (t + 1));
                        else kl = Math.max(kl, (y - b) / (t + 1));
                        if (y >= 0) kr = Math.min(kr, y / (t + 1));
                        else kr = Math.min(kr, -((-y + t) / (t + 1)));

                        if (kl <= kr) ans = Math.max(ans, x + y - kl);
                    }
                }
                c++;
                if (c >= 0) {
                    if (t == 0) {
                        if (c <= a) ans = Math.max(ans, c + b);
                    } else {
                        long x = c, y = -c;
                        long kl = -INF, kr = INF;

                        if (a - x >= 0) kr = Math.min(kr, (a - x) / t);
                        else kr = Math.min(kr, -((x - a + t - 1) / t));
                        if (x - 1 >= 0) kl = Math.max(kl, (1 - x) / t);
                        else kl = Math.max(kl, (1 - x + t - 1) / t);

                        if (y - b >= 0) kl = Math.max(kl, (y - b + t) / (t + 1));
                        else kl = Math.max(kl, (y - b) / (t + 1));
                        if (y >= 0) kr = Math.min(kr, y / (t + 1));
                        else kr = Math.min(kr, -((-y + t) / (t + 1)));

                        if (kl <= kr) ans = Math.max(ans, x + y - kl);
                    }
                }
            }
        }
        out.println(ans);
    }

    long[] gcd(long a, long b) {
        if (b == 0) return new long[]{a, 1, 0};
        long[] r = gcd(b, a % b);
        return new long[]{r[0], r[2], r[1] - a / b * r[2]};
    }

    public static void main(String[] args) {
        in = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
        new CandiesForChildren().solve();
        out.close();
    }

    static FastScanner in;
    static PrintWriter out;

    static class FastScanner {
        BufferedReader in;
        StringTokenizer st;

        public FastScanner(BufferedReader in) {
            this.in = in;
        }

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

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

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

        public double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }
}


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

public class D {

	long go1(long n, long s, long k) {

		// no overeating
		long ans1 = -1;
		for (long c2 = n; c2 >= 0; c2--) {
			long full = n + c2;

			long last = k % full;
			if (last == 0) {
				last = full;
			}

			long last2 = last - s;
			long rest2 = c2 - last2;

			if (!(0 <= last2 && last2 <= s && 0 <= rest2 && rest2 <= n - s)) {
				continue;
			}

			ans1 = c2;
			break;
		}

		long ans2 = -1;
		// overeating!
		for (long c2 = n; c2 > 0; c2--) {
			long full = n + c2;

			long last = (k + 1) % full;
			if (last == 0) {
				last = full;
			}

			long last2 = last - s;
			long rest2 = c2 - last2;

			if (!(0 <= last2 && last2 <= s && 0 <= rest2 && rest2 <= n - s)) {
				continue;
			}

			if (last2 == 0) {
				continue;
			}

			ans2 = c2;
			break;
		}

		return Math.max(ans1, ans2);
	}

	void submit() {
		long n = nextLong();
		long l = nextLong();
		long r = nextLong();
		long k = nextLong();

		long s;
		if (l <= r) {
			s = r - l + 1;
		} else {
			s = r - l + 1 + n;
		}

		out.println(go1(n, s, k));

//		if (n <= C) {
//			out.println(go1(n, s, k));
//		} else {
//			out.println(go2(n, s, k));
//		}
	}

	void test() {

	}

	void stress() {
		for (int tst = 0;; tst++) {
			if (false) {
				throw new AssertionError();
			}
			System.err.println(tst);
		}
	}

	D() throws IOException {
		is = System.in;
		out = new PrintWriter(System.out);
		submit();
		// stress();
		// test();
		out.close();
	}

	static final Random rng = new Random();
	static final int C = 10_000_000;

	static int rand(int l, int r) {
		return l + rng.nextInt(r - l + 1);
	}

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

	private InputStream is;
	PrintWriter out;

	private byte[] buf = new byte[1 << 14];
	private int bufSz = 0, bufPtr = 0;

	private int readByte() {
		if (bufSz == -1)
			throw new RuntimeException("Reading past EOF");
		if (bufPtr >= bufSz) {
			bufPtr = 0;
			try {
				bufSz = is.read(buf);
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
			if (bufSz <= 0)
				return -1;
		}
		return buf[bufPtr++];
	}

	private boolean isTrash(int c) {
		return c < 33 || c > 126;
	}

	private int skip() {
		int b;
		while ((b = readByte()) != -1 && isTrash(b))
			;
		return b;
	}

	String nextToken() {
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!isTrash(b)) {
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	String nextString() {
		int b = readByte();
		StringBuilder sb = new StringBuilder();
		while (!isTrash(b) || b == ' ') {
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

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

	char nextChar() {
		return (char) skip();
	}

	int nextInt() {
		int ret = 0;
		int b = skip();
		if (b != '-' && (b < '0' || b > '9')) {
			throw new InputMismatchException();
		}
		boolean neg = false;
		if (b == '-') {
			neg = true;
			b = readByte();
		}
		while (true) {
			if (b >= '0' && b <= '9') {
				ret = ret * 10 + (b - '0');
			} else {
				if (b != -1 && !isTrash(b)) {
					throw new InputMismatchException();
				}
				return neg ? -ret : ret;
			}
			b = readByte();
		}
	}

	long nextLong() {
		long ret = 0;
		int b = skip();
		if (b != '-' && (b < '0' || b > '9')) {
			throw new InputMismatchException();
		}
		boolean neg = false;
		if (b == '-') {
			neg = true;
			b = readByte();
		}
		while (true) {
			if (b >= '0' && b <= '9') {
				ret = ret * 10 + (b - '0');
			} else {
				if (b != -1 && !isTrash(b)) {
					throw new InputMismatchException();
				}
				return neg ? -ret : ret;
			}
			b = readByte();
		}
	}
}


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

/**
 * @author Don Li
 */
public class CandiesForChildren {

    long INF = (long) 1e18;

    void solve() {
        long n = in.nextLong(), l = in.nextLong() - 1, r = in.nextLong() - 1, k = in.nextLong();

        if (r < l) r += n;
        long a = r - l + 1, b = n - a;

        long ans = -1;
        if (n <= Math.cbrt(k)) {
            for (long x = 0; x <= a; x++) {
                for (long y = 0; y <= b; y++) {
                    long c = k - x - a;
                    if (c >= 0 && c % (x + y + n) == 0) ans = Math.max(ans, x + y);
                    if (c + 1 >= 0 && (c + 1) % (x + y + n) == 0 && x > 0) ans = Math.max(ans, x + y);
                }
            }
        } else {
            for (long t = 0; t <= k / n; t++) {
                long c = k - n * t - a;
                if (c >= 0) {
                    if (t == 0) {
                        if (c <= a) ans = Math.max(ans, c + b);
                    } else {
                        long[] ret = gcd(t + 1, t);
                        long g = ret[0], x = ret[1], y = ret[2];
                        x *= c / g; y *= c / g;
                        long kl = -INF, kr = INF;

                        if (a - x >= 0) kr = Math.min(kr, (a - x) / t);
                        else kr = Math.min(kr, -((x - a + t - 1) / t));
                        if (x >= 0) kl = Math.max(kl, -x / t);
                        else kl = Math.max(kl, (-x + t - 1) / t);

                        if (y - b >= 0) kl = Math.max(kl, (y - b + t) / (t + 1));
                        else kl = Math.max(kl, (y - b) / (t + 1));
                        if (y >= 0) kr = Math.min(kr, y / (t + 1));
                        else kr = Math.min(kr, -((-y + t) / (t + 1)));

                        if (kl <= kr) ans = Math.max(ans, x + y - kl);
                    }
                }
                c++;
                if (c >= 0) {
                    if (t == 0) {
                        if (c <= a) ans = Math.max(ans, c + b);
                    } else {
                        long[] ret = gcd(t + 1, t);
                        long g = ret[0], x = ret[1], y = ret[2];
                        x *= c / g; y *= c / g;
                        long kl = -INF, kr = INF;

                        if (a - x >= 0) kr = Math.min(kr, (a - x) / t);
                        else kr = Math.min(kr, -((x - a + t - 1) / t));
                        if (x - 1 >= 0) kl = Math.max(kl, (1 - x) / t);
                        else kl = Math.max(kl, (1 - x + t - 1) / t);

                        if (y - b >= 0) kl = Math.max(kl, (y - b + t) / (t + 1));
                        else kl = Math.max(kl, (y - b) / (t + 1));
                        if (y >= 0) kr = Math.min(kr, y / (t + 1));
                        else kr = Math.min(kr, -((-y + t) / (t + 1)));

                        if (kl <= kr) ans = Math.max(ans, x + y - kl);
                    }
                }
            }
        }
        out.println(ans);
    }

    long[] gcd(long a, long b) {
        if (b == 0) return new long[]{a, 1, 0};
        long[] r = gcd(b, a % b);
        return new long[]{r[0], r[2], r[1] - a / b * r[2]};
    }

    public static void main(String[] args) {
        in = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
        new CandiesForChildren().solve();
        out.close();
    }

    static FastScanner in;
    static PrintWriter out;

    static class FastScanner {
        BufferedReader in;
        StringTokenizer st;

        public FastScanner(BufferedReader in) {
            this.in = in;
        }

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

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

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

        public double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }
}


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

import static java.lang.Integer.min;
import static java.lang.Integer.max;

public class e1542easy {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);

        solve(s.nextInt(), s.nextInt());
    }

    public static void solve(int n, int mod) {
        ArrayList<long[]> inversions = new ArrayList<>();
        inversions.add(new long[]{1});

        long last[];
        long next[];
        for (int i = 1; i < n; i++) {
            last = inversions.get(i - 1);
            next = new long[i * (i + 1) / 2 + 1];

            int e;
            for (int j = 0; j < next.length; j++) {
                e = 0;
                for (int k = min(j, i); k >= 0; k--) {
                    if (j - k < last.length) {
                        e += last[j - k];
                        e = e % mod;
                    }
                }
                next[j] = e;
            }

            inversions.add(next);
        }

        for (int i = 0; i < n; i++) {
            //System.out.println(Arrays.toString(inversions.get(i)));
        }

        long perms[] = new long[n];
        perms[0] = 0;

        long c;
        long inv[];
        long m;
        for (int i = 1; i < n; i++) {
            c = (perms[i - 1] * (i + 1)) % mod;

            inv = inversions.get(i - 1);
            for (int j = 0; j < inv.length; j++) {
                for (int k = j + 2; k < inv.length; k++) {
                    m = min(k - j, i + 1);
                    c = (c + ((inv[j] * inv[k]) % mod) * ((m - 1) * (2 * i - (m - 2)) / 2)) % mod;
                }
            }

            perms[i] = c;
        }

        //System.out.println(Arrays.toString(perms));
        System.out.println(perms[n - 1]);
    }
}


import javax.swing.*;
import java.lang.reflect.Array;
import java.text.DecimalFormat;
import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.*;
import java.util.stream.Stream;

// Please name your class Main
public class Main {
    static FastScanner fs=new FastScanner();
    static class FastScanner {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st=new StringTokenizer("");
        public String next() {
            while (!st.hasMoreElements())
                try {
                    st=new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            return st.nextToken();
        }
        int Int() {
            return Integer.parseInt(next());
        }

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

        String Str(){
            return next();
        }
    }

    public static void main (String[] args) throws java.lang.Exception {
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        //reading /writing file
        //Scanner in=new Scanner(System.in);
        //Scanner in=new Scanner(new File("input.txt"));
        //PrintWriter pr=new PrintWriter("output.txt");

        int T=1;
        for(int t=0;t<T;t++){
            Solution sol1=new Solution(out,fs);
            sol1.solution(T,t);
        }
        out.flush();

    }

    public static int[] Arr(int n){
        int A[]=new int[n];
        for(int i=0;i<n;i++)A[i]=Int();
        return A;
    }
    public static int Int(){
        return fs.Int();
    }
    public static long Long(){
        return fs.Long();
    }
    public static String Str(){
        return fs.Str();
    }

}

class Solution {
    PrintWriter out;
    int INF = Integer.MAX_VALUE;
    int NINF = Integer.MIN_VALUE;
    int MOD = 998244353;
    int mod = 1000000007;
    Main.FastScanner fs;

    public Solution(PrintWriter out, Main.FastScanner fs) {
        this.out = out;
        this.fs = fs;

    }

    public void solution(int all, int testcase) {
        int n = fs.Int();
        mod = fs.Int();
        long dp[] = new long[n * n + 5];
        dp[0] = 1;
        long sums[] = new long[dp.length];
        sums[0] = dp[0];
        for(int i = 1; i < sums.length;i++){
            sums[i] = sums[i - 1] + dp[i];
        }

        //init
        long fact[] = new long[501 * 501];
        fact[0] = fact[1] = 1;
        for(int i = 2; i < fact.length;i++){
            fact[i] = fact[i - 1] * i;
            fact[i] %= mod;
        }
        long ncr[][] = new long[501][501];
        ncr[0][0]=1;
        for (int i=1;i<ncr.length;i++) {
            ncr[i][0]=1;
            for (int j=1;j<ncr[0].length;j++) {
                ncr[i][j]=(ncr[i-1][j] + ncr[i-1][j-1])%mod;
                if(ncr[i][j] == 0)ncr[i][j] += mod;
            }
        }

        //cnt == 2, dp == 0
        int I = 1;

        long res = 0;
        for(int i = n - 2; i >= 0; i--) {
            int cnt = n - i;
            int pre = n - cnt;
            long com = (ncr[n][pre] * fact[pre]) % mod;
            if(com == 0) com += mod;
            long sum = 0;
            long last[] = dp;

            //System.out.println(i+"  "+Arrays.toString(dp));

            long ssum = 0;
            long total =0;
            for(int j = 2; j < dp.length; j++) { // j == inversions
                if(dp[j]==0)break;
                total += sums[j - 2] * (cnt - 1);
                total %= mod;
                if(total == 0) total += mod;

                sum += last[j] * total;
                sum %= mod;
                if(sum == 0) sum += mod;

                ssum += sums[j - 2];
                if(j - cnt - 1 >= 0) {
                    ssum -= sums[j - cnt - 1];
                }
                ssum += mod;
                ssum %= mod;
                if(ssum == 0) ssum += mod;

                total -= ssum;
                total += mod;
                total %= mod;
                if(total == 0)total += mod;
            }
            res += sum * com;
            res%=mod;
            if(res == 0) res += mod;

            long cur[] = new long[dp.length];
            for(int j = 0; j < dp.length; j++) {
                cur[j] = get(sums, j, Math.max(0,j - I));
                cur[j] %= mod;
            }

            dp = cur;
            sums[0] = cur[0];
            for(int j = 1; j < cur.length; j++){
                sums[j] = sums[j - 1] + dp[j];
                sums[j] %= mod;
                if(sums[j] == 0){
                    sums[j] += mod;
                }
            }
            I++;
        }
        out.println(res % mod);
    }

    public long get(long sum[], int i, int j){
        if(j == 0) return sum[i];
        return (sum[i] - sum[j - 1] + mod) % mod;
    }
}


import javax.swing.*;
import java.lang.reflect.Array;
import java.text.DecimalFormat;
import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.*;
import java.util.stream.Stream;

// Please name your class Main
public class Main {
    static FastScanner fs=new FastScanner();
    static class FastScanner {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st=new StringTokenizer("");
        public String next() {
            while (!st.hasMoreElements())
                try {
                    st=new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            return st.nextToken();
        }
        int Int() {
            return Integer.parseInt(next());
        }

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

        String Str(){
            return next();
        }
    }

    public static void main (String[] args) throws java.lang.Exception {
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        //reading /writing file
        //Scanner in=new Scanner(System.in);
        //Scanner in=new Scanner(new File("input.txt"));
        //PrintWriter pr=new PrintWriter("output.txt");

        int T=1;
        for(int t=0;t<T;t++){
            Solution sol1=new Solution(out,fs);
            sol1.solution(T,t);
        }
        out.flush();

    }

    public static int[] Arr(int n){
        int A[]=new int[n];
        for(int i=0;i<n;i++)A[i]=Int();
        return A;
    }
    public static int Int(){
        return fs.Int();
    }
    public static long Long(){
        return fs.Long();
    }
    public static String Str(){
        return fs.Str();
    }

}

class Solution {
    PrintWriter out;
    int INF = Integer.MAX_VALUE;
    int NINF = Integer.MIN_VALUE;
    int MOD = 998244353;
    int mod = 1000000007;
    Main.FastScanner fs;

    public Solution(PrintWriter out, Main.FastScanner fs) {
        this.out = out;
        this.fs = fs;

    }

    public void solution(int all, int testcase) {
        int n = fs.Int();
        mod = fs.Int();

        int dp[] = new int[n * n + 5];
        dp[0] = 1;
        int sums[] = new int[dp.length];
        sums[0] = dp[0];
        for(int i = 1; i < sums.length;i++){
            sums[i] = sums[i - 1] + dp[i];
        }

        //init
        int fact[] = new int[501 * 501];
        fact[0] = fact[1] = 1;
        for(int i = 2; i < fact.length;i++){
            fact[i] = fact[i - 1] * i;
            fact[i] %= mod;
        }
        int ncr[][] = new int[501][501];
        ncr[0][0]=1;
        for (int i=1;i<ncr.length;i++) {
            ncr[i][0]=1;
            for (int j=1;j<ncr[0].length;j++) {
                ncr[i][j]=(ncr[i-1][j] + ncr[i-1][j-1])%mod;
                if(ncr[i][j] == 0)ncr[i][j] += mod;
            }
        }

        //cnt == 2, dp == 0
        int I = 1;

        long res = 0;
        for(int i = n - 2; i >= 0; i--) {
            int cnt = n - i;
            int pre = n - cnt;
            long com = ((ncr[n][pre] + 0l) * fact[pre]) % mod;
            if(com == 0) com += mod;
            long sum = 0;
            int last[] = dp;

            //System.out.println(i+"  "+Arrays.toString(dp));

            long ssum = 0;
            long total =0;
            for(int j = 2; j < dp.length; j++) { // j == inversions
                total += (sums[j - 2] + 0l) * (cnt - 1);
                total %= mod;
                if(total == 0) total += mod;

                sum += last[j] * total;
                sum %= mod;
                if(sum == 0) sum += mod;

                ssum += sums[j - 2];
                if(j - cnt - 1 >= 0) {
                    ssum -= sums[j - cnt - 1];
                }
                ssum += mod;
                ssum %= mod;
                if(ssum == 0) ssum += mod;

                total -= ssum;
                total += mod;
                total %= mod;
                if(total == 0)total += mod;
            }
            res += sum * com;
            res%=mod;
            if(res == 0) res += mod;

            int cur[] = new int[dp.length];
            for(int j = 0; j < dp.length; j++) {
                cur[j] = get(sums, j, Math.max(0,j - I));
                cur[j] %= mod;
                if(cur[j] == 0){
                    cur[j] += mod;
                }
            }

            dp = cur;
            sums[0] = cur[0];
            for(int j = 1; j < cur.length; j++){
                sums[j] = sums[j - 1] + dp[j];
                sums[j] %= mod;
                if(sums[j] == 0){
                    sums[j] += mod;
                }
            }
            I++;
        }
        out.println(res % mod);
    }

    public int get(int sum[], int i, int j){
        if(j == 0) return sum[i];
        return (sum[i] - sum[j - 1] + mod) % mod;
    }
}


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Map.Entry;
import java.util.StringTokenizer;
import java.util.TreeMap;

public class Techno19_2F {

	static int MODE = -1;

	static final Comparator<int[]> COMP_ARR = new Comparator<int[]>() {
		public int compare(int[] a1, int[] a2) {
			if (MODE != -1 && (a1.length == 32 || a2.length == 32)) {
				if (a1.length == 32) {
					if (MODE < a2.length) {
						return -1;
					}
					if (MODE > a2.length) {
						return 1;
					}
				} else {
					if (a1.length < MODE) {
						return -1;
					}
					if (a1.length > MODE) {
						return 1;
					}
				}

				for (int i = 0; i < MODE; i++) {
					if (a1[i] < a2[i]) {
						return -1;
					}
					if (a1[i] > a2[i]) {
						return 1;
					}
				}
				return 0;
			} else {
				if (a1.length < a2.length) {
					return -1;
				}
				if (a1.length > a2.length) {
					return 1;
				}

				for (int i = 0; i < a2.length; i++) {
					if (a1[i] < a2[i]) {
						return -1;
					}
					if (a1[i] > a2[i]) {
						return 1;
					}
				}
				return 0;
			}
		}
	};

	static TreeMap<int[], Integer> index = new TreeMap<>(COMP_ARR);
	static int[][] states;

	static ArrayList<int[]> start = new ArrayList<>();

	static int[] numD;

	static int[] pFact = new int[1_000_001];

	static TreeMap<int[], Integer> divCostInd = new TreeMap<>(COMP_ARR);

	public static void main(String[] args) throws IOException {
		cGen = new int[23];
		numD = new int[6000];
		states = new int[6000][];
		genAll(0, 23, 23, 1);

		aList = new ArrayList[6000];
		for (int i = 0; i < 6000; i++) {
			aList[i] = new ArrayList<>();
		}
		fAList();

		divCost = new int[400][301];
		for (int[] a : divCost) {
			Arrays.fill(a, Integer.MAX_VALUE / 2);
		}
		cost = new int[index.size()];

		Arrays.fill(pFact, 1);
		for (int i = 2; i <= 1_000_000; i++) {
			if (pFact[i] == 1) {
				for (int m = i; m <= 1_000_000; m += i) {
					pFact[m] = i;
				}
			}
		}

		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter printer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));

		int nT = Integer.parseInt(reader.readLine());

		while (nT-- > 0) {
			StringTokenizer inputData = new StringTokenizer(reader.readLine());
			int a = Integer.parseInt(inputData.nextToken());
			int b = Integer.parseInt(inputData.nextToken());

			int[] aA = toArray(a);
			int[] bA = toArray(b);

			Integer aRes = divCostInd.get(aA);
			if (aRes == null) {
				aRes = divCostInd.size();
				bfs(aA, divCostInd.size());
				divCostInd.put(aA, divCostInd.size());
			}
			Integer bRes = divCostInd.get(bA);
			if (bRes == null) {
				bRes = divCostInd.size();
				bfs(bA, divCostInd.size());
				divCostInd.put(bA, divCostInd.size());
			}

			int minA = Integer.MAX_VALUE / 4;
			for (int nD = 1; nD <= 300; nD++) {
				minA = Math.min(minA, divCost[aRes][nD] + divCost[bRes][nD]);
			}
			printer.println(minA);
		}
		printer.close();
	}

	static int[] toArray(int a) {
		ArrayList<Integer> cnts = new ArrayList<Integer>();
		int last = -1;
		int cCnt = 0;

		while (a > 1) {
			int cPFact = pFact[a];
			if (cPFact == last) {
				cCnt++;
			} else {
				if (cCnt != 0) {
					cnts.add(cCnt);
				}
				last = cPFact;
				cCnt = 1;
			}
			a /= pFact[a];
		}
		if (cCnt != 0) {
			cnts.add(cCnt);
		}
		Collections.sort(cnts, Comparator.reverseOrder());
		int[] res = new int[cnts.size()];
		for (int i = 0; i < cnts.size(); i++) {
			res[i] = cnts.get(i);
		}
		return res;
	}

	static int[] cost;

	static int[][] divCost;

	static void bfs(int[] sState, int searchI) {
		int sInd = index.get(sState);
		ArrayDeque<Integer> queue = new ArrayDeque<>();

		queue.add(index.get(sState));

		Arrays.fill(cost, -1);
		cost[sInd] = 0;

		while (!queue.isEmpty()) {
			int cStInd = queue.remove();
			for (int nStInd : aList[cStInd]) {
				if (cost[nStInd] == -1) {
					cost[nStInd] = cost[cStInd] + 1;
					queue.add(nStInd);
				}
			}
		}

		for (Entry<int[], Integer> cE : index.entrySet()) {
			int cNumD = numD[cE.getValue()];
			if (cNumD <= 300) {
				divCost[searchI][cNumD] = Math.min(divCost[searchI][cNumD], cost[cE.getValue()]);
			}
		}
	}

	static ArrayList<Integer>[] aList;

	static void fAList() {
		int[] cState = new int[32];
		for (Entry<int[], Integer> cE : index.entrySet()) {
			int[] oState = cE.getKey();
			int cStInd = cE.getValue();

			int cLen = states[cStInd].length;
			for (int i = 0; i < cLen; i++) {
				cState[i] = oState[i];
			}
			MODE = cLen;

			for (int i = 0; i < cLen; i++) {
				if (i == 0 || cState[i - 1] > cState[i]) {
					cState[i]++;
					Integer nStInd = index.get(cState);
					cState[i]--;

					if (nStInd == null) {
						continue;
					}
					aList[cStInd].add(nStInd);
				}

				if (i == cLen - 1 && cState[i] == 1) {
					MODE--;
					Integer nStInd = index.get(cState);
					MODE++;
					if (nStInd == null) {
						continue;
					}
					aList[cStInd].add(nStInd);
				} else if (i == cLen - 1 || cState[i] > cState[i + 1]) {
					cState[i]--;
					Integer nStInd = index.get(cState);
					cState[i]++;
					if (nStInd == null) {
						continue;
					}
					aList[cStInd].add(nStInd);
				}
			}
			cState[cLen] = 1;

			MODE++;
			Integer nStInd = index.get(cState);
			MODE--;
			if (nStInd == null) {
				continue;
			}
			aList[cStInd].add(nStInd);
		}
	}

	static int[] cGen;

	static void genAll(int i, int max, int rem, int cProd) {
		numD[index.size()] = cProd;

		int[] cKey = Arrays.copyOf(cGen, i);
		states[index.size()] = cKey;
		index.put(cKey, index.size());

		if (rem > 0) {
			for (int nV = Math.min(max, rem); nV >= 1; nV--) {
				cGen[i] = nV;
				genAll(i + 1, nV, rem - nV, cProd * (nV + 1));
			}
		}
	}
}