Problem: Petya learned a new programming language CALPAS. A program in this language always takes one non-negative integer and returns one non-negative integer as well.

In the language, there are only three commands: apply a bitwise operation AND, OR or XOR with a given constant to the current integer. A program can contain an arbitrary sequence of these operations with arbitrary constants from 0 to 1023. When the program is run, all operations are applied (in the given order) to the argument and in the end the result integer is returned.

Petya wrote a program in this language, but it turned out to be too long. Write a program in CALPAS that does the same thing as the Petya's program, and consists of no more than 5 lines. Your program should return the same integer as Petya's program for all arguments from 0 to 1023.

Input

The first line contains an integer n (1 ≤ n ≤ 5·105) — the number of lines.

Next n lines contain commands. A command consists of a character that represents the operation ("&", "|" or "^" for AND, OR or XOR respectively), and the constant xi 0 ≤ xi ≤ 1023.

Output

Output an integer k (0 ≤ k ≤ 5) — the length of your program.

Next k lines must contain commands in the same format as in the input.

Examples

Input

3
| 3
^ 2
| 1


Output

2
| 3
^ 2


Input

3
&amp; 1
&amp; 3
&amp; 5


Output

1
&amp; 1


Input

3
^ 1
^ 2
^ 3


Output

0

Note

You can read about bitwise operations in <https://en.wikipedia.org/wiki/Bitwise_operation>.

Second sample:

Let x be an input of the Petya's program. It's output is ((x&1)&3)&5 = x&(1&3&5) = x&1. So these two programs always give the same outputs.

Solution (in JAVA):

Solution:
import java.io.*;
import java.util.*;
import java.util.function.IntFunction;
import java.util.stream.Collectors;

public class Solution {


    static MyScanner sc;
    private static PrintWriter out;
    static long M2 = 1_000_000_000L + 7;

    public static void main(String[] s) throws Exception {
        StringBuilder stringBuilder = new StringBuilder();
//        stringBuilder.append("100 ");
//        for (int p = 0; p < 100; p++) {
//            stringBuilder.append(" 30 " + p * 5 + " 0 ");
//        }


        if (stringBuilder.length() == 0) {
            sc = new MyScanner(System.in);
        } else {
            sc = new MyScanner(new BufferedReader(new StringReader(stringBuilder.toString())));
        }

        out = new PrintWriter(new OutputStreamWriter(System.out));

        initData();
        solve();
        out.flush();
    }

    private static void initData() {


    }


    private static void solve() throws IOException {
        int n = sc.nextInt();

        int[][] ll = new int[n][2];

        for (int r = 0; r < n; r++) {
            String ppp = sc.next();
            ll[r][0] = "|".equalsIgnoreCase(ppp) ? 3 : ll[r][0];
            ll[r][0] = "&".equalsIgnoreCase(ppp) ? 1 : ll[r][0];
            ll[r][0] = "^".equalsIgnoreCase(ppp) ? 2 : ll[r][0];
            ll[r][1] = sc.nextInt();
        }

        int[] dest = new int[10];
        for (int k = 0; k < 10; k++) {
            for (int[] ttt : ll) {
                if (ttt[0] == 3 && isset(ttt[1], k)) {
                    dest[k] = 2;
                }
                if (ttt[0] == 1 && !isset(ttt[1], k)) {
                    dest[k] = 3;
                }
                if (ttt[0] == 2 && isset(ttt[1], k) && dest[k] == 2) {
                    dest[k] = 3;
                    continue;
                }
                if (ttt[0] == 2 && isset(ttt[1], k) && dest[k] == 3) {
                    dest[k] = 2;
                    continue;
                }
                if (ttt[0] == 2 && isset(ttt[1], k) && dest[k] == 1) {
                    dest[k] = 0;
                    continue;
                }
                if (ttt[0] == 2 && isset(ttt[1], k) && dest[k] == 0) {
                    dest[k] = 1;
                    continue;
                }
            }

        }
        int xs = 0;
        for (int l = 0; l < 10; l++) {
            if (dest[l] == 1) {
                xs += 1 << l;
            }
        }
        out.println(3);
        out.println("^ " + xs);
        xs = 0;
        for (int l = 0; l < 10; l++) {
            if (dest[l] == 2) {
                xs += 1 << l;
            }
        }
        out.println("| " + xs);
        xs = 1023;
        for (int l = 0; l < 10; l++) {
            if (dest[l] == 3) {
                xs -= 1 << l;
            }
        }
        out.println("& " + xs);

    }

    private static boolean isset(int i, int k) {
        return (i & (1 << k)) > 0;
    }

    private static long c(long from, long to) {
        long res = (fact(to) * inv(from)) % M2;
        return (res * inv(to - from)) % M2;
    }

    private static long inv(long from) {
        return pow(fact(from), M2 - 2, M2);
    }

    private static long fact(long from) {
        long r = 1;
        for (int i = 1; i <= from; i++) {
            r *= i;
            r %= M2;

        }
        return r;
    }

    private static void solveT() throws IOException {
        int t = sc.nextInt();
        while (t-- > 0) {
            solve();
        }
    }


    private static long gcd(long l, long l1) {
        if (l > l1) return gcd(l1, l);
        if (l == 0) return l1;
        return gcd(l1 % l, l);
    }

    private static long pow(long a, long b, long m) {
        if (b == 0) return 1;
        if (b == 1) return a;
        long pp = pow(a, b / 2, m);
        pp *= pp;
        pp %= m;
        return (pp * (b % 2 == 0 ? 1 : a)) % m;
    }


    static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        MyScanner(BufferedReader br) {
            this.br = br;
        }

        public MyScanner(InputStream in) {
            this(new BufferedReader(new InputStreamReader(in)));
        }

        void findToken() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

        String next() {
            findToken();
            return st.nextToken();
        }

        Integer[] nab(int n) {
            Integer[] k = new Integer[n];
            for (int i = 0; i < n; i++) {
                k[i] = sc.fi();
            }
            return k;
        }

        int[] na(int n) {
            int[] k = new int[n];
            for (int i = 0; i < n; i++) {
                k[i] = sc.fi();
            }
            return k;
        }

        long[] nl(int n) {
            long[] k = new long[n];
            for (int i = 0; i < n; i++) {
                k[i] = sc.nextLong();
            }
            return k;
        }

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

        int fi() {
            String t = next();
            int cur = 0;
            boolean n = t.charAt(0) == '-';
            for (int a = n ? 1 : 0; a < t.length(); a++) {
                cur = cur * 10 + t.charAt(a) - '0';
            }
            return n ? -cur : cur;
        }

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

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


    private static final class HLD {
        private final int count;
        private final IntFunction<MetricG> metricGSupplier;
        private final int[] buckets;
        private final int[] indexes;
        private final int[] split;
        private ArrayList<MetricG> data = new ArrayList<>();
        private int[] parent;
        ArrayList<ArrayList<Integer>> levels = new ArrayList<>();
        int ct = 0;

        public HLD(int n, IntFunction<MetricG> metricGSupplier) {
            this.count = n;
            this.metricGSupplier = metricGSupplier;
            this.parent = new int[n];
            this.buckets = new int[n];
            this.indexes = new int[n];
            this.split = new int[n];
            Arrays.fill(this.buckets, -1);
        }

        public void put(int item, int level, int parent) {
            this.parent[item] = parent;
            for (int i = levels.size(); i <= level; i++) {
                levels.add(new ArrayList<>());
            }
            levels.get(level).add(item);
            ct++;
            if (ct == count) {
                build();
            }
        }

        long v(int val) {
            return data.get(buckets[val]).calc(0, indexes[val]);
        }

        long v(int f, int t) {
            return data.get(buckets[f]).calc(indexes[f], indexes[t]);
        }

        long ct(int from, int to, LongLongFunc ft, long init) {
            while (buckets[from] != buckets[to]) {
                init = ft.p(init, v(from));
                from = split[from];
            }
            return ft.p(init, v(from, to));
        }


        private interface LongLongFunc {
            long p(long a1, long a2);
        }

        private void build() {
            int bck = 0;
            for (int k = levels.size() - 1; k >= 0; k--) {
                for (int i : levels.get(k)) {
                    if (buckets[i] != -1) continue;
                    int ll = i;
                    int ct = 0;
                    int val = bck++;
                    while (ll >= 0 && buckets[ll] == -1) {
                        buckets[ll] = val;
                        ct++;
                        ll = parent[ll];
                    }
                    split[i] = ll;
                    int r = i;
                    data.add(metricGSupplier.apply(ct));
                    while (r != ll) {
                        indexes[r] = --ct;
                        r = parent[r];
                    }

                }
            }
        }

        public void put(int item, long value) {
            data.get(buckets[item]).put(indexes[item], (int) value);
        }
    }

    private interface MetricG {
        long calc(int from, int to);

        void put(int x, int val);
    }


    private static final class STree {
        long[] val1;
        int[] from1;
        int[] to1;
        long[] max1;

        public STree(int c) {
            int size = Integer.highestOneBit(Math.max(c, 4));
            if (size != c) {
                size <<= 1;
            }
            int rs = size << 1;
            val1 = new long[rs];
            from1 = new int[rs];
            max1 = new long[rs];
            Arrays.fill(max1, Long.MIN_VALUE);
            Arrays.fill(val1, Long.MIN_VALUE);
            to1 = new int[rs];

            Arrays.fill(from1, Integer.MAX_VALUE);
            for (int r = rs - 1; r > 1; r--) {
                if (r >= size) {
                    from1[r] = r - size;
                    to1[r] = r - size;
                }
                from1[r / 2] = Math.min(from1[r / 2], from1[r]);
                to1[r / 2] = Math.max(to1[r / 2], to1[r]);
            }
        }

        public long max(int from, int to) {
            return max(1, from, to);
        }

        private long max(int cur, int from, int to) {
            if (cur >= val1.length) return Long.MIN_VALUE;
            if (from <= from1[cur] && to1[cur] <= to) {
                return max1[cur];
            }
            if (from1[cur] > to || from > to1[cur]) {
                return Long.MIN_VALUE;
            }
            cur <<= 1;
            return Math.max(max(cur, from, to), max(cur + 1, from, to));
        }


        public void put(int x, long val) {
            x += val1.length >> 1;
            val1[x] = val;
            max1[x] = val;
            addToParent(x);
        }


        private void addToParent(int cur) {
            while (cur > 1) {
                cur >>= 1;
                max1[cur] = Math.max(max1[cur << 1], max1[1 + (cur << 1)]);
            }
        }

    }
}