#!/usr/bin/env python3
import sys

MOD = 1000000007  # type: int


def solve(L: str):
    dp = [(0,0)] * (len(L)+1)
    dp[0] = (1,0)
    for i in range(1,len(L)+1):
        isOne = L[i-1] == "1"
        if isOne:
            mContinue = dp[i-1][0]*2%MOD
            mDiscontinue = (dp[i-1][0] + dp[i-1][1]*3)%MOD
            dp[i] = (mContinue,mDiscontinue)
        else:
            mContinue = dp[i-1][0]%MOD
            mDiscontinue = (dp[i-1][1]*3)%MOD
            dp[i] = (mContinue,mDiscontinue)
    print((dp[len(L)][0]+dp[len(L)][1])%MOD)

    return


# Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    L = next(tokens)  # type: int
    solve(L)

if __name__ == '__main__':
    main() import sys sys MOD = 1000000007 MOD 1000000007 def solve(L: str):
    dp = [(0,0)] * (len(L)+1)
    dp[0] = (1,0)
    for i in range(1,len(L)+1):
        isOne = L[i-1] == "1"
        if isOne:
            mContinue = dp[i-1][0]*2%MOD
            mDiscontinue = (dp[i-1][0] + dp[i-1][1]*3)%MOD
            dp[i] = (mContinue,mDiscontinue)
        else:
            mContinue = dp[i-1][0]%MOD
            mDiscontinue = (dp[i-1][1]*3)%MOD
            dp[i] = (mContinue,mDiscontinue)
    print((dp[len(L)][0]+dp[len(L)][1])%MOD)

    return


# Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template) solve dp = [(0,0)] * (len(L)+1) dp [(0,0)] * (len(L)+1) [(0,0)] (0,0) 0 0 len(L)+1 len(L) len L 1 dp[0] = (1,0) dp[0] dp 0 (1,0) 1 0 for i in range(1,len(L)+1):
        isOne = L[i-1] == "1"
        if isOne:
            mContinue = dp[i-1][0]*2%MOD
            mDiscontinue = (dp[i-1][0] + dp[i-1][1]*3)%MOD
            dp[i] = (mContinue,mDiscontinue)
        else:
            mContinue = dp[i-1][0]%MOD
            mDiscontinue = (dp[i-1][1]*3)%MOD
            dp[i] = (mContinue,mDiscontinue)
     i range(1,len(L)+1) range 1 len(L)+1 len(L) len L 1 isOne = L[i-1] == "1" isOne L[i-1] == "1" L[i-1] L i-1 i 1 "1" if isOne:
            mContinue = dp[i-1][0]*2%MOD
            mDiscontinue = (dp[i-1][0] + dp[i-1][1]*3)%MOD
            dp[i] = (mContinue,mDiscontinue)
        else:
            mContinue = dp[i-1][0]%MOD
            mDiscontinue = (dp[i-1][1]*3)%MOD
            dp[i] = (mContinue,mDiscontinue)
     isOne mContinue = dp[i-1][0]*2%MOD mContinue dp[i-1][0]*2%MOD dp[i-1][0]*2 dp[i-1][0] [i-1] dp i-1 i 1 0 2 MOD mDiscontinue = (dp[i-1][0] + dp[i-1][1]*3)%MOD mDiscontinue (dp[i-1][0] + dp[i-1][1]*3)%MOD dp[i-1][0] + dp[i-1][1]*3 dp[i-1][0] [i-1] dp i-1 i 1 0 dp[i-1][1]*3 dp[i-1][1] [i-1] dp i-1 i 1 1 3 MOD dp[i] = (mContinue,mDiscontinue) dp[i] dp i (mContinue,mDiscontinue) mContinue mDiscontinue mContinue = dp[i-1][0]%MOD mContinue dp[i-1][0]%MOD dp[i-1][0] [i-1] dp i-1 i 1 0 MOD mDiscontinue = (dp[i-1][1]*3)%MOD mDiscontinue (dp[i-1][1]*3)%MOD dp[i-1][1]*3 dp[i-1][1] [i-1] dp i-1 i 1 1 3 MOD dp[i] = (mContinue,mDiscontinue) dp[i] dp i (mContinue,mDiscontinue) mContinue mDiscontinue print((dp[len(L)][0]+dp[len(L)][1])%MOD) print (dp[len(L)][0]+dp[len(L)][1])%MOD dp[len(L)][0]+dp[len(L)][1] dp[len(L)][0] [len(L)] dp len(L) len L 0 dp[len(L)][1] [len(L)] dp len(L) len L 1 MOD return L: str L def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    L = next(tokens)  # type: int
    solve(L) main def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
     iterate_tokens for line in sys.stdin:
            for word in line.split():
                yield word
     line sys.stdin sys stdin for word in line.split():
                yield word
     word line.split() line.split line split yield word word tokens = iterate_tokens() tokens iterate_tokens() iterate_tokens L = next(tokens) L next(tokens) next tokens solve(L) solve L if __name__ == '__main__':
    main() __name__ == '__main__' __name__ '__main__' main() main def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    L = next(tokens)  # type: int
    solve(L) def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    L = next(tokens)  # type: int
    solve(L) main def solve(L: str):
    dp = [(0,0)] * (len(L)+1)
    dp[0] = (1,0)
    for i in range(1,len(L)+1):
        isOne = L[i-1] == "1"
        if isOne:
            mContinue = dp[i-1][0]*2%MOD
            mDiscontinue = (dp[i-1][0] + dp[i-1][1]*3)%MOD
            dp[i] = (mContinue,mDiscontinue)
        else:
            mContinue = dp[i-1][0]%MOD
            mDiscontinue = (dp[i-1][1]*3)%MOD
            dp[i] = (mContinue,mDiscontinue)
    print((dp[len(L)][0]+dp[len(L)][1])%MOD)

    return


# Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template) def solve(L: str):
    dp = [(0,0)] * (len(L)+1)
    dp[0] = (1,0)
    for i in range(1,len(L)+1):
        isOne = L[i-1] == "1"
        if isOne:
            mContinue = dp[i-1][0]*2%MOD
            mDiscontinue = (dp[i-1][0] + dp[i-1][1]*3)%MOD
            dp[i] = (mContinue,mDiscontinue)
        else:
            mContinue = dp[i-1][0]%MOD
            mDiscontinue = (dp[i-1][1]*3)%MOD
            dp[i] = (mContinue,mDiscontinue)
    print((dp[len(L)][0]+dp[len(L)][1])%MOD)

    return


# Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template) solve MOD = 1000000007 1000000007 MOD
#!/usr/bin/env python3
import sys

MOD = 1000000007  # type: int


def solve(L: str):
    dp = [(0,0)] * (len(L)+1)
    dp[0] = (1,0)
    for i in range(1,len(L)+1):
        isOne = L[i-1] == "1"
        if isOne:
            mContinue = dp[i-1][0]*2%MOD
            mDiscontinue = (dp[i-1][0] + dp[i-1][1]*3)%MOD
            dp[i] = (mContinue,mDiscontinue)
        else:
            mContinue = dp[i-1][0]%MOD
            mDiscontinue = (dp[i-1][1]*3)%MOD
            dp[i] = (mContinue,mDiscontinue)
    print((dp[len(L)][0]+dp[len(L)][1])%MOD)

    return


# Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    L = next(tokens)  # type: int
    solve(L)

if __name__ == '__main__':
    main()
