#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <limits>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <functional>

using namespace std;

using ll = long long;
using ui = unsigned int;
const ll MOD = 1000000007;
const ll INF = 9223372036854775807;

//129 Sum Equals Xor
int main() {
	char s[101010];
	scanf("%s", s);
	ll len = strlen(s);

	vector<ll> dp(2, 0);
	dp[0] = 1ll;
	dp[1] = 2ll;

	for (ll i = 1; i < len; i++) {
		if (s[i] == '1') {
			dp[0] *= 3ll;
			dp[0] %= MOD;
			dp[0] += dp[1];
			dp[0] %= MOD;
			dp[1] *= 2ll;
			dp[1] %= MOD;
		}
		else {
			dp[0] *= 3ll;
			dp[0] %= MOD;
		}
	}

	ll result = (dp[0] + dp[1]) % MOD;

	printf("%lld\n", result);
}


//131 Friendships
/*
vector<vector<ll>> comb(ll n, ll r) {
	vector<vector<ll>> v(n + 1, vector<ll>(n + 1, 0));
	for (ll i = 0; i < v.size(); i++) {
		v[i][0] = 1;
		v[i][i] = 1;
	}
	for (ll j = 1; j < v.size(); j++) {
		for (ll k = 1; k < j; k++) {
			v[j][k] = (v[j - 1][k - 1] + v[j - 1][k]);
		}
	}
	return v;
}

struct LLPair {
	ll a = 0;
	ll b = 0;
	LLPair() {}
	LLPair(ll a, ll b) {
		this->a = a;
		this->b = b;
	}
};

// nCk�̑g�ݍ��킹�ɑ΂��ď��������s����
void recursive_comb(int *indexes, int s, int rest, std::function<void(int *)> f) {
	if (rest == 0) {
		f(indexes);
	}
	else {
		if (s < 0) return;
		recursive_comb(indexes, s - 1, rest, f);
		indexes[rest - 1] = s;
		recursive_comb(indexes, s - 1, rest - 1, f);
	}
}
void foreach_comb(int n, int k, std::function<void(int *)> f) {
	int *indexes = new int[k];
	recursive_comb(indexes, n - 1, k, f);
	delete[] indexes;
}

ll disCount = 0;
vector<LLPair> result;

int main() {
	ll N;
	scanf("%lld", &N);
	ll K;
	scanf("%lld", &K);

	auto c = comb(N - 1, 2);
	ll max = c[N - 1][2];

	if (max < K) {
		printf("-1\n");
		return 0;
	}

	disCount = max - K;

	for (ll i = 1; i <= N - 1; i++) {
		result.push_back(LLPair(i, N));
	}

	//���s��
	foreach_comb(N - 1, 2, [](int *indexes) {
		//std::cout << indexes[0] << ',' << indexes[1] << ',' << std::endl;
		if (disCount > 0) {
			result.push_back(LLPair(indexes[0] + 1, indexes[1] + 1));
			disCount--;
		}
	});

	printf("%lld\n", (ll)result.size());
	for (auto val : result) {
		printf("%lld %lld\n", val.a, val.b);
	}
}
*/

//133 Virus Tree 2
/*
int main() {
	ll N;
	scanf("%lld", &N);
	ll K;
	scanf("%lld", &K);
	vector<vector<ll>> tree(N, vector<ll>(0));
	for (ll i = 0; i < N - 1; i++) {
		ll a;
		scanf("%lld", &a);
		ll b;
		scanf("%lld", &b);
		tree[a - 1].push_back(b - 1);
		tree[b - 1].push_back(a - 1);
	}

	vector<ll> depth(N, -1);
	queue<ll> q;
	q.push(0);
	depth[0] = 0;
	ll result = K;

	while (q.empty() == false) {
		ll node = q.front();
		q.pop();
		ll d = depth[node];
		ll colorLast = d == 0 ? K - 1 : K - 2;

		for (auto next : tree[node]) {
			if (depth[next] >= 0) {
				//parent
				continue;
			}

			if (colorLast == 0) {
				printf("0\n");
				return 0;
			}

			depth[next] = d + 1;
			q.push(next);

			result *= colorLast;
			result %= MOD;
			colorLast--;
		}
	}

	printf("%lld\n", result);
}
/**/

//141 Who Says a Pun?
/*
vector<int> Zalgorithm(const char *s) {
	int len = strlen(s);
	vector<int> prefix(len);
	for (int i = 1, j = 0; i < len; i++) {
		if (i + prefix[i - j] < j + prefix[j]) {
			prefix[i] = prefix[i - j];
		}
		else {
			int k = max(0, j + prefix[j] - i);
			while (i + k < len && s[k] == s[i + k]) ++k;
			prefix[i] = k;
			j = i;
		}
	}
	prefix[0] = len;
	return prefix;
}

int main() {
	int N;
	scanf("%d", &N);
	char s[101010];
	scanf("%s", s);

	int result = 0;

	for (int i = 0; i < N - 1; i++) {
		auto prefix = Zalgorithm(s + i);

		int len = N - i;
		for (int j = 1; j < prefix.size(); j++) {
			result = max(result, min(prefix[j], j));
		}
	}

	printf("%d\n", result);
}
*/

//139 League
/*
struct LLPair {
	int a = 0;
	int b = 0;
	LLPair() {}
	LLPair(int a, int b) {
		this->a = a;
		this->b = b;
	}
};

int main() {
	int N;
	scanf("%d", &N);
	vector<vector<int>> A(N, vector<int>(N - 1, 0));
	for (int j = 0; j < N; j++) {
		for (int i = 0; i < N - 1; i++) {
			scanf("%d", &A[j][i]);
			A[j][i]--;
		}
	}

	vector<vector<vector<LLPair>>> graph(N, vector<vector<LLPair>>(N, vector<LLPair>(0)));
	vector<vector<vector<LLPair>>> graphR(N, vector<vector<LLPair>>(N, vector<LLPair>(0)));
	vector<vector<int>> inEdge(N, vector<int>(N, 0));
	for (int j = 0; j < N; j++) {
		for (int i = 0; i < N - 2; i++) {
			int a = j;
			int b = A[j][i];
			if (a > b) {
				swap(a, b);
			}

			int c = j;
			int d = A[j][i + 1];
			if (c > d) {
				swap(c, d);
			}

			graph[a][b].push_back(LLPair(c, d)); //a vs b �̌�� c vs d ���s��			
			graphR[c][d].push_back(LLPair(a, b)); //c vs d ���s���O�� a vs b
			inEdge[c][d]++; //c vs d �ւ̗����G�b�W��
		}
	}

	//���[�v�̌��o���g�|���W�J���\�[�g�Ŏ��{

	queue<LLPair> S; //���������N����0�ł���m�[�h�̃Z�b�g
	vector<LLPair> L; //�g�|���W�J���\�[�g�̌���
	
	for (int j = 0; j < N; j++) {
		for (int i = j + 1; i < N; i++) {
			if (graphR[j][i].size() == 0) {
				S.push(LLPair(j, i));
			}
		}
	}

	while (S.empty() == false) {
		LLPair node = S.front();
		S.pop();
		L.push_back(node);

		for (auto next : graph[node.a][node.b]) {
			inEdge[next.a][next.b]--;
			if (inEdge[next.a][next.b] == 0) {
				S.push(LLPair(next.a, next.b));
			}
		}
	}

	//���[�v�����݂���ꍇ�͉��Ȃ�
	if ((int)L.size() < N * (N - 1) / 2) {
		printf("-1\n");
		return 0;
	}

	int result = 0;
	stack<LLPair> st;
	vector<vector<int>> dist(N, vector<int>(N, 1));

	int maxDist = 0;

	for (auto node : L) {
		int d = dist[node.a][node.b];

		for (auto next : graph[node.a][node.b]) {
			if (d + 1 > dist[next.a][next.b]) {
				dist[next.a][next.b] = d + 1;
				maxDist = max(maxDist, d + 1);
			}
		}
	}

	result = maxDist;

	printf("%d\n", result);
}
*/


Measured memory_bytes: 384