There are famous Russian nesting dolls named matryoshkas sold in one of the souvenir stores nearby, and you'd like to buy several of them. The store has n different matryoshkas. Any matryoshka is a figure of volume out_i with an empty space inside of volume in_i (of course, out_i > in_i).

You don't have much free space inside your bag, but, fortunately, you know that matryoshkas can be nested one inside another. Formally, let's call a set of matryoshkas nested if we can rearrange dolls in such a way, that the first doll can be nested inside the second one, the second doll — inside the third one and so on. Matryoshka i can be nested inside matryoshka j if out_i ≤ in_j. So only the last doll will take space inside your bag.

Let's call extra space of a nested set of dolls as a total volume of empty space inside this structure. Obviously, it's equal to in_{i_1} + (in_{i_2} - out_{i_1}) + (in_{i_3} - out_{i_2}) + ... + (in_{i_k} - out_{i_{k-1}}), where i_1, i_2, ..., i_k are the indices of the chosen dolls in the order they are nested in each other.

Finally, let's call a nested subset of the given sequence as big enough if there isn't any doll from the sequence that can be added to the nested subset without breaking its nested property.

You want to buy many matryoshkas, so you should choose a big enough nested subset to buy it. But you will be disappointed if too much space in your bag will be wasted, so you want to choose a big enough subset so that its extra space is minimum possible among all big enough subsets. Now you wonder, how many different nested subsets meet these conditions (they are big enough, and there is no big enough subset such that its extra space is less than the extra space of the chosen subset). Two subsets are considered different if there exists at least one index i such that one of the subsets contains the i-th doll, and another subset doesn't.

Since the answer can be large, print it modulo 10^9 + 7.

Input

The first line contains a single integer n (1 ≤ n ≤ 2 ⋅ 10^5) — the number of matryoshkas.

The next n lines contain a description of each doll: two integers out_i and in_i (1 ≤ in_i < out_i ≤ 10^9) — the outer and inners volumes of the i-th matryoshka.

Output

Print one integer — the number of big enough nested subsets such that extra space of each of these subsets is minimum possible. Since the answer can be large, print it modulo 10^9 + 7.

Example

Input


7
4 1
4 2
4 2
2 1
5 4
6 4
3 2


Output


6

Note

There are 6 big enough nested subsets with minimum possible extra space in the example: 

  * \{1, 5\}: we can't add any other matryoshka and keep it nested; it's extra space is 1; 
  * \{1, 6\}; 
  * \{2, 4, 5\}; 
  * \{2, 4, 6\}; 
  * \{3, 4, 5\}; 
  * \{3, 4, 6\}. 



There are no more "good" subsets because, for example, subset \{6, 7\} is not big enough (we can add the 4-th matryoshka to it) or subset \{4, 6, 7\} has extra space equal to 2.


import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

public class CF1197E {
    public static void main(String[] args) throws Exception {
        boolean local = System.getProperty("ONLINE_JUDGE") == null;
        boolean async = false;

        Charset charset = Charset.forName("ascii");

        FastIO io = local ? new FastIO(new FileInputStream("D:\\DATABASE\\TESTCASE\\Code.in"), System.out, charset) : new FastIO(System.in, System.out, charset);
        Task task = new Task(io, new Debug(local));

        if (async) {
            Thread t = new Thread(null, task, "dalt", 1 << 27);
            t.setPriority(Thread.MAX_PRIORITY);
            t.start();
            t.join();
        } else {
            task.run();
        }

        if (local) {
            io.cache.append("\n\n--memory -- \n" + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20) + "M");
        }

        io.flush();
    }

    public static class Task implements Runnable {
        final FastIO io;
        final Debug debug;
        int inf = (int) 1e9;

        public Task(FastIO io, Debug debug) {
            this.io = io;
            this.debug = debug;
        }

        @Override
        public void run() {
            solve();
        }

        public void solve() {
            int n = io.readInt();
            Box[] boxes = new Box[n + 1];
            int[] allValues = new int[n + n + 2];
            for (int i = 1; i <= n; i++) {
                boxes[i] = new Box();
                allValues[i] = boxes[i].out = io.readInt();
                allValues[i + n] = boxes[i].in = io.readInt();
            }
            DiscreteMap dm = new DiscreteMap(allValues, 0, allValues.length);
            int maxIn = 0;
            for (int i = 1; i <= n; i++) {
                boxes[i].in = dm.rankOf(boxes[i].in);
                boxes[i].out = dm.rankOf(boxes[i].out);
                maxIn = Math.max(boxes[i].in, maxIn);
            }

            int m = dm.maxRank();
            int[] dp = new int[m + 1];
            int[] way = new int[m + 1];
            dp[0] = 0;
            way[0] = 1;
            Segment root = new Segment(dm.minRank(), dm.maxRank());
            root.update(0, 0, dm.minRank(), dm.maxRank(), 0, 1);

            Map<Integer, List<Box>> groupByOut = Arrays.asList(boxes)
                    .subList(1, boxes.length)
                    .stream()
                    .collect(Collectors.groupingBy((x) -> x.out));

            int[] q = new int[2];
            for (int i = 1; i <= dm.maxRank(); i++) {
                dp[i] = inf;
                way[i] = 0;

                for (Box box : groupByOut.getOrDefault(i, Collections.emptyList())) {
                    q[0] = inf;
                    q[1] = 0;
                    root.query(0, box.in, dm.minRank(), dm.maxRank(), q);
                    q[0] += dm.iThElement(box.in);
                    if (dp[i] > q[0]) {
                        dp[i] = q[0];
                        way[i] = 0;
                    }
                    if (dp[i] == q[0]) {
                        way[i] = mod.plus(way[i], q[1]);
                    }
                }
                root.update(i, i, dm.minRank(), dm.maxRank(), dp[i] - dm.iThElement(i), way[i]);
            }

            int minWaste = inf;
            int minWasteWay = 0;
            for (int i = maxIn + 1; i <= dm.maxRank(); i++) {
                if (minWaste > dp[i]) {
                    minWaste = dp[i];
                    minWasteWay = 0;
                }
                if (minWaste == dp[i]) {
                    minWasteWay = mod.plus(minWasteWay, way[i]);
                }
            }

            io.cache.append(minWasteWay);
        }

    }


    static Modular mod = new Modular((int) 1e9 + 7);

    public static class Segment implements Cloneable {
        private Segment left;
        private Segment right;
        int min;
        int way;

        public void pushUp() {
            min = Math.min(left.min, right.min);
            way = 0;
            if (left.min == min) {
                way = mod.plus(way, left.way);
            }
            if (right.min == min) {
                way = mod.plus(way, right.way);
            }
        }

        public void pushDown() {
        }

        public Segment(int l, int r) {
            if (l < r) {
                int m = (l + r) >> 1;
                left = new Segment(l, m);
                right = new Segment(m + 1, r);
                pushUp();
            } else {

            }
        }

        private boolean covered(int ll, int rr, int l, int r) {
            return ll <= l && rr >= r;
        }

        private boolean noIntersection(int ll, int rr, int l, int r) {
            return ll > r || rr < l;
        }

        public void update(int ll, int rr, int l, int r, int v, int w) {
            if (noIntersection(ll, rr, l, r)) {
                return;
            }
            if (covered(ll, rr, l, r)) {
                if (min > v) {
                    min = v;
                    way = 0;
                }
                if (min == v) {
                    way = mod.plus(way, w);
                }
                return;
            }
            pushDown();
            int m = (l + r) >> 1;
            left.update(ll, rr, l, m, v, w);
            right.update(ll, rr, m + 1, r, v, w);
            pushUp();
        }

        public void query(int ll, int rr, int l, int r, int[] ans) {
            if (noIntersection(ll, rr, l, r)) {
                return;
            }
            if (covered(ll, rr, l, r)) {
                if (ans[0] > min) {
                    ans[0] = min;
                    ans[1] = 0;
                }
                if (ans[0] == min) {
                    ans[1] = mod.plus(ans[1], way);
                }
                return;
            }
            pushDown();
            int m = (l + r) >> 1;
            left.query(ll, rr, l, m, ans);
            right.query(ll, rr, m + 1, r, ans);
        }
    }

    /**
     * Created by dalt on 2018/6/1.
     */
    public static class Randomized {
        static Random random = new Random();

        public static double nextDouble(double min, double max) {
            return random.nextDouble() * (max - min) + min;
        }

        public static void randomizedArray(int[] data, int from, int to) {
            to--;
            for (int i = from; i <= to; i++) {
                int s = nextInt(i, to);
                int tmp = data[i];
                data[i] = data[s];
                data[s] = tmp;
            }
        }

        public static void randomizedArray(long[] data, int from, int to) {
            to--;
            for (int i = from; i <= to; i++) {
                int s = nextInt(i, to);
                long tmp = data[i];
                data[i] = data[s];
                data[s] = tmp;
            }
        }

        public static void randomizedArray(double[] data, int from, int to) {
            to--;
            for (int i = from; i <= to; i++) {
                int s = nextInt(i, to);
                double tmp = data[i];
                data[i] = data[s];
                data[s] = tmp;
            }
        }

        public static void randomizedArray(float[] data, int from, int to) {
            to--;
            for (int i = from; i <= to; i++) {
                int s = nextInt(i, to);
                float tmp = data[i];
                data[i] = data[s];
                data[s] = tmp;
            }
        }

        public static <T> void randomizedArray(T[] data, int from, int to) {
            to--;
            for (int i = from; i <= to; i++) {
                int s = nextInt(i, to);
                T tmp = data[i];
                data[i] = data[s];
                data[s] = tmp;
            }
        }

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

    public static class DiscreteMap {
        int[] val;
        int f;
        int t;

        public DiscreteMap(int[] val, int f, int t) {
            Randomized.randomizedArray(val, f, t);
            Arrays.sort(val, f, t);
            int wpos = f + 1;
            for (int i = f + 1; i < t; i++) {
                if (val[i] == val[i - 1]) {
                    continue;
                }
                val[wpos++] = val[i];
            }
            this.val = val;
            this.f = f;
            this.t = wpos;
        }

        /**
         * Return 0, 1, so on
         */
        public int rankOf(int x) {
            return Arrays.binarySearch(val, f, t, x) - f;
        }

        public int floorRankOf(int x) {
            int index = Arrays.binarySearch(val, f, t, x);
            if (index >= 0) {
                return index - f;
            }
            index = -(index + 1);
            return index - 1 - f;
        }

        public int ceilRankOf(int x) {
            int index = Arrays.binarySearch(val, f, t, x);
            if (index >= 0) {
                return index - f;
            }
            index = -(index + 1);
            return index - f;
        }

        /**
         * Get the i-th smallest element
         */
        public int iThElement(int i) {
            return val[f + i];
        }

        public int minRank() {
            return 0;
        }

        public int maxRank() {
            return t - f - 1;
        }

        @Override
        public String toString() {
            return Arrays.toString(Arrays.copyOfRange(val, f, t));
        }
    }

    public static class Box {
        int in;
        int out;
    }

    /**
     * Mod operations
     */
    public static class Modular {
        int m;

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

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

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

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

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

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

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

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

    public static class FastIO {
        public final StringBuilder cache = new StringBuilder(1 << 13);
        private final InputStream is;
        private final OutputStream os;
        private final Charset charset;
        private StringBuilder defaultStringBuf = new StringBuilder(1 << 13);
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastIO(InputStream is, OutputStream os, Charset charset) {
            this.is = is;
            this.os = os;
            this.charset = charset;
        }

        public FastIO(InputStream is, OutputStream os) {
            this(is, os, Charset.forName("ascii"));
        }

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

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

        public int readInt() {
            int sign = 1;

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

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

            return val;
        }

        public long readLong() {
            int sign = 1;

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

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

            return val;
        }

        public double readDouble() {
            boolean sign = true;
            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+';
                next = read();
            }

            long val = 0;
            while (next >= '0' && next <= '9') {
                val = val * 10 + next - '0';
                next = read();
            }
            if (next != '.') {
                return sign ? val : -val;
            }
            next = read();
            long radix = 1;
            long point = 0;
            while (next >= '0' && next <= '9') {
                point = point * 10 + next - '0';
                radix = radix * 10;
                next = read();
            }
            double result = val + (double) point / radix;
            return sign ? result : -result;
        }

        public String readString(StringBuilder builder) {
            skipBlank();

            while (next > 32) {
                builder.append((char) next);
                next = read();
            }

            return builder.toString();
        }

        public String readString() {
            defaultStringBuf.setLength(0);
            return readString(defaultStringBuf);
        }

        public int readLine(char[] data, int offset) {
            int originalOffset = offset;
            while (next != -1 && next != '\n') {
                data[offset++] = (char) next;
                next = read();
            }
            return offset - originalOffset;
        }

        public int readString(char[] data, int offset) {
            skipBlank();

            int originalOffset = offset;
            while (next > 32) {
                data[offset++] = (char) next;
                next = read();
            }

            return offset - originalOffset;
        }

        public int readString(byte[] data, int offset) {
            skipBlank();

            int originalOffset = offset;
            while (next > 32) {
                data[offset++] = (byte) next;
                next = read();
            }

            return offset - originalOffset;
        }

        public char readChar() {
            skipBlank();
            char c = (char) next;
            next = read();
            return c;
        }

        public void flush() throws IOException {
            os.write(cache.toString().getBytes(charset));
            os.flush();
            cache.setLength(0);
        }

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

    public static class Debug {
        private boolean allowDebug;

        public Debug(boolean allowDebug) {
            this.allowDebug = allowDebug;
        }

        public void assertTrue(boolean flag) {
            if (!allowDebug) {
                return;
            }
            if (!flag) {
                fail();
            }
        }

        public void fail() {
            throw new RuntimeException();
        }

        public void assertFalse(boolean flag) {
            if (!allowDebug) {
                return;
            }
            if (flag) {
                fail();
            }
        }

        private void outputName(String name) {
            System.out.print(name + " = ");
        }

        public void debug(String name, int x) {
            if (!allowDebug) {
                return;
            }

            outputName(name);
            System.out.println("" + x);
        }

        public void debug(String name, long x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println("" + x);
        }

        public void debug(String name, double x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println("" + x);
        }

        public void debug(String name, int[] x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println(Arrays.toString(x));
        }

        public void debug(String name, long[] x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println(Arrays.toString(x));
        }

        public void debug(String name, double[] x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println(Arrays.toString(x));
        }

        public void debug(String name, Object x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println("" + x);
        }

        public void debug(String name, Object... x) {
            if (!allowDebug) {
                return;
            }
            outputName(name);
            System.out.println(Arrays.deepToString(x));
        }
    }
}
