import java.lang.Long

val mod = 1000000007

fun main(args: Array<String>) {
    val (L, R) = readInputLine().split(" ").map { Long.toString(it.toLong(), 2).padStart(64, '0').toCharArray() }

    L.reverse()
    R.reverse()

    // dp[xにMSBが現れたか][xがLより真に大きいか][yがRより真に小さいか][桁数]
    val dp = Array(2, {Array(2, {Array(2, {IntArray(64, {-1})})})})

    println(solve(L, R, dp, 63, 0, 0, 0))
}

fun readInputLine(): String {
    return readLine()!!
}

fun solve(L: CharArray, R: CharArray, dp: Array<Array<Array<IntArray>>>, pos: Int, Xflag: Int, Yflag: Int, MSBflag: Int): Int {
    if (pos == -1) {
        return 1
    }
    
    if (dp[MSBflag][Xflag][Yflag][pos] != -1) {
        return dp[MSBflag][Xflag][Yflag][pos]
    }
    
    var ret = 0
    
    // Xのビットが0, Yのビットも0のパターン
    // XがLより真に大きいことが確定している場合はXのビットは自由に動けるため、
    // Xが真に大きいフラグまたはLのビットが0を条件にする
    // Yのビットについては0にすると必ずRに等しいかRより真に小さくなるためDon't care
    if (Xflag == 1 || L[pos] == '0') {
        ret += solve(L, R, dp, pos - 1, Xflag, if (R[pos] == '1') 1 else Yflag, MSBflag)
        ret %= mod
    }
    
    // Xのビットが0, Yのビットが1のパターン
    // X条件は同様、YがRより真に小さいことが確定している場合はYのビットは自由に動けるため、
    // Yが真に小さいフラグまたはRのビットが0を条件にする
    // XのMSBが現れる前にこのパターンには入らない。
    // Yの最上位ビットが1, 対応するXのビットが0のパターンに該当するため。
    if ((Xflag == 1 || L[pos] == '0') && (Yflag == 1 || R[pos] == '1') && MSBflag == 1) {
        ret += solve(L, R, dp, pos - 1, Xflag, Yflag, MSBflag)
        ret %= mod
    }
    
    // Xのビットが1, Yのビットが1のパターン
    // Y条件は同様、Xのビットについては1にすると必ずLに等しいかLより真に大きくなるためDon't care
    // XとYのMSBが現れたとして、MSBflagには1を入れる
    if (Yflag == 1 || R[pos] == '1') {
        ret += solve(L, R, dp, pos - 1, if (L[pos] == '0') 1 else Xflag, Yflag, 1)
        ret %= mod
    }
    
    // Xのビットが1, Yのビットが0のパターンは繰り下がりが発生するためやらない。
    
    dp[MSBflag][Xflag][Yflag][pos] = ret
    return ret
}
