import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.stream.IntStream;

public class Main {

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

    private void solve() throws IOException {
        try {
            //			solveA();
//			solveB();
            //			solveB2();
            //			solveC();
            //			solveD();
            //			solveD2();
            solveE();
            //			 solveF();
        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.flush();
                out.close();
            }
        }

    }

    private void solveA() {
        int p = nextInt();
        int q = nextInt();
        int r = nextInt();

        out.println(Math.min(q + r, Math.min(p + q, p + r)));
    }

    private void solveB() {
        int n = nextInt();
        int[] wk = IntStream.range(0, n).map(i -> nextInt()).toArray();
        //		int[] wk = IntStream.range(0, n).map(i -> nextInt()).sorted().toArray();

        int[] rui = new int[n];
        //0-Nの累積和を行う
        rui[0] = wk[0];
        for (int i = 1; i < rui.length; i++) {
            rui[i] = rui[i - 1] + wk[i];
        }
        long res = Integer.MAX_VALUE / 10;
        /*
         * 実際にT候補の数値を探すためにiを1からn-1まで移動させる
         * 2グループに分けるためには、一番最初または最後まで行ってはいけない
         * (rui[n - 1] - rui[i]) -> i+1からNまでの和
         * rui[i] -> 0からiまでの和
         */
        for (int i = 1; i < n - 1; i++) {
            res = Math.min(res, Math.abs((rui[n - 1] - rui[i]) - rui[i]));
        }

        out.println(res);
    }

    private void solveB2() {
        int n = nextInt();
        int[] wk = IntStream.range(0, n).map(i -> nextInt()).toArray();

        long res = Integer.MAX_VALUE / 10;
        for (int i = 1; i < n - 1; i++) {
            int sum1 = 0;
            int sum2 = 0;
            for (int j = 0; j < n; j++) {
                if (j <= i) {
                    sum1 += wk[j];
                } else {
                    sum2 += wk[j];
                }
            }
            res = Math.min(res, Math.abs(sum1 - sum2));
        }

        out.println(res);
    }

    private void solveC() {
        int n = nextInt();
        int m = nextInt();
        Set<Integer> key = new HashSet<Integer>();
        for (int i = 0; i < m; i++) {
            key.add(nextInt());
        }

        long[] dp = new long[n + 1];
        dp[0] = 1;
        long CONST_MOD = (long) (Math.pow(10, 9) + 7);
        for (int i = 0; i <= n; i++) {
            if (key.contains(i)) {
                continue;
            }
            if (i + 2 <= n) {
                dp[i + 2] = dp[i + 2] % CONST_MOD + dp[i] % CONST_MOD;
            }
            if (i + 1 <= n) {
                dp[i + 1] = dp[i + 1] % CONST_MOD + dp[i] % CONST_MOD;
            }
        }

        out.println(dp[n] % CONST_MOD);
    }

    private void solveD2() {
        int h = nextInt();
        int w = nextInt();
        char[][] wk = new char[h][w];
        for (int i = 0; i < wk.length; i++) {
            wk[i] = next().toCharArray();
        }
        int[][] rui1 = new int[h][w];
        /*
         * Wについて累積和を作成
         */
        for (int i = 0; i < h; i++) {
            int cnt = 0;
            /*
             * 入力例1だと、以下みたいな感じ(横並び)
             * 012012
             * 123450
             * 123401
             * 010123
             */
            for (int j = 0; j < w; j++) {
                if (wk[i][j] == '.') {
                    cnt++;
                } else {
                    cnt = 0;
                }
                rui1[i][j] = cnt;
            }
            /*
             * 累積した結果をならす(横並び)
             * 012012
             * 123450
             * 123401
             * 010123
             * を
             * 022022
             * 555550
             * 444401
             * 010133
             * に変換
             */
            for (int j = w - 1; j > 0; j--) {
                if (rui1[i][j - 1] != 0 && rui1[i][j] != 0) {
                    rui1[i][j - 1] = rui1[i][j];
                }
            }
        }

        int[][] rui2 = new int[h][w];
        /*
         * Hについて累積和を作成
         */
        for (int j = 0; j < w; j++) {
            int cnt = 0;
            /*
             * 入力例1だと、以下みたいな感じ(縦並び)
             * 011011
             * 122120
             * 233201
             * 040312
             */
            for (int i = 0; i < h; i++) {
                if (wk[i][j] == '.') {
                    cnt++;
                } else {
                    cnt = 0;
                }
                rui2[i][j] = cnt;
            }
            /*
             * 累積した結果をならす(縦並び)
             * 011011
             * 122120
             * 233201
             * 040312
             * を
             * 043021
             * 243320
             * 243302
             * 040312
             * に変換
             */
            for (int i = h - 1; i > 0; i--) {
                if (rui2[i - 1][j] != 0 && rui2[i][j] != 0) {
                    rui2[i - 1][j] = rui2[i][j];
                }
            }
        }

        /*
         * 累積してあるので全てなめる
         * ただし、上下左右が重なっている中央部分を-1する
         */
        long res = 0;
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                long cnt = rui1[i][j] + rui2[i][j] - 1;
                res = Math.max(res, cnt);
            }
        }

        out.println(res);
    }

    private void solveD() {
        int h = nextInt();
        int w = nextInt();
        char[][] wk = new char[h][w];
        for (int i = 0; i < wk.length; i++) {
            wk[i] = next().toCharArray();
        }
        int[][] rui1 = new int[h][w];
        for (int i = 0; i < h; i++) {
            int cnt = 0;
            for (int j = 0; j < w; j++) {
                if (wk[i][j] == '.') {
                    cnt++;
                } else {
                    cnt = 0;
                }
                rui1[i][j] = cnt;
            }
        }
        for (int i = h - 1; i >= 0; i--) {
            for (int j = w - 1; j > 0; j--) {
                if (rui1[i][j - 1] != 0 && rui1[i][j] != 0) {
                    rui1[i][j - 1] = rui1[i][j];
                }
            }
        }
        int[][] rui2 = new int[h][w];
        for (int j = 0; j < w; j++) {
            int cnt = 0;
            for (int i = 0; i < h; i++) {
                if (wk[i][j] == '.') {
                    cnt++;
                } else {
                    cnt = 0;
                }
                rui2[i][j] = cnt;
            }
        }
        for (int j = w - 1; j >= 0; j--) {
            for (int i = h - 1; i > 0; i--) {
                if (rui2[i - 1][j] != 0 && rui2[i][j] != 0) {
                    rui2[i - 1][j] = rui2[i][j];
                }
            }
        }
        long res = 0;
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                long cnt = rui1[i][j] + rui2[i][j] - 1;
                res = Math.max(res, cnt);
            }
        }

        out.println(res);
    }

    /**
     * a + b = (a xor b) + (a & b) * 2
     * (a + b) == (a ^ b) + ((a & b) << 1)
     * a+b <= L
     * a xor b = a + b
     * →(a&b)*2が0だと言っている
     */
    private void solveE() {
//        int a = 11;
//        int b = 6;
//        out.println((a + b) == (a ^ b) + ((a & b) << 1));
//        out.println((a + b) == (a ^ b));
//        out.println((a + b) + "/" + (a ^ b) + "/" + (a & b) + "/" + (a & b) * 2 + "/" + ((a & b) << 1));
        String l = next();
        final long MOD = (long) (Math.pow(10, 9) + 7);
        long[][] dp = new long[l.length() + 10][2];
        /*
        dp[i][j]=>i桁目までを見た、
        j=0:i桁が一致
        j=1:未満であることがすでに確定
        https://betrue12.hateblo.jp/entry/2019/06/10/213932
        https://qiita.com/vain0x/items/e74a23d5c62711f95ea0#e---sum-equals-xor
         */
        dp[0][0] = 1;
        for (int i = 0; i < l.length(); i++) {
            //a+b==0
            if (l.charAt(i) == '0') {
                /*
                i桁目が
                 */
                dp[i + 1][0] = dp[i][0] % MOD;
                dp[i + 1][1] = dp[i][1] % MOD;
            } else {
                /*
                i桁目が1ということは、[0]つまり1を採用することができない
                1+1=1^1となれないため
                なので、次のけたの未満フラグは[1]を採用
                 */
                dp[i + 1][1] = (dp[i][0] + dp[i][1]) % MOD;
            }
            //a+b==1
            /*

             */
            if (l.charAt(i) == '0') {
                dp[i + 1][1] = (dp[i + 1][1] + (dp[i][1] * 2L % MOD)) % MOD;
            } else {
                dp[i + 1][0] = (dp[i + 1][0] + (dp[i][0] * 2L % MOD)) % MOD;
                dp[i + 1][1] = (dp[i + 1][1] + (dp[i][1] * 2L % MOD)) % MOD;
            }
        }

        out.println((dp[l.length()][0] + dp[l.length()][1]) % MOD);
    }


    private void solveF() {
        int n = nextInt();

        out.println("");
    }

    private final PrintWriter out = new PrintWriter(System.out);
    private final InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;

    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        } else {
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }

    private int readByte() {
        if (hasNextByte())
            return buffer[ptr++];
        else
            return -1;
    }

    private static boolean isPrintableChar(int c) {
        return 33 <= c && c <= 126;
    }

    private void skipUnprintable() {
        while (hasNextByte() && !isPrintableChar(buffer[ptr]))
            ptr++;
    }

    public boolean hasNext() {
        skipUnprintable();
        return hasNextByte();
    }

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

    public String next() {
        if (!hasNext())
            throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while (isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    public long nextLong() {
        if (!hasNext())
            throw new NoSuchElementException();
        long n = 0;
        boolean minus = false;
        int b = readByte();
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        if (b < '0' || '9' < b) {
            throw new NumberFormatException();
        }
        while (true) {
            if ('0' <= b && b <= '9') {
                n *= 10;
                n += b - '0';
            } else if (b == -1 || !isPrintableChar(b)) {
                return minus ? -n : n;
            } else {
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
}

Measured memory_bytes: 27476