#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <cmath>
#include <numeric>
#include <iomanip>
#include <set>
#include <string.h>

using namespace std;

typedef long long ll;

#define REP(i,n) for(ll (i)=0;(i)<(n);(i)++)
#define REP3(i,st,en) for(ll (i)=(st);(i)<(en);(i)++)

using P = pair<ll, ll>;
const int MOD = 1e9+7;
const ll INF = 1e+14;
const double PI = 3.14159265349;


/*
  a b  u v
  0 8  8 8
  1 7  6 8   001 111
  2 6  4 8
  3 5  6 8   011 101
  4 4  0 8
  5 3  6 8   101 011
  6 2  4 8
  7 1  6 8   111 001
  8 0  8 0

 XORと和が等しい -> どちらか一方が1のbit(XORで1になるbit)が同じものはすべてaが1とした1通りに集約できる．
 そこで，a,bの各桁に(1,1),(1,0),(0,0)を割り当てていく．((1,0)と(0,1)は上の理由より同じ．)
 XORが等しい時，"どちらか一方が1のbitの桁"は必ず等しい(XORはそららの総和になるが，ある桁の値を他の桁の和で表すことは出来ないんので，一意になる．)．
 そのため，この割り当ての際にXORと和が被ることはなく，これを桁DPで和がN以下になるように数え上げれば良い．

 桁DPのときの注意点として，下の桁からの繰り上げで上位桁が変わる．そこで，通常の桁DPのように上位桁から決めていくのではなく，下位桁から決めて繰り上げの情報を上位桁に渡す．
*/


int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);

  ll N;
  cin >> N;

  ll DIG = 63;
  vector<ll> bit(DIG);
  REP(i,DIG){
    bit[i] = (N>>i) & 1;
  }

  vector<vector<vector<ll>>> dp(DIG,vector<vector<ll>>(2,vector<ll>(2,0))); // [digit][smaller][carry]

  dp[0][0][0] = 1;
  dp[0][1][0] = 1;
  REP(i,DIG-1){
    // not smallerな組み合わせ dp[][0][]
    //    |-- 前の桁からのcarry-なし
    //　  |　       |-- 次の桁へのcarry-なし  >>  pair (1,0),(0,0)
    dp[i+1][0][0] += dp[i][0][0] * 2; dp[i+1][0][0] %= MOD;
    //    |         \--- 次の桁へのcarry-あり  >> pair (1,1)
    dp[i+1][0][1] += dp[i][0][0]; dp[i+1][0][1] %= MOD;
    //    |
    //    \--- 前の桁からのcarry-あり
    //　 　         |-- 次の桁へのcarry-なし  >>  pair (0,0)
    dp[i+1][0][0] += dp[i][0][1]; dp[i+1][0][0] %= MOD;
    //              \--- 次の桁へのcarry-あり >>  pair (1,0),(1,1)
    dp[i+1][0][1] += dp[i][0][1] * 2; dp[i+1][0][1] %= MOD;


    // smallerな組み合わせ dp[][1][]
    //     |-- Nのi桁目が 1
    if (bit[i] == 1){
      //  |       |-- vのi桁目が0ならそれ以下がnot-smallerでもsmallerのまま
      //　|       |        |-- 次の桁へのcarry-なし  >>  pair (0,0)
      dp[i+1][1][0] += dp[i][0][0]; dp[i+1][1][0] %= MOD;
      //  |       |        \--- 次の桁へのcarry-あり
      //  |       |             |-- 前の桁からのcarry-なし  >>  pair (1,1)
      dp[i+1][1][1] += dp[i][0][0]; dp[i+1][1][1] %= MOD;
      //  |       |             \--- 前の桁からのcarry-あり  >>  pair (1,0)
      dp[i+1][1][1] += dp[i][0][1]; dp[i+1][1][1] %= MOD;
      //  |       |
      //  |       |
      //  |       \---vのi桁目が1ならそれ以下はsmallerでないとだめ
      //　|　              |-- 次の桁へのcarry-なし
      //  |                |    |--- 前の桁からのcarry-なし  >>  pair (1,0)
      dp[i+1][1][0] += dp[i][1][0]; dp[i+1][1][0] %= MOD;
      //  |                |    \--- 前の桁からのcarry-あり  >>  pair (0,0)
      dp[i+1][1][0] += dp[i][1][1]; dp[i+1][1][0] %= MOD;
      //  |                \-- 次の桁へのcarry-あり  >>  pair (1,1)
      dp[i+1][1][1] += dp[i][1][1]; dp[i+1][1][1] %= MOD;
    }
    //    |-- Nのi桁目が 0
    if (bit[i] == 0){
      //  |       |-- vのi桁目が0でかつsmallerでないとだめ
      //　|       |        |-- 次の桁へのcarry-なし  >>  pair (0,0)
      dp[i+1][1][0] += dp[i][1][0]; dp[i+1][1][0] %= MOD;
      //  |       |        \--- 次の桁へのcarry-あり
      //  |       |             |-- 前の桁からのcarry-なし  >>  pair (1,1)
      dp[i+1][1][1] += dp[i][1][0]; dp[i+1][1][1] %= MOD;
      //  |       |             \--- 前の桁からのcarry-あり  >>  pair (1,0)
      dp[i+1][1][1] += dp[i][1][1]; dp[i+1][1][1] %= MOD;
    }
  }

  cout << dp[DIG-1][1][0] << "\n";
  return 0;
}


Measured memory_bytes: 256