#![allow(unused_imports)]
#![allow(dead_code)]
#![allow(unused_mut)]

use crate::rust::library::{util::io::*,math::mod_int::*};
use itertools::*;

const MOD: u32 = 1_000_000_007;
const_mod!(P,MOD);
type Fp=ModInt<P>;

fn main() {
    input!{
        n:usize,
        v:[Fp;n],
    }
    println!("{}",(v.iter().copied().sum::<Fp>().pow(2)-v.iter().map(|&x|x*x).sum::<Fp>())/Fp::new(2));
}

pub mod rust {

pub mod library {

pub mod math {

pub mod mod_int {

use std::ops::{Add,AddAssign,Sub,SubAssign,Mul,MulAssign,Div,DivAssign,Neg};
use std::str::FromStr;
use std::num::ParseIntError;
use std::iter::{Sum,Product};

pub fn inv_mod(a:u64,m:u64)->u64{
    let m=m as i64;
    let mut a=a as i64;
    let mut b=m as i64;
    let mut u=1i64;
    let mut v=0i64;
    while b>0 {
        let t=a/b;
        a-=t*b;
        u-=t*v;
        std::mem::swap(&mut a,&mut b);
        std::mem::swap(&mut u,&mut v);
    }
    let ans =(if u>=0{u%m}else{m+(u%m)%m})as u64;
    ans
}

pub trait Mod:Sized{
    fn m()->u32;
    fn m64()->u64;
    fn mi64()->i64;
}
#[macro_export]
macro_rules! const_mod{
    ($st:ident,$m:expr)=>{
        struct $st{}
        impl Mod for $st {
            fn m()->u32{$m}
            fn m64()->u64{$m as u64}
            fn mi64()->i64{$m as i64}
        }
    }
}

pub struct ModInt<M:Mod>{a:u32,_p:std::marker::PhantomData<M>}

impl<M: Mod> ModInt<M>{
    pub fn new(a:u32)->Self{
        ModInt{a,_p:std::marker::PhantomData}
    }
    pub fn newu64(a:u64)->Self{
        ModInt{a:(a%M::m64())as u32,_p:std::marker::PhantomData}
    }
    pub fn newi64(a:i64)->Self{
        ModInt{a:((a%M::mi64()+M::mi64())%M::mi64()) as u32,_p:std::marker::PhantomData}
    }
    pub fn value(&self)->u32{self.a}
    pub fn pow(&self,p:u64)->Self{
        let mut exp=p;
        let mut now=*self;
        let mut ans=ModInt::new(1);
        while exp>0{
            if (exp&1)==1{ans*=now;}
            now*=now;
            exp>>=1;
        }
        ans
    }
    // pub fn comb(k:usize)->Self{
    //     Self::new(k)
    // }
    pub fn inv(&self)->Self{Self::new(inv_mod(self.a as u64,M::m64())as u32)}
}

impl<M:Mod>Clone for ModInt<M>{
    fn clone(&self)->Self{ModInt::new(self.a)}
}
impl<M:Mod>Copy for ModInt<M>{}
impl<M:Mod>From<i64>for ModInt<M>{
    fn from(i:i64)->Self{Self::newi64(i)}
}
impl<M:Mod>From<i32>for ModInt<M>{
    fn from(i:i32)->Self{Self::newi64(i as i64)}
}

impl<M:Mod>FromStr for ModInt<M>{
    type Err = ParseIntError;
    fn from_str(i:&str)->Result<Self, Self::Err>{
        let res=i.parse::<i64>()?;
        Ok(Self::newi64(res))
    }
}
impl<M:Mod>Sum for ModInt<M>{
    fn sum<I>(iter: I) -> Self where I: Iterator<Item = Self>,{
        iter.fold(Self::new(0), |b, i| b + i)
    }
}

impl<M:Mod>Product for ModInt<M>{
    fn product<I>(iter: I) -> Self where I: Iterator<Item = Self>,{
        iter.fold(Self::new(0), |b, i| b * i)
    }
}
impl<M:Mod>Add for ModInt<M>{
    type Output=Self;
    fn add(self,rhs:Self)->Self{
        let a=self.a+rhs.a;
        ModInt::new(if a>=M::m(){a-M::m()}else{a})
    }
}
impl<M:Mod>Sub for ModInt<M>{
    type Output=Self;
    fn sub(self,rhs:Self)->Self{
        ModInt::new(if self.a<rhs.a{M::m()+self.a-rhs.a}else{self.a-rhs.a})
    }
}
impl<M:Mod>Mul for ModInt<M>{
    type Output=Self;
    fn mul(self,rhs:Self)->Self{
        ModInt::newu64(self.a as u64*rhs.a as u64)
    }
}
impl<M:Mod>Div for ModInt<M>{
    type Output=Self;
    fn div(self,rhs:Self)->Self{
        self*rhs.inv()
    }
}
impl<M:Mod>Neg for ModInt<M> {
    type Output = Self;
    fn neg(self) -> Self {
        ModInt::new(M::m()-self.value())
    }
}
impl<M:Mod>AddAssign for ModInt<M>{fn add_assign(&mut self,rhs:Self){*self=*self+rhs;}}
impl<M:Mod>SubAssign for ModInt<M>{fn sub_assign(&mut self,rhs:Self){*self=*self-rhs;}}
impl<M:Mod>MulAssign for ModInt<M>{fn mul_assign(&mut self,rhs:Self){*self=*self*rhs;}}
impl<M:Mod>DivAssign for ModInt<M>{fn div_assign(&mut self,rhs:Self){*self=*self/rhs;}}

impl<M:Mod>std::fmt::Debug for ModInt<M>{
    fn fmt(&self,f:&mut std::fmt::Formatter)->Result<(),std::fmt::Error>{
        write!(f,"M{}",self.a)
    }
}
impl<M:Mod> std::fmt::Display for ModInt<M> {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        self.value().fmt(f)
    }
}

}  // mod mod_int

}  // mod math

pub mod util {

pub mod io {

#[macro_export]
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let mut s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

#[macro_export]
macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};

    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

#[macro_export]
macro_rules! read_value {
    ($iter:expr, [tree;$len:expr]) => {
        {
            let mut g:Vec<Vec<usize>>=vec![Vec::new();$len];
            for (s,t) in read_value!($iter,[(usize1,usize1);$len-1]){
                g[s].push(t);
                g[t].push(s);
            }
            g
        }
    };
    ($iter:expr, [graph;$vertex:expr,$edge:expr]) => {
        {
            let mut g:Vec<Vec<usize>>=vec![Vec::new();$vertex];
            for (s,t) in read_value!($iter,[(usize1,usize1);$edge]){
                g[s].push(t);
                g[t].push(s);
            }
            g
        }
    };
    ($iter:expr, [directed;$vertex:expr,$edge:expr]) => {
        {
            let mut g:Vec<Vec<usize>>=vec![Vec::new();$vertex];
            for (s,t) in read_value!($iter,[(usize1,usize1);$edge]){
                g[s].push(t);
            }
            g
        }
    };
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };

    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };

    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };

    ($iter:expr, bytes) => {
        read_value!($iter, String).into_bytes()
    };

    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };

    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

}  // mod io

}  // mod util

}  // mod library

}  // mod rust


// -*- coding:utf-8-unix -*-

use proconio::input;

fn main() {
    input! {
        n: usize,
        a: [u64; n],
    }

    let mut ans = 0;
    let mut part_sum = a.iter().sum::<u64>();
    let divisor = 10_u64.pow(9) + 7;
    // println!("ps: {}", part_sum);
    // println!("{:?}", a);
    for i in 1..n {
        // println!("ai-1: {}", a[i - 1]);
        part_sum = (part_sum + divisor - a[i - 1]) % divisor;
        // println!("ps: {}", part_sum);
        ans = (ans + (a[i - 1] * part_sum) % divisor) % divisor;
    }
    println!("{}", ans);
}


use std::mem;
use std::io;

fn procon_read<T: std::str::FromStr>() ->  Vec<T> {
    let mut buf = String::new();
    io::stdin().read_line(&mut buf).expect("");
    let iter = buf.split_whitespace();
    let mut v: Vec<T> = Vec::new();
    for i in iter {
        v.push(i.parse().ok().unwrap());
    }
    v
}

fn mod_add(a:&u64, b:&u64, m:&u64) -> u64 {
    (*a%*m + *b%*m)%*m
}

fn mod_sub(a:&u64, b:&u64, m:&u64) -> u64 {
    let mut ret = (*a%*m) as i64 - (*b%*m) as i64;
    if ret < 0 {
        ret += *m as i64;
    }
    ret as u64
}

fn mod_mul(a:&u64, b:&u64, m:&u64) -> u64 {
    ((*a%*m)*(*b%*m))%m
}

fn mod_pow(a:&u64, b:&u64, m:&u64) -> u64 {
    let mut ret:u64 = 1;
    let mut aa = *a%*m;
    let mut bb = *b;
    while bb != 0 {
        if bb&(1_u64) == 1 {
            ret = (ret*aa)%*m;
        }
        aa = (aa*aa)%*m;
        bb >>= 1;
    }
    ret
}

fn mod_inv(a:&u64, p:&u64) -> u64 {
    // aのmod p における逆元を求める
    let mut aa = *a;
    let mut b = *p;
    let mut u:i64 = 1;
    let mut v:i64 = 0;
    while b != 0 {
        let t = aa/b;
        aa = aa - t*b;
        mem::swap(&mut aa, &mut b);
        u = u - (t as i64) * v;
        mem::swap(&mut u, &mut v);
    }
    u = u % (*p as i64);
    if u < 0 {
        u += (*p as i64);
    }
    u as u64
}

fn mod_div(a:&u64, b:&u64, m:&u64) -> u64 {
    let mut ret = *a%*m;
    let inv = *b%*m;
    ret = (ret * mod_inv(&inv, m))%*m;
    ret
}

fn COMinit(fac:&mut Vec<u64>, finv:&mut Vec<u64>, inv:&mut Vec<u64>, memMax:u64, m:&u64){
    fac.push(1); fac.push(1);
    finv.push(1); finv.push(1);
    for i in 2..memMax as usize {
        fac.push((fac[i-1]*(i as u64))%*m);
        inv.push(*m - ((inv[(*m as usize)%i] * (*m/(i as u64)) )%*m) );
        finv.push( (finv[i-1]*(inv[i]) ) % *m );
    }
}

fn comb(n:&u64, k:&u64, m:&u64, fac:&Vec<u64>, finv:&Vec<u64>) -> u64 {
    if *n < *k {
        return 0
    }
    fac[*n as usize] * ((finv[*k as usize]*finv[(*n - *k) as usize] )%*m) % *m
}

fn main() {
    let n:u64 = procon_read()[0];
    let v:Vec<u64> = procon_read();
    let m:u64 = 1000000007;// 10⁹ +7
    let mut ret = 0_u64;
    for j in 1..n as usize {
        for i in 0..j as usize {
            ret = mod_add(&ret, &mod_mul(&v[i], &v[j], &m), &m);
        }
    }
    println!("{}", ret);
}


fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>()
.split_whitespace()
        .map(|e| e.parse().ok().unwrap())
        .collect()
}

fn read_vec2<T: std::str::FromStr>(n: u32) -> Vec<Vec<T>> {
    (0..n).map(|_| read_vec()).collect()
}

fn main() {
    // solver code...
    let _ = read::<i64>();
    let mut a_vec = read_vec::<i64>();
    a_vec = a_vec.sort();
    let MOD = 1000000007;
    let mut sum = 0;
    for a in &a_vec {
        sum += a;
    }

    let mut ans = 0;
    for a in &a_vec {
        sum -= a;
        ans += (a * sum)%MOD;
        ans %= MOD;
    }

    println!("{}", ans);
}


fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>()
.split_whitespace()
        .map(|e| e.parse().ok().unwrap())
        .collect()
}

fn read_vec2<T: std::str::FromStr>(n: u32) -> Vec<Vec<T>> {
    (0..n).map(|_| read_vec()).collect()
}

fn main() {
    // solver code...
    let _ = read::<i64>();
    let mut a_vec = read_vec::<i64>();
    a_vec.sort();
    let mut max_a: i64 = 0;
    let MOD = 1000000007;
    let mut sum = 0;
    for a in &a_vec {
        sum += a;
    }

    let mut ans = 0;
    for a in &a_vec {
        sum -= a;
        ans += (a * sum)%MOD;
        ans %= MOD;
    }

    println!("{}", ans);
}


import Foundation

let main: () = {
    let MOD = 1_000_000_007
    let N = nextInt()
    let A = listOfInt()
    var S = IntArray(N + 1)
    for n in 1 ... N {
        S[n] = S[n - 1] + A[n - 1]
    }
    var ans = 0
    for n in 0 ..< N - 1 {
        let sum = S[N] - S[n + 1]
        let mod = sum % MOD
        ans += mod * A[n] % MOD
        ans %= MOD
    }
    print(ans)
}()

//----------------------------------

let dx = [1, 0, -1, 0] //[1, 0, -1, 0, -1,  1, -1, 1]
let dy = [0, 1, 0, -1] //[0, 1, 0, -1, -1, -1,  1, 1]

@inlinable func gcd(_ a: Int, _ b: Int) -> Int { (b > 0) ? gcd(b, a % b) : a }
@inlinable func lcm(_ a: Int, _ b: Int) -> Int { a / gcd(a, b) * b }

//----------------------------------

infix operator  =~ : ComparisonPrecedence
infix operator !=~ : ComparisonPrecedence
func =~ <T: FixedWidthInteger>(left: T, right: Range<T>) -> Bool { right ~= left }
func !=~ <T: FixedWidthInteger>(left: T, right: Range<T>) -> Bool { !(right ~= left) }
func =~ <T: FixedWidthInteger>(left: T, right: ClosedRange<T>) -> Bool { right ~= left }
func !=~ <T: FixedWidthInteger>(left: T, right: ClosedRange<T>) -> Bool { !(right ~= left) }

func =~ <T: Collection > (left: T.Element, right: T) -> Bool where T.Element : Equatable { right.contains(left) }
func !=~ <T: Collection > (left: T.Element, right: T) -> Bool where T.Element : Equatable { !right.contains(left) }

infix operator /^ : MultiplicationPrecedence
infix operator /^= : AssignmentPrecedence
func /^ <T: FixedWidthInteger>(left: T, right: T) -> T { (left + (right - 1)) / right }
func /^= <T: FixedWidthInteger>(left: inout T, right: T) { left = (left + (right - 1)) / right }

@inlinable func chmax<T: Comparable>(_ m: inout T, _ q: T) { if (m < q) { m = q } }
@inlinable func chmin<T: Comparable>(_ m: inout T, _ q: T) { if (m > q) { m = q } }
@inlinable func chRmax<T: Comparable>(_ m: inout T, _ q: T) -> Bool { if (m < q) { m = q; return true } else { return false } }
@inlinable func chRmin<T: Comparable>(_ m: inout T, _ q: T) -> Bool { if (m > q) { m = q; return true } else { return false } }

prefix operator *
prefix func * <T> (a: [T]) -> (T, T) { (a[0], a[1]) }
prefix func * <T> (a: [T]) -> (T, T, T) { (a[0], a[1], a[2]) }
prefix func * <T> (a: [T]) -> (T, T, T, T) { (a[0], a[1], a[2], a[3]) }
prefix func * <T> (a: [T]) -> (T, T, T, T, T) { (a[0], a[1], a[2], a[3], a[4]) }
prefix func * <T> (a: [T]) -> (T, T, T, T, T, T) { (a[0], a[1], a[2], a[3], a[4], a[5]) }

func printErr(_ str: String, terminator: String = "\n") {
    let s = str + terminator
    FileHandle.standardError.write(s.data(using: .utf8)!)
    FileHandle.standardError.synchronizeFile()
}

@inlinable func next() -> String { readLine()! }
@inlinable func nextInt() -> Int { Int(next())! }
@inlinable func nextDouble() -> Double { Double(next())! }
@inlinable func listOfString() -> [String] { next().split(separator: " ").map(String.init) }
@inlinable func listOfInt() -> [Int] { listOfString().map { Int($0)! } }
@inlinable func listOfInt(_ offset: Int = 0) -> [Int] { listOfString().map { Int($0)! + offset } }
@inlinable func listOfInt(_ offsets: Int ...) -> [Int] { listOfString().enumerated().map { Int($0.element)! + offsets[$0.offset % offsets.count] } }
@inlinable func listOfDouble(_ offset: Double = 0.0) -> [Double] { listOfString().map { Double($0)! + offset } }
@inlinable func listOfDouble(_ offsets: Double ...) -> [Double] { listOfString().enumerated().map { Double($0.element)! + offsets[$0.offset % offsets.count] } }

extension Int {
    init(s: String) { self.init(s)! }
    var isEven: Bool { self.isMultiple(of: 2) }
    var isOdd: Bool { !self.isEven }
    var isTrue: Bool { self != 0 }
    var isFalse: Bool { !self.isTrue }
    var toString: String { String(self) }
    var toChar: Character { Character(UnicodeScalar(UInt8(self))) }
}
func + (left: Int, right: Bool) -> Int { left + (right ? 1 : 0) }
extension Character {
    var asciiCode: Int { Int(self.asciiValue!) }
    var string: String { String(self) }
}
extension String {
    @inlinable subscript (position: Int) -> Character { self[self.index(self.startIndex, offsetBy: position)] }
    @inlinable func repeate(_ times: Int) -> String { String(repeating: self, count: times) }
    //  @inlinable subscript (n: Int) -> String { String(self[self.index(self.startIndex, offsetBy: n)]) }
    //  @inlinable subscript (n: Int) -> Int { Int(self[self.index(self.startIndex, offsetBy: n)].asciiValue!) }
    var toInt: Int { Int(self)! }
}
extension String { // VB like
    @inlinable func _index(_ position: Int) -> String.Index! {
        if !(0 ..< self.count ~= position) { return nil }
        return self.index(self.startIndex, offsetBy: position)
    }
    @inlinable func mid(from index: Int, length: Int) -> String! {
        if let startPosition = self._index(index) {
            if let endPosition = self._index(index + length - 1) {
                return String(self[startPosition...endPosition])
            } else {
                let endPosition = self.index(before: self.endIndex)
                return String(self[startPosition...endPosition])
            }
        }
        return ""
    }
    @inlinable func left(_ length: Int) -> String { String(self.prefix(length)) }
    @inlinable func right(_ length: Int) -> String { String(self.suffix(length)) }
}

extension Dictionary {
    @inlinable mutating func getOrSet(_ key: Key, _ defaultValue: () -> Value) -> Value {
        if let stored = self[key] { return stored }
        else {
            let newValue = defaultValue()
            self[key] = newValue
            return newValue
        }
    }
    @inlinable mutating func getOrElse(_ key: Key, _ defaultValue: () -> Value) -> Value {
        if let stored = self[key] { return stored } else { return defaultValue() }
    }
    @inlinable func containsKey(_ key: Key) -> Bool { self.keys.contains(key) }
}

extension Set {
    static func += (left: inout Set<Element>, right: Element) { left.insert(right) }
    static func -= (left: inout Set<Element>, right: Element) { left.remove(right) }
}

extension Array {
    static func += (left: inout Array<Element>, right: Element) { left.append(right) }
    init(_ size: Int, _ initValue: ((Int) -> Element)) {
        self = [Element]()
        for index in 0 ..< size {
            let value = initValue(index)
            self.append(value)
        }
    }
    init(_ size: Int, _ initValue: (() -> Element)) {
        self = [Element]()
        for _ in 0 ..< size {
            let value = initValue()
            self.append(value)
        }
    }
}
typealias IntArray = Array<Int>
typealias DoubleArray = Array<Double>
typealias BoolArray = Array<Bool>
typealias StringArray = Array<String>

extension Array where Element == Int {
    init(_ size: Int) {
        self = [Element](repeating: 0, count: size)
    }
}
extension Array where Element == Double {
    init(_ size: Int) {
        self = [Element](repeating: 0.0, count: size)
    }
}
extension Array where Element == Bool {
    init(_ size: Int) {
        self = [Element](repeating: false, count: size)
    }
}
extension Array where Element == String {
    init(_ size: Int) {
        self = [Element](repeating: "", count: size)
    }
}

extension Array {
    @inlinable func count(_ predicate: ((Element) -> Bool)) -> Int {
        var cnt = 0; for e in self { if (predicate(e)) { cnt += 1 } }
        return cnt
    }
    @inlinable func groupBy<K>(_ keySelector: (Element) -> K) -> [K : [Element]] {
        var destination = [K : [Element]]()
        for element in self {
            let key = keySelector(element)
            var list = destination.getOrSet(key) { [Element]() }
            list.append(element)
            destination[key] = list
        }
        return destination
    }
    @inlinable func groupByIndexed<K>(_ keySelector: (Element) -> K) -> [K : [Int]] {
        var destination = [K : [Int]]()
        for element in self.enumerated() {
            let key = keySelector(element.element)
            var list = destination.getOrSet(key) { [Int]() }
            list.append(element.offset)
            destination[key] = list
        }
        return destination
    }
}

extension Array {
    func binarySearch(_ element: Element, by compare: (Element, Element) -> Int, fromIndex: Int = 0, toIndex: Int = -1) -> Int {
        var low = fromIndex
        var high = (toIndex == -1) ? self.count - 1 : toIndex - 1
        while (low <= high) {
            let mid = (low + high) >> 1 // safe from overflows
            let midVal = self[mid]
            let cmp = compare(midVal, element)
            if (cmp < 0) { low = mid + 1 }          //-1
            else if (0 < cmp) { high = mid - 1 }    // 1
            else { return mid } // key found        // 0
        }
        return -(low + 1)  // key not found
    }
}
extension Array where Element : Comparable {
    func binarySearch(_ element: Element, fromIndex: Int = 0, toIndex: Int = -1) -> Int {
        var low = fromIndex
        var high = (toIndex == -1) ? self.count - 1 : toIndex - 1
        while (low <= high) {
            let mid = (low + high) >> 1 // safe from overflows
            let midVal = self[mid]
            if (midVal < element) { low = mid + 1 }
            else if (midVal > element) { high = mid - 1 }
            else { return mid } // key found
        }
        return -(low + 1)  // key not found
    }
}

extension Array where Element == Int {
    @inlinable func distinct() -> [Element] {
        var set = Set<Element>(), ary = [Element]()
        for n in self.indices { if !set.contains(self[n]) { ary.append(self[n]); set.insert(self[n]) } }
        return ary
    }
    @inlinable func any(_ predicate: (Element) -> Bool) -> Bool {
        var any = false; for element in self { if predicate(element) { any = true } }
        return any
    }
    @inlinable func all(_ predicate: (Element) -> Bool) -> Bool {
        self.allSatisfy(predicate)
    }
    @inlinable func sum() -> Element { self.reduce(0, +) }
    @inlinable func sum(by predicate: (Element) -> Element) -> Element {
        var sum = 0; for e in self { sum += predicate(e) }
        return sum
    }
    @inlinable func joinToString(_ sepatator: String = " ") -> String { self.map { String($0) }.joined(separator: sepatator) }
}

extension Array where Element == Double {
    @inlinable func sum() -> Element { self.reduce(0.0, +) }
    @inlinable func sum(by predicate: (Element) -> Element) -> Element {
        var sum = 0.0; for e in self { sum += predicate(e) }
        return sum
    }
    @inlinable func joinToString(_ sepatator: String = " ") -> String { self.map { String($0) }.joined(separator: sepatator) }
}
extension Array where Element == String {
    @inlinable func toIntDouble() -> (Int, Double) { (Int(self[0])!, Double(self[1])!) }
    @inlinable func toIntString() -> (Int, String) { (Int(self[0])!, self[1]) }
    @inlinable func toIntIntString() -> (Int, Int, String) { (Int(self[0])!, Int(self[1])!, self[2]) }
}

@inlinable func block( _ action: () -> Void) {
    action()
}
@inlinable func repeate(_ times1: Int, _ action: () -> Void) {
    for _ in 0 ..< times1 { action() }
}
@inlinable func repeate(_ times1: Int, _ action: (Int) -> Void) {
    for index1 in 0 ..< times1 {
        action(index1)
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ action: (Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            action(index1, index2)
        }
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ times3: Int, _ action: (Int, Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            for index3 in 0 ..< times3 {
                action(index1, index2, index3)
            }
        }
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ times3: Int, _ times4: Int, _ action: (Int, Int, Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            for index3 in 0 ..< times3 {
                for index4 in 0 ..< times4 {
                    action(index1, index2, index3, index4)
                }
            }
        }
    }
}

func measureTimeSeconds(block: (() -> Void)) -> Double {
    let startTime = Date()
    block()
    let duration = -startTime.timeIntervalSinceNow
    return duration
}


import Foundation

let main: () = {
    let MOD = 1_000_000_007
    let N = nextInt()
    let A = listOfInt()
    var sum = 0
    var ans = 0
    for n in 0 ..< N {
        ans += A[n] * sum
        ans %= MOD
        sum += A[n]
        sum %= MOD
    }
    print(ans)
}()

//----------------------------------

let dx = [1, 0, -1, 0] //[1, 0, -1, 0, -1,  1, -1, 1]
let dy = [0, 1, 0, -1] //[0, 1, 0, -1, -1, -1,  1, 1]

@inlinable func gcd(_ a: Int, _ b: Int) -> Int { (b > 0) ? gcd(b, a % b) : a }
@inlinable func lcm(_ a: Int, _ b: Int) -> Int { a / gcd(a, b) * b }

//----------------------------------

infix operator  =~ : ComparisonPrecedence
infix operator !=~ : ComparisonPrecedence
func =~ <T: FixedWidthInteger>(left: T, right: Range<T>) -> Bool { right ~= left }
func !=~ <T: FixedWidthInteger>(left: T, right: Range<T>) -> Bool { !(right ~= left) }
func =~ <T: FixedWidthInteger>(left: T, right: ClosedRange<T>) -> Bool { right ~= left }
func !=~ <T: FixedWidthInteger>(left: T, right: ClosedRange<T>) -> Bool { !(right ~= left) }

func =~ <T: Collection > (left: T.Element, right: T) -> Bool where T.Element : Equatable { right.contains(left) }
func !=~ <T: Collection > (left: T.Element, right: T) -> Bool where T.Element : Equatable { !right.contains(left) }

infix operator /^ : MultiplicationPrecedence
infix operator /^= : AssignmentPrecedence
func /^ <T: FixedWidthInteger>(left: T, right: T) -> T { (left + (right - 1)) / right }
func /^= <T: FixedWidthInteger>(left: inout T, right: T) { left = (left + (right - 1)) / right }

@inlinable func chmax<T: Comparable>(_ m: inout T, _ q: T) { if (m < q) { m = q } }
@inlinable func chmin<T: Comparable>(_ m: inout T, _ q: T) { if (m > q) { m = q } }
@inlinable func chRmax<T: Comparable>(_ m: inout T, _ q: T) -> Bool { if (m < q) { m = q; return true } else { return false } }
@inlinable func chRmin<T: Comparable>(_ m: inout T, _ q: T) -> Bool { if (m > q) { m = q; return true } else { return false } }

prefix operator *
prefix func * <T> (a: [T]) -> (T, T) { (a[0], a[1]) }
prefix func * <T> (a: [T]) -> (T, T, T) { (a[0], a[1], a[2]) }
prefix func * <T> (a: [T]) -> (T, T, T, T) { (a[0], a[1], a[2], a[3]) }
prefix func * <T> (a: [T]) -> (T, T, T, T, T) { (a[0], a[1], a[2], a[3], a[4]) }
prefix func * <T> (a: [T]) -> (T, T, T, T, T, T) { (a[0], a[1], a[2], a[3], a[4], a[5]) }

func printErr(_ str: String, terminator: String = "\n") {
    let s = str + terminator
    FileHandle.standardError.write(s.data(using: .utf8)!)
    FileHandle.standardError.synchronizeFile()
}

@inlinable func next() -> String { readLine()! }
@inlinable func nextInt() -> Int { Int(next())! }
@inlinable func nextDouble() -> Double { Double(next())! }
@inlinable func listOfString() -> [String] { next().split(separator: " ").map(String.init) }
@inlinable func listOfInt() -> [Int] { listOfString().map { Int($0)! } }
@inlinable func listOfInt(_ offset: Int = 0) -> [Int] { listOfString().map { Int($0)! + offset } }
@inlinable func listOfInt(_ offsets: Int ...) -> [Int] { listOfString().enumerated().map { Int($0.element)! + offsets[$0.offset % offsets.count] } }
@inlinable func listOfDouble(_ offset: Double = 0.0) -> [Double] { listOfString().map { Double($0)! + offset } }
@inlinable func listOfDouble(_ offsets: Double ...) -> [Double] { listOfString().enumerated().map { Double($0.element)! + offsets[$0.offset % offsets.count] } }

extension Int {
    init(s: String) { self.init(s)! }
    var isEven: Bool { self.isMultiple(of: 2) }
    var isOdd: Bool { !self.isEven }
    var isTrue: Bool { self != 0 }
    var isFalse: Bool { !self.isTrue }
    var toString: String { String(self) }
    var toChar: Character { Character(UnicodeScalar(UInt8(self))) }
}
func + (left: Int, right: Bool) -> Int { left + (right ? 1 : 0) }
extension Character {
    var asciiCode: Int { Int(self.asciiValue!) }
    var string: String { String(self) }
}
extension String {
    @inlinable subscript (position: Int) -> Character { self[self.index(self.startIndex, offsetBy: position)] }
    @inlinable func repeate(_ times: Int) -> String { String(repeating: self, count: times) }
    //  @inlinable subscript (n: Int) -> String { String(self[self.index(self.startIndex, offsetBy: n)]) }
    //  @inlinable subscript (n: Int) -> Int { Int(self[self.index(self.startIndex, offsetBy: n)].asciiValue!) }
    var toInt: Int { Int(self)! }
}
extension String { // VB like
    @inlinable func _index(_ position: Int) -> String.Index! {
        if !(0 ..< self.count ~= position) { return nil }
        return self.index(self.startIndex, offsetBy: position)
    }
    @inlinable func mid(from index: Int, length: Int) -> String! {
        if let startPosition = self._index(index) {
            if let endPosition = self._index(index + length - 1) {
                return String(self[startPosition...endPosition])
            } else {
                let endPosition = self.index(before: self.endIndex)
                return String(self[startPosition...endPosition])
            }
        }
        return ""
    }
    @inlinable func left(_ length: Int) -> String { String(self.prefix(length)) }
    @inlinable func right(_ length: Int) -> String { String(self.suffix(length)) }
}

extension Dictionary {
    @inlinable mutating func getOrSet(_ key: Key, _ defaultValue: () -> Value) -> Value {
        if let stored = self[key] { return stored }
        else {
            let newValue = defaultValue()
            self[key] = newValue
            return newValue
        }
    }
    @inlinable mutating func getOrElse(_ key: Key, _ defaultValue: () -> Value) -> Value {
        if let stored = self[key] { return stored } else { return defaultValue() }
    }
    @inlinable func containsKey(_ key: Key) -> Bool { self.keys.contains(key) }
}

extension Set {
    static func += (left: inout Set<Element>, right: Element) { left.insert(right) }
    static func -= (left: inout Set<Element>, right: Element) { left.remove(right) }
}

extension Array {
    static func += (left: inout Array<Element>, right: Element) { left.append(right) }
    init(_ size: Int, _ initValue: ((Int) -> Element)) {
        self = [Element]()
        for index in 0 ..< size {
            let value = initValue(index)
            self.append(value)
        }
    }
    init(_ size: Int, _ initValue: (() -> Element)) {
        self = [Element]()
        for _ in 0 ..< size {
            let value = initValue()
            self.append(value)
        }
    }
}
typealias IntArray = Array<Int>
typealias DoubleArray = Array<Double>
typealias BoolArray = Array<Bool>
typealias StringArray = Array<String>

extension Array where Element == Int {
    init(_ size: Int) {
        self = [Element](repeating: 0, count: size)
    }
}
extension Array where Element == Double {
    init(_ size: Int) {
        self = [Element](repeating: 0.0, count: size)
    }
}
extension Array where Element == Bool {
    init(_ size: Int) {
        self = [Element](repeating: false, count: size)
    }
}
extension Array where Element == String {
    init(_ size: Int) {
        self = [Element](repeating: "", count: size)
    }
}

extension Array {
    @inlinable func count(_ predicate: ((Element) -> Bool)) -> Int {
        var cnt = 0; for e in self { if (predicate(e)) { cnt += 1 } }
        return cnt
    }
    @inlinable func groupBy<K>(_ keySelector: (Element) -> K) -> [K : [Element]] {
        var destination = [K : [Element]]()
        for element in self {
            let key = keySelector(element)
            var list = destination.getOrSet(key) { [Element]() }
            list.append(element)
            destination[key] = list
        }
        return destination
    }
    @inlinable func groupByIndexed<K>(_ keySelector: (Element) -> K) -> [K : [Int]] {
        var destination = [K : [Int]]()
        for element in self.enumerated() {
            let key = keySelector(element.element)
            var list = destination.getOrSet(key) { [Int]() }
            list.append(element.offset)
            destination[key] = list
        }
        return destination
    }
}

extension Array {
    func binarySearch(_ element: Element, by compare: (Element, Element) -> Int, fromIndex: Int = 0, toIndex: Int = -1) -> Int {
        var low = fromIndex
        var high = (toIndex == -1) ? self.count - 1 : toIndex - 1
        while (low <= high) {
            let mid = (low + high) >> 1 // safe from overflows
            let midVal = self[mid]
            let cmp = compare(midVal, element)
            if (cmp < 0) { low = mid + 1 }          //-1
            else if (0 < cmp) { high = mid - 1 }    // 1
            else { return mid } // key found        // 0
        }
        return -(low + 1)  // key not found
    }
}
extension Array where Element : Comparable {
    func binarySearch(_ element: Element, fromIndex: Int = 0, toIndex: Int = -1) -> Int {
        var low = fromIndex
        var high = (toIndex == -1) ? self.count - 1 : toIndex - 1
        while (low <= high) {
            let mid = (low + high) >> 1 // safe from overflows
            let midVal = self[mid]
            if (midVal < element) { low = mid + 1 }
            else if (midVal > element) { high = mid - 1 }
            else { return mid } // key found
        }
        return -(low + 1)  // key not found
    }
}

extension Array where Element == Int {
    @inlinable func distinct() -> [Element] {
        var set = Set<Element>(), ary = [Element]()
        for n in self.indices { if !set.contains(self[n]) { ary.append(self[n]); set.insert(self[n]) } }
        return ary
    }
    @inlinable func any(_ predicate: (Element) -> Bool) -> Bool {
        var any = false; for element in self { if predicate(element) { any = true } }
        return any
    }
    @inlinable func all(_ predicate: (Element) -> Bool) -> Bool {
        self.allSatisfy(predicate)
    }
    @inlinable func sum() -> Element { self.reduce(0, +) }
    @inlinable func sum(by predicate: (Element) -> Element) -> Element {
        var sum = 0; for e in self { sum += predicate(e) }
        return sum
    }
    @inlinable func joinToString(_ sepatator: String = " ") -> String { self.map { String($0) }.joined(separator: sepatator) }
}

extension Array where Element == Double {
    @inlinable func sum() -> Element { self.reduce(0.0, +) }
    @inlinable func sum(by predicate: (Element) -> Element) -> Element {
        var sum = 0.0; for e in self { sum += predicate(e) }
        return sum
    }
    @inlinable func joinToString(_ sepatator: String = " ") -> String { self.map { String($0) }.joined(separator: sepatator) }
}
extension Array where Element == String {
    @inlinable func toIntDouble() -> (Int, Double) { (Int(self[0])!, Double(self[1])!) }
    @inlinable func toIntString() -> (Int, String) { (Int(self[0])!, self[1]) }
    @inlinable func toIntIntString() -> (Int, Int, String) { (Int(self[0])!, Int(self[1])!, self[2]) }
}

@inlinable func block( _ action: () -> Void) {
    action()
}
@inlinable func repeate(_ times1: Int, _ action: () -> Void) {
    for _ in 0 ..< times1 { action() }
}
@inlinable func repeate(_ times1: Int, _ action: (Int) -> Void) {
    for index1 in 0 ..< times1 {
        action(index1)
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ action: (Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            action(index1, index2)
        }
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ times3: Int, _ action: (Int, Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            for index3 in 0 ..< times3 {
                action(index1, index2, index3)
            }
        }
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ times3: Int, _ times4: Int, _ action: (Int, Int, Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            for index3 in 0 ..< times3 {
                for index4 in 0 ..< times4 {
                    action(index1, index2, index3, index4)
                }
            }
        }
    }
}

func measureTimeSeconds(block: (() -> Void)) -> Double {
    let startTime = Date()
    block()
    let duration = -startTime.timeIntervalSinceNow
    return duration
}


func main(input1: String = readLine()!, input2: String = readLine()!) {
    let integers = input2.split(separator: " ").map { Int($0)! }

    let mod = 1000000007
    var summary = 0
    for i in integers {
        summary += i
        summary %= mod
    }
    var result = 0
    for i in integers {
        summary -= i
        if summary < 0 {
            summary += mod
        }
        result += i * summary
        result %= mod
    }
    print(result)
}

main()


let N = Int(readLine()!)!
let AN = readLine()!.split(separator: " ").compactMap { Int($0) }
let mod = 1000000007

var sumAN = AN.reduce(0) { ($0 + $1) % mod }
var sumList: [Int] = []
for i in 0..<N {
    sumAN -= AN[i]
    sumList.append(sumAN)
}

var result = 0
for i in 0..<N {
    result += AN[i] * sumList[i]
    result %= mod
}
print(result)


let N = Int(readLine()!)!
let AN = readLine()!.split(separator: " ").compactMap { Int($0) }
let mod = 1000000007

var sumAN = AN.reduce(0) { $0 + $1 }
var sumList: [Int] = []
for i in 0..<N {
    sumAN -= AN[i]
    sumList.append(sumAN)
}

var result = 0
for i in 0..<N {
    result += AN[i] * sumList[i]
    result %= mod
}
print(result)


import Foundation

let N = Int(readLine()!)!
let AN = readLine()!.split(separator: " ").compactMap { Int($0) }

var sumAN = AN.reduce(0) { $0 + $1 }
var sumList: [Int] = []
for i in 0..<N {
    sumAN -= AN[i]
    sumList.append(sumAN)
}

var result = 0
for i in 0..<N-1 {
    result += AN[i] * sumList[i]
    result %= Int(pow(10.0, 9)) + 7
}
print(result)


import * as fs from 'fs';

const M = 10 ** 9 + 7;
const Mb = BigInt(M);

function modX(num: number) {
  return num % M;
}

function modX2(num1: number, num2: number) {
  return Number((BigInt(num1) * BigInt(num2)) % Mb);
}

function main(input) {
  input = input.split("\n");
  const N = parseInt(input[0]);
  const AList = input[1].split(' ').map(i => parseInt(i));
  let ans = 0;
  let sum = 0;
  for (let i = 1; i < N; i++) {
    sum += AList[i - 1];
    sum = modX(sum);
    ans += modX2(AList[i], sum);
    ans = modX(ans);
  }
  console.log('%s', ans);
}

main(fs.readFileSync("/dev/stdin", "utf8"));


// @ts-ignore
import * as fs from 'fs';

// メイン
function main(input: string[]) {
    const n: number = +input[0];
    const a: bigint[] = input[1].split(" ").map(x => BigInt(x));
    const m:bigint = BigInt(Math.pow(10, 9) + 7);
    var p:bigint = BigInt(0);
    var s:bigint = BigInt(0);
    for (var i = 0; i < a.length; i++) {
        console.debug("i=", i, "p=", p, "s=", s);
        p = (p + a[i] * s) % m;
        s = (s + a[i]) % m;
    }
    var x = Number(p);
    console.log(x);
}

// エントリポイント
// - OSによるパラメタの処理の違いを吸収
function entrypoint() {
    try {
        var input = fs.readFileSync("/dev/stdin", "utf8").split("\n");
        console.debug = function () { };
        main(input);
    }
    catch (ex) {
        console.log("----");
        console.log("file='%s'", __filename.split("\\").slice(-1)[0]);
        console.log("----");
        const lines: string[] = [];
        // @ts-ignore
        const reader = require('readline').createInterface({
            // @ts-ignore
            input: process.stdin,
            // @ts-ignore
            output: process.stdout
        });
        reader.on('line', function (line: string) {
            lines.push(line);
        });
        reader.on('close', function () {
            input = lines;
            console.log("input=%o", input);
            console.time();
            console.log("----")
            main(input);
            console.log("----")
            console.timeEnd();
        });
    }
}
entrypoint();


import * as fs from 'fs';

const input = fs.readFileSync('/dev/stdin', 'utf8');
// const input = fs.readFileSync('./input.txt', 'utf8');
const L = BigInt(10 ** 9 + 7);

_c(input);

function _c(input: string) {
  const [_N, _A] = input.split('\n');
  const A = _A.split(' ').map((s) => BigInt(s));
  // console.log(A);

  const sumFor: bigint[] = [];
  sumFor[A.length - 1] = A[A.length - 1];
  for (let i = A.length - 2; i > 0; i--) {
    sumFor[i] = A[i] + sumFor[i + 1];
  }
  // console.log(sumFor);

  let sum = 0n;
  for (let i = 0; i < A.length - 1; i++) {
    sum = (sum + A[i] * sumFor[i + 1]) % L;
  }

  console.log(sum.toString());
}


var main = (input: string) => {
    let t: string[] = input.split("\n");
    const n: number = parseInt(t[0]);
    const a: number[] = t[1].split(" ").map(e => parseInt(e, 10));

    const mod: number = 1_000_000_007;
    let count: number = 0;
    for (let i: number = 0; i < n - 1; i++) {
        let sum = 0;
        for (let j: number = i + 1; j < n; j++) {
            sum += a[j];
        }
        count = (count + a[i] * sum) % mod;
    }
    console.log(count);
}

main(require("fs").readFileSync("/dev/stdin", "utf8"));


var main = (input: string) => {
    let t: string[] = input.split("\n");
    const n: number = parseInt(t[0]);
    const a: number[] = t[1].split(" ").map(e => parseInt(e, 10));

    const mod: number = 1_000_000_007;
    let count: number = 0;
    for (let i: number = 0; i < n - 1; i++) {
        for (let j: number = i + 1; j < n; j++) {
            count = (count + a[i] * a[j]) % mod;
        }
    }
    console.log(count);
}

main(require("fs").readFileSync("/dev/stdin", "utf8"));


// @ts-ignore
import * as fs from 'fs';

// メイン
function main(input: string[]) {
    const n: number = +input[0];
    const a: number[] = input[1].split(" ").map(x => +x);
    const m = Math.pow(10, 9) + 7;
    var p = 0;
    var s = 0;
    for (var i = 0; i < a.length; i++) {
        console.debug("i=", i, "p=", p, "s=", s);
        p = (p + a[i] * s) % m;
        s = (s + a[i]) % m;
    }
    console.log(p);
}

// エントリポイント
// - OSによるパラメタの処理の違いを吸収
function entrypoint() {
    try {
        var input = fs.readFileSync("/dev/stdin", "utf8").split("\n");
        console.debug = function () { };
        main(input);
    }
    catch (ex) {
        console.log("----");
        console.log("file='%s'", __filename.split("\\").slice(-1)[0]);
        console.log("----");
        const lines: string[] = [];
        // @ts-ignore
        const reader = require('readline').createInterface({
            // @ts-ignore
            input: process.stdin,
            // @ts-ignore
            output: process.stdout
        });
        reader.on('line', function (line: string) {
            lines.push(line);
        });
        reader.on('close', function () {
            input = lines;
            console.log("input=%o", input);
            console.time();
            console.log("----")
            main(input);
            console.log("----")
            console.timeEnd();
        });
    }
}
entrypoint();


a,b,c,d = map(int, input().split())
Al = list(range(a,b))
Bo = list(range(c,d))
print(len(set(Al) & set(Bo)))


a, b, c, d = map(int, input().split())
print(max(0, min(b, d) - max(a, c) ))


a,b,c,d = map(int,input().split())
if a <= c <= b <= d:
    print(b - c)
elif c <= a <= d <= b:
    print(d - a)
elif a <= c <= d <= b:
    print(d - c)
elif c <= a <= b <= d:
    print(b - a)
else:
#elif b <= c or d <= a:
    print(0)


A, B, C, D = map(int, input().split())

M1 = max(A, C)
M2 = min(B, D)

if B >= C:
    print(M2 - M1)

else:
    print(0)


A, B, C, D = map(int, input().split())

M1 = max(A, C)
M2 = min(B, D)

if B > C:
    print(abs(M1 - M2))

else:
    print(0)


A, B, C, D = map(int, input().split())

if A<=C and D<=B: print(D-C)

if C<=A and B<=D: print(B-A)

if (A<=C and C<= B and B<=D): print(B-C)

if C<=A and A<=D and D<=B: print(D-A)

if B<=C or D<=A: print(0)


import java.io.*;
import java.util.*;
import static java.lang.Math.*;

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

    public void solve(String[] args) {
        MyScanner scanner = new MyScanner();
        int A = scanner.nextInt();
        int B = scanner.nextInt();
        int C = scanner.nextInt();
        int D = scanner.nextInt();
        boolean a = false;
        boolean b = false;
        int ans = 0;
        for (int i = 0; i <= 100; i++) {
            if (i == A) {
                a = true;
            }
            if (i == B) {
                a = false;
            }
            if (i == C) {
                b = true;
            }
            if (i == D) {
                b = false;
            }
            if (a && b) {
                ans++;
            }
        }
        System.out.println(ans);
    }

    private class MyScanner {
        String[] s;
        int i;
        BufferedReader br;
        String reg = " ";

        MyScanner () {
            s = new String[0];
            i = 0;
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public String next() {
            try {
                if (i < s.length) return s[i++];
                String line = br.readLine();
                while (line.equals("")) {
                    line = br.readLine();
                }
                s = line.split(reg, 0);
                i = 0;
                return s[i++];
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        public int nextInt() {
            try {
                return Integer.parseInt(next());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return -1;
        }

        public double nextDouble() {
            try {
                return Double.parseDouble(next());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return -1;
        }

        public long nextLong()  {
            try {
                return Long.parseLong(next());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return -1;
        }
    }
}


import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.BigDecimal;

public class Main{
    public static void main (String[] args) throws java.lang.Exception {
        InputReader in = new InputReader(System.in);
        PrintWriter w = new PrintWriter(System.out);

        int a = in.nextInt(), b = in.nextInt(), c = in.nextInt(), d = in.nextInt();
        if (d <= a || c >= b)
            w.println(0);
        else
            w.println(Math.min(d, b) - Math.max(a, c));

        w.close();
    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1)
                throw new UnknownError();
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new UnknownError();
                }
                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public int peek() {
            if (numChars == -1)
                return -1;
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    return -1;
                }
                if (numChars <= 0)
                    return -1;
            }
            return buf[curChar];
        }

        public void skip(int x) {
            while (x-- > 0)
                read();
        }

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

        public long nextLong() {
            return Long.parseLong(next());
        }

        public String nextString() {
            return next();
        }

        public String next() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuffer res = new StringBuffer();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));

            return res.toString();
        }

        public String nextLine() {
            StringBuffer buf = new StringBuffer();
            int c = read();
            while (c != '\n' && c != -1) {
                if (c != '\r')
                    buf.appendCodePoint(c);
                c = read();
            }
            return buf.toString();
        }

        public double nextDouble() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            double res = 0;
            while (!isSpaceChar(c) && c != '.') {
                if (c == 'e' || c == 'E')
                    return res * Math.pow(10, nextInt());
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            if (c == '.') {
                c = read();
                double m = 1;
                while (!isSpaceChar(c)) {
                    if (c == 'e' || c == 'E')
                        return res * Math.pow(10, nextInt());
                    if (c < '0' || c > '9')
                        throw new InputMismatchException();
                    m /= 10;
                    res += (c - '0') * m;
                    c = read();
                }
            }
            return res * sgn;
        }
        public int[] nextIntArray(int n) {
            int[] a = new int[n];
            for (int i = 0; i < n; i++)
                a[i] = nextInt();
            return a;
        }
        public long[] nextLongArray(int n) {
            long[] a = new long[n];
            for (int i = 0; i < n; i++)
                a[i] = nextLong();
            return a;
        }
        public boolean hasNext() {
            int value;
            while (isSpaceChar(value = peek()) && value != -1)
                read();
            return value != -1;
        }

        private boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

    }
}


import java.io.*;
import java.util.*;
import java.math.*;
import java.util.concurrent.*;

class Main
{
    static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
	static FastScanner sc=new FastScanner(br);
    static PrintWriter out=new PrintWriter(System.out);
	static Random rnd=new Random();

    public static void main(String args[]) throws Exception
    {
		int[] cnt=new int[105];

		int l1=sc.nextInt(),r1=sc.nextInt();

		for(int i=l1+1;i<=r1;i++)
		{
			cnt[i]++;
		}

		int l2=sc.nextInt(),r2=sc.nextInt(),res=0;

		for(int i=l2+1;i<=r2;i++)
		{
			if(cnt[i]>0)
			{
				res++;
			}
		}

		out.println(res);out.close();
    }
}
class FastScanner
{
    BufferedReader in;
    StringTokenizer st;

    public FastScanner(BufferedReader in) {
        this.in = in;
    }

    public String nextToken() throws Exception {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

	public String next() throws Exception {
		return nextToken().toString();
	}

    public int nextInt() throws Exception {
        return Integer.parseInt(nextToken());
    }

    public long nextLong() throws Exception {
        return Long.parseLong(nextToken());
    }

    public double nextDouble() throws Exception {
        return Double.parseDouble(nextToken());
    }
}


import java.util.*; import java.io.*; import java.math.*;
public class Main{
	//Don't have to see. start------------------------------------------
	static class InputIterator{
		ArrayList<String> inputLine = new ArrayList<String>(1024);
		int index = 0; int max; String read;
		InputIterator(){
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			try{
				while((read = br.readLine()) != null){
					inputLine.add(read);
				}
			}catch(IOException e){}
			max = inputLine.size();
		}
		boolean hasNext(){return (index < max);}
		String next(){
			if(hasNext()){
				return inputLine.get(index++);
			}else{
				throw new IndexOutOfBoundsException("There is no more input");
			}
		}
	}
	static HashMap<Integer, String> CONVSTR = new HashMap<Integer, String>();
	static InputIterator ii = new InputIterator();//This class cannot be used in reactive problem.
	static PrintWriter out = new PrintWriter(System.out);
	static void flush(){out.flush();}
	static void myout(Object t){out.println(t);}
	static void myerr(Object t){System.err.print("debug:");System.err.println(t);}
	static String next(){return ii.next();}
	static boolean hasNext(){return ii.hasNext();}
	static int nextInt(){return Integer.parseInt(next());}
	static long nextLong(){return Long.parseLong(next());}
	static double nextDouble(){return Double.parseDouble(next());}
	static ArrayList<String> nextStrArray(){return myconv(next(), 8);}
	static ArrayList<String> nextCharArray(){return myconv(next(), 0);}
	static ArrayList<Integer> nextIntArray(){
		ArrayList<String> input = nextStrArray(); ArrayList<Integer> ret = new ArrayList<Integer>(input.size());
		for(int i = 0; i < input.size(); i++){
			ret.add(Integer.parseInt(input.get(i)));
		}
		return ret;
	}
	static ArrayList<Long> nextLongArray(){
		ArrayList<String> input = nextStrArray(); ArrayList<Long> ret = new ArrayList<Long>(input.size());
		for(int i = 0; i < input.size(); i++){
			ret.add(Long.parseLong(input.get(i)));
		}
		return ret;
	}
	static String myconv(Object list, int no){//only join
		String joinString = CONVSTR.get(no);
		if(list instanceof String[]){
			return String.join(joinString, (String[])list);
		}else if(list instanceof ArrayList){
			return String.join(joinString, (ArrayList)list);
		}else{
			throw new ClassCastException("Don't join");
		}
	}
	static ArrayList<String> myconv(String str, int no){//only split
		String splitString = CONVSTR.get(no);
		return new ArrayList<String>(Arrays.asList(str.split(splitString)));
	}
	public static void main(String[] args){
		CONVSTR.put(8, " "); CONVSTR.put(9, "\n"); CONVSTR.put(0, "");
		solve();flush();
	}
	//Don't have to see. end------------------------------------------
	static void solve(){//Here is the main function
		ArrayList<Integer> one = nextIntArray();
      int A = one.get(0);
      int B = one.get(1);
      int C = one.get(2);
      int D = one.get(3);
      int[] list = new int[101];
      for(int i = A; i <= B; i++){
        list[i]++;
      }
      for(int i = C; i <= D; i++){
        list[i]++;
      }
      int output = 0;
      for(int i = 0; i < 101; i++){
        if(list[i] == 2){
          output++;
        }
      }
      myout(Math.max(output - 1), 0);
	}
	//Method addition frame start

	//Method addition frame end
}


package practice;

import java.util.*;

public class AC70B {
	public static void main (String[] args)
	{
		Scanner in = new Scanner (System.in);
		int[] A= new int[2];
		int[] B  = new int[2];
		int max_low=0;
		int min_high=0;

		for(int i=0; i<2; i++)
		{
			A[i]=in.nextInt();
		}
		for(int i=0; i<2; i++)
		{
			B[i]=in.nextInt();
		}

		max_low=Math.max(A[0],B[0]);
		min_high= Math.min(A[1],B[1]);

		if (max_low>min_high)
			System.out.println("0");

		else
			System.out.println(min_high-max_low);

	}
}


import java.util.*;

public class AC70B {
	public static void main (String[] args)
	{
		Scanner in = new Scanner (System.in);
		int[] A= new int[2];
		int[] B  = new int[2];
		int max_low=0;
		int min_high=0;

		for(int i=0; i<2; i++)
		{
			A[i]=in.nextInt();
		}
		for(int i=0; i<2; i++)
		{
			B[i]=in.nextInt();
		}

		max_low=Math.max(A[0],B[0]);
		min_high= Math.min(A[1],B[1]);

		if (max_low>min_high)
			System.out.println("0");

		else
			System.out.println(min_high-max_low);

	}
}


#include <cstdio>

int main() {
  int a, b, c, d;
  scanf("%d%d%d%d", &a, &b, &c, &d);
  if(c > a)
    a = c;
  if(d < b)
    b = d;
  if(a < b)
    printf("%d", b - a);
  else
    printf("0");
  return 0;
}


#include <cstdio>
#include <algorithm>

using namespace std;

inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
	return x*f;
}

int main()
{
	int a,b,c,d;
	a=read(); b=read(); c=read(); d=read();
	a=max(a,c); b=min(b,d);
	printf("%d\n",max(0,b-a));
	return 0;
}


#include <cstdio>
#include <algorithm>
int main() {
    int a, b, c, d;
    scanf("%d %d %d %d", &a, &b, &c, &d);
    if(a > c) std::swap(a,c), std::swap(b, d);
    int len;
    if(d > b) len = (b - c > 0) ? (b-c) : 0;
    else len = d - c;
    printf("%d", len);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

int main(){
  int a,b,c,d,time;
  cin >>a>>b>>c>>d;
  if(a>=d||b<=c){
    time=0;
  }else if(a<=b){
    time=(int)min(c-b,d-b);
  }else{
    time=(int)min(c-a,d-a);
  }
  cout << time << endl;
}


#include<bits/stdc++.h>
using namespace std;

int main(){
  int a,b,c,d,time;
  cin >>a>>b>>c>>d;
  if(a>=d||b<=c){time=0;
  }else if(a<=b){
    time=min(c-b,d-b);
  }else{
    time=min(c-a,d-a);
  }
  cout << time << endl;
}


#include<bits/stdc++.h>
using namespace std;

int main(){
  int a,b,c,d,time;
  cin >>a>>b>>c>>d;
  if(a>=d||b<=c){time=0;}
  else if(a<=b){
    time=min(c-b,d-b);
  }else{
    time=min(c-a,c-b);
  }
  cout << time << endl;
}


#include <stdio.h>

int main(void){
    int A,B,C,D;
    scanf("%d %d %d %d",&A,&B,&C,&D);
    if(A<=D&&C<=B){
        int po1;
        if(A>C)po1=A;
        else po1=C;
        int po2;
        if(B<D)po2=B;
        else po2=D;
        printf("%d",po2-po1);
    }
    else printf("0");
    return 0;
}


#include<stdio.h>
int main(){
    int a,b,c,d;
    int s[100];
    int t[100];
    int count=0;
    scanf("%d %d %d %d",&a,&b,&c,&d);
    for(int i=0;i<100;i++){
        if((a<=i)&&(i<b)){
            s[i]=1;
        }else{
            s[i]=0;
        }
    }
    for(int i=0;i<100;i++){
        if((c<=i)&&(i<d)){
            t[i]=1;
        }else{
            t[i]=0;
        }
    }
    for(int i=0;i<100;i++){
            if((s[i]==1)&&(t[i]==1)){
                count=count+1;
            }else{

            }
    }
    printf("%d\n",count);
}


#include <stdio.h>

int main()
{
int a, b, c, d;
int t;

scanf("%d%d%d%d",&a,&b, &c, &d);

if(b <= c || d <=a ){
  t = 0;
}
else {
  if(a <=c){
    if(b <=d){
      t = b - c;
    }
    else{
      t = d-c;
    }
  }
  else{
    if(b <=d){
      t = b - a;
    }
    else{
      t = d-a;
    }
  }
}

  printf("%d\n", t);

return 0;
}


#include <stdio.h>
#include <string.h>
#pragma warning(disable : 4996)

int main()
{
    int A, B, C, D;
    int i;
    int a[100] = {0};
    int b[100] = {0};
    int c[100] = { 0 };
    int time = 0;

    scanf("%d %d %d %d", &A, &B, &C, &D);

    for (i = A; i <= B; i++) {
        a[i] = 1;
    }

    for (i = C; i <= D; i++) {
        b[i] = 1;
    }

    for (i = 0; i < 100; i++) {
        c[i] = a[i] + b[i];
        if (c[i] == 2)
            time++;
    }

    if (time == 0)
        printf("%d", time);
    else
    printf("%d", time-1);

    return 0;
}


#include<stdio.h>

int min(int a,int b)
{

   if(a>b)return b;
   else return a;
}
int max(int a, int b)
{
    if(a>b)return a;
    else return b;
}

int main()
{
    int a,b,c,d,e,f;
    int ans=0;

    scanf("%d %d %d %d",&a,&b,&c,&d);

    if(b<c)
    {
        ans=0;
    }
    else if(b>=c)
    {
       e=min(b,d);
       f=max(a,c);
       ans=e-f;
    }
    printf("%d\n",ans);

    return 0;
}


#include<stdio.h>

int min(int a,int b)
{

   if(a>b)return b;
   else return a;
}
int max(int a, int b)
{
    if(a>b)return a;
    else return b;
}

int main()
{
    int a,b,c,d,e,f;
    int ans=0;

    scanf("%d %d %d %d",&a,&b,&c,&d);

    if(b<=c)
    {
        ans=0;
    }
    else if(b>c)
    {
       e=min(b,d);
       f=max(a,c);
       ans=e-f;
    }
    printf("%d\n",ans);

    return 0;
}


function Main(inp) {
    var input = inp.split('\n')[0].split(' ').map(function(n) {
        return Number(n);
    });
    var count = 0;
    for(var i = 0; i <= 100; i++) {
        var onA = false, onB = false;
        if (input[0] <= i && i < input[1]) {
            onA = true;
        }
        if (input[2] <= i && i < input[3]) {
            onB = true;
        }
        if (onA && onB) {
            count += 1;
        }
    }
    console.log(count);
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));


function Main(input) {
	var input = input.split(" ");
  	input = input.map(function (element) { return Number(element); });
  	var n=0;
	for(i=input[0];i<=input[1];i++){
      if(i>=input[2]&&i<=input[3]){
        n++;
      }
    }
	if(n!==0){
	  n--;
  	}
      console.log(n);
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));


function Main(input){
    input = input.split(" ");

    input[0] = parseInt(input[0], 10);
    input[1] = parseInt(input[1], 10);
    input[2] = parseInt(input[2], 10);
    input[3] = parseInt(input[3], 10);

    if(input[2] >= input[1]){
        console.log(0);
    }else if(input[3] <= input[0]){
        console.log(0);
    }else{
        if(input[0] < input[2]){
            var start = input[2]
        }else{
            var start = input[0]
        }

        if(input[1] < input[3]){
            var end = input[1]
        }else{
            var end = input[3]
        }

        console.log('%d', end - start);
    }
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));


'use strict';
function Main(stdin){
  const [A, B, C, D] = stdin.trim().split(' ').map(str => Number(str));

  let start =  A < C ? C : A;
  let end = B < D ? B : D;
  let result = end < start ? 0 : end - start;
  console.log(result);
}

// 固定
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


'use strict'

function main(input) {
  const inputList = input.split(' ');
  const [a, b, c, d] = inputList.map(input => Number(input))

  const left = Math.max(a, c)
  const right = Math.min(b, d)

  if (left > right) {
    console.log(String(0))
  } else {
    console.log(String(right-left))
  }
}

main(require("fs").readFileSync("/dev/stdin", "utf8"));


'use strict'

function main(input) {
  const inputList = input.split(' ');
  const [a, b, c, d] = inputList.map(input => Number(input))

  const left = Math.max(a, c)
  const right = Math.min(b, d)

  if (left > right) {
    console.log(0)
  } else {
    console.log(right-left)
  }
}

main(require("fs").readFileSync("/dev/stdin", "utf8"));


package main

import (
	"bufio"
	"container/heap"
	"fmt"
	"math"
	"os"
	"strconv"
)

const (
	initialBufSize = 10000
	maxBufSize     = 1000000
	mod            = 1e9 + 7
)

var (
	sc *bufio.Scanner = func() *bufio.Scanner {
		sc := bufio.NewScanner(os.Stdin)
		buf := make([]byte, initialBufSize)
		sc.Buffer(buf, maxBufSize)
		sc.Split(bufio.ScanWords)
		return sc
	}()
)

func main() {
	A := getInt()
	B := getInt()
	C := getInt()
	D := getInt()

	diff := min(B, D) - max(A, C)
	fmt.Println(max(0, diff))
}

type Graph struct {
	n     int
	edges [][]int
}

func NewGraph(n int) *Graph {
	g := &Graph{
		n:     n,
		edges: make([][]int, n),
	}
	return g
}

func (g *Graph) AddEdge(u, v int) {
	g.edges[v] = append(g.edges[v], u)
	g.edges[u] = append(g.edges[u], v)
}

func dfs(c int, edges [][]int, visited map[int]struct{}) {
	visited[c] = struct{}{}

	for _, v := range edges[c] {
		_, flag := visited[v]
		if flag {
			continue
		}
		dfs(v, edges, visited)
	}
}

func bfs(c int, graph *Graph) {
	next := make([]int, 0)
	next = append(next, c)
	visited := make(map[int]struct{})

	for ; len(next) != 0; {
		u := next[0]
		next = next[1:]
		visited[u] = struct{}{}

		for _, v := range graph.edges[u] {
			_, flag := visited[v]
			if flag {
				continue
			}

			// なにか処理

			next = append(next, v)
		}
	}
}

func getInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func getIntArray(n int) []int {
	array := make([]int, n)
	for i := 0; i < n; i++ {
		array[i] = getInt()
	}
	return array
}

func getString() string {
	sc.Scan()
	return sc.Text()
}

func getStringArray(n int) []string {
	array := make([]string, n)
	for i := 0; i < n; i++ {
		array[i] = getString()
	}
	return array
}

func abs(a int) int {
	return int(math.Abs(float64(a)))
}

func pow(p, q int) int {
	return int(math.Pow(float64(p), float64(q)))
}

func powMod(n, p int) int {
	if p == 0 {
		return 1
	} else if p%2 == 0 {
		t := powMod(n, p/2)
		return calcMod(t * t)
	} else {
		return calcMod(n * powMod(n, p-1))
	}
}

func min(nums ...int) int {
	if len(nums) == 0 {
		panic("funciton min() requires at least one argument.")
	}
	res := nums[0]
	for i := 0; i < len(nums); i++ {
		res = int(math.Min(float64(res), float64(nums[i])))
	}
	return res
}

func max(nums ...int) int {
	if len(nums) == 0 {
		panic("funciton max() requires at least one argument.")
	}
	res := nums[0]
	for i := 0; i < len(nums); i++ {
		res = int(math.Max(float64(res), float64(nums[i])))
	}
	return res
}

func strSearch(a []string, b string) bool {
	for i := 0; i < len(a); i++ {
		if a[i] == b {
			return true
		}
	}
	return false
}

func printIntArray(array []int) {
	strArray := fmt.Sprint(array)
	fmt.Println(strArray[1 : len(strArray)-1])
}

func calcMod(x int) int {
	return x % mod
}

func reverse(s string) string {
	runes := []rune(s)
	for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
	return string(runes)
}

func isPrime(n int) bool {
	if n < 2 {
		return false
	} else if n == 2 {
		return true
	} else if n % 2 == 0 {
		return false
	}

	sqrtN := int(math.Sqrt(float64(n)))
	for i := 3; i <= sqrtN; i += 2 {
		if n % i == 0 {
			return false
		}
	}

	return true
}

func contains(s []int, e int) bool {
	for _, v := range s {
		if e == v {
			return true
		}
	}
	return false
}

func makeRange(min, max int) []int {
	a := make([]int, max-min+1)
	for i := range a {
		a[i] = min + i
	}
	return a
}

func powerset2(nums []int) [][]int {
	length := int(math.Pow(2, float64(len(nums))))
	result := make([][]int, length)

	index := 0
	result[index] = []int{}
	index++

	for _, n := range nums {
		max := index
		for i := 0; i < max; i++ {
			result[index] = copyAndAppend(result[i], n)
			index++
		}
	}

	return result
}

func copyAndAppend(nums []int, n int) []int {
	dst := make([]int, len(nums)+1)
	copy(dst, nums)
	dst[len(nums)] = n
	return dst
}

func calcGcd(x, y int) int {
	if y == 0 {
		return x
	} else if x >= y {
		return calcGcd(y, x % y)
	} else {
		return calcGcd(x, y % x)
	}
}

func getDivisor(n int) []int {
	var divisor []int
	divisor = append(divisor, 1)
	if n != 1 {
		divisor = append(divisor, n)
	}

	sqrt := int(math.Sqrt(float64(n)))
	for i := 2; i <= sqrt; i++ {
		if n % i == 0 {
			divisor = append(divisor, i)
			divisor = append(divisor, n/i)
		}
	}
	return divisor
}

type intHeap []int

func (h intHeap) Len() int {
	return len(h)
}

func (h intHeap) Less(i, j int) bool {
	return h[i] > h[j]
}

func (h intHeap) Swap(i, j int) {
	h[i], h[j] = h[j], h[i]
}

func (h *intHeap) Push(x interface{}) {
	*h = append(*h, x.(int))
}

func (h *intHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}

func initHeap() *intHeap {
	ih := &intHeap{}
	heap.Init(ih)
	return ih
}

func (h *intHeap) pushHeap(n int) {
	heap.Push(h, n)
}

func (h *intHeap) popHeap() int {
	return heap.Pop(h).(int)
}

func factMod(n int) int {
	value := 1
	for ; n > 1; n-- {
		value = calcMod(value * n)
	}
	return value
}

func combinationMod(n, k int) int {
	factN := factMod(n)
	factK := factMod(k)
	factNK := factMod(n - k)
	factKR := powMod(factK, mod - 2)
	factNKR := powMod(factNK, mod - 2)
	return calcMod(factN * calcMod(factKR * factNKR))
}


package main

import (
  "fmt"
)

func maxInt(a ...int) int {m := a[0]; for _, x := range a {if x > m {m = x}}; return m}
func minInt(a ...int) int {m := a[0]; for _, x := range a {if x < m {m = x}}; return m}

func main() {
  var a, b, c, d int
  fmt.Scan(&a, &b, &c, &d)
  res := maxInt(0, minInt(b, d) - maxInt(a, c))
  fmt.Println(res)
}


package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"reflect"
	"sort"
	"strconv"
	"strings"
	// "regexp"
)

/* sort */
type pair struct {
	index  int64
	p1, p2 interface{}
}
type pairs []pair

func (slice pairs) Len() int {
	return len(slice)
}

func (slice pairs) Less(i, j int) bool {
	return slice[i].index < slice[j].index
}

func (slice pairs) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}

/* sort */
type Int64Slice []int64

func (slice Int64Slice) Len() int {
	return len(slice)
}

func (slice Int64Slice) Less(i, j int) bool {
	return slice[i] < slice[j]
}

func (slice Int64Slice) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}
func Int64s(a []int64)                    { sort.Sort(Int64Slice(a)) }
func Int64sSliceAreSorted(a []int64) bool { return sort.IsSorted(Int64Slice(a)) }

const (
	initialBufSize = 1e4
	maxBufSize     = 1e8
	INF            = 1e8
)

var (
	scanner = bufio.NewScanner(os.Stdin)
	writer  = bufio.NewWriter(os.Stdout)
	di      = []int64{-1, 0, 1, 0}
	dj      = []int64{0, -1, 0, 1}
)

func main() {
	buf := make([]byte, initialBufSize)
	scanner.Buffer(buf, maxBufSize)
	scanner.Split(bufio.ScanWords)
	A, B, C, D := readInt(), readInt(), readInt(), readInt()
	ans := int64(0)
	if C > B || A > D {
		fmt.Println(0)
	} else {
		ans = B - C
		if B > D {
			ans -= B - D
		}
		if A > C {
			ans -= A - C
		}
		fmt.Println(ans)
	}
}

/*==========================================
 *             Library
 *==========================================*/
func NextPermutation(x sort.Interface) bool {
	n := x.Len() - 1
	if n < 1 {
		return false
	}
	j := n - 1
	for ; !x.Less(j, j+1); j-- {
		if j == 0 {
			return false
		}
	}
	l := n
	for !x.Less(j, l) {
		l--
	}
	x.Swap(j, l)
	for k, l := j+1, n; k < l; {
		x.Swap(k, l)
		k++
		l--
	}
	return true
}
func doubleAry(h int64, w int64, init int64) (res [][]int64) {
	res = make([][]int64, h)
	for i := int64(0); i < h; i++ {
		res[i] = make([]int64, w)
		for j := int64(0); j < w; j++ {
			res[i][j] = init
		}
	}
	return
}

func aryEq(a []int64, b []int64) bool {
	return reflect.DeepEqual(a, b)
}

func clone(n []int64) (r []int64) {
	r = make([]int64, len(n))
	for i := 0; i < len(n); i++ {
		r[i] = n[i]
	}
	return
}
func write(s string) {
	writer.WriteString(s)
}

func print() {
	writer.Flush()
}

// scanner.Split(bufio.ScanWords) をコメントアウトしないと使用不可
func readLine() (s string) {
	if scanner.Scan() {
		s = scanner.Text()
	}
	return s
}

func readInt() (read int64) {
	scanner.Scan()
	read, err := strconv.ParseInt(scanner.Text(), 10, 64)
	if err != nil {
		panic(err)
	}
	return
}

func readFloat() (read float64) {
	scanner.Scan()
	read, err := strconv.ParseFloat(scanner.Text(), 64)
	if err != nil {
		panic(err)
	}
	return
}

func readRunes() (read []rune) {
	scanner.Scan()
	for _, v := range scanner.Text() {
		read = append(read, v)
	}
	return
}

func readString() (read string) {
	scanner.Scan()
	read = scanner.Text()
	return
}

func readStrings() (read []string) {
	scanner.Scan()
	for _, v := range scanner.Text() {
		read = append(read, string(v))
	}
	return
}

func s2i(s string) int64 {
	var intVal, e = strconv.ParseInt(s, 10, 64)
	if e != nil {
		panic(e)
	}
	return intVal
}

func i2s(i int64) string {
	var strVal = strconv.FormatInt(i, 10)
	return strVal
}

func s2f(s string) float64 {
	var floatVal, e = strconv.ParseFloat(s, 64)
	if e != nil {
		panic(e)
	}
	return floatVal
}

func abs(i int64) int64 {
	return int64(math.Abs(float64(i)))
}

func max(a ...int64) int64 {
	ans := int64(0)
	for i, v := range a {
		if i == 0 {
			ans = v
		}
		if ans < v {
			ans = v
		}
	}
	return ans
}
func min(a ...int64) int64 {
	ans := int64(0)
	for i, v := range a {
		if i == 0 {
			ans = v
		}
		if ans > v {
			ans = v
		}
	}
	return ans
}

func sum(i []int64) int64 {
	sum := int64(0)
	for _, val := range i {
		sum += val
	}
	return sum
}

func split(s string) []string {
	return strings.Fields(s)
}

func strAry2intAry(strs []string) []int64 {
	var ret = make([]int64, 0, len(strs))
	for _, str := range strs {
		var intVal = s2i(str)
		ret = append(ret, intVal)
	}
	return ret
}

func intAry2strAry(nums []int64) []string {
	var ret = make([]string, 0, len(nums))
	for _, num := range nums {
		var strVal = i2s(num)
		ret = append(ret, strVal)
	}
	return ret
}

func ary2str(strs []string) string {
	return strings.Join(strs, " ")
}

func reverse(res []int64) []int64 {
	for i, j := 0, len(res)-1; i < j; i, j = i+1, j-1 {
		res[i], res[j] = res[j], res[i]
	}
	return res
}
func reverseStr(res []string) []string {
	for i, j := 0, len(res)-1; i < j; i, j = i+1, j-1 {
		res[i], res[j] = res[j], res[i]
	}
	return res
}

func ini(res []int, init int) {
	if len(res) == 0 {
		return
	}
	res[0] = init
	for i := 0; i < len(res); i++ {
		copy(res[i:], res[:i])
	}
}

//
// func regexpExample() {
//     // Your code here!
//     var str = "13:20"
//     r := regexp.MustCompile(`(\d+):(\d+)`)
//     fmt.Println(r.FindStringSubmatch(str))
// }

// type Country struct {
//     gold int
//     silver int
//     blonze int
// }

// // 複数ソートのサンプル
// func stableSortExample() []Country{
//     var country = []Country {
//         {gold:1, silver:2, blonze:3},
//         {gold:1, silver:2, blonze:3},
//         {gold:1, silver:3, blonze:2},
//         {gold:1, silver:3, blonze:3},
//     }
//     sort.SliceStable(country, func(i, j int) bool { return country[i].blonze > country[j].blonze })
//     sort.SliceStable(country, func(i, j int) bool { return country[i].silver > country[j].silver })
//     sort.SliceStable(country, func(i, j int) bool { return country[i].gold > country[j].gold })
//     return country
// }


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var sc = bufio.NewScanner((os.Stdin))

func nextLine() string {
	sc.Scan()
	return sc.Text()
}

func nextInt() int {
	l := nextLine()
	i, e := strconv.Atoi(l)
	if e != nil {
		panic(e)
	}
	return i
}

func main() {
	sc.Split(bufio.ScanWords)
	A, B, C, D := nextInt(), nextInt(), nextInt(), nextInt()

	fmt.Printf("%d\n", ABC070B(A, B, C, D))
}

// ABC070B ...
func ABC070B(A, B, C, D int) int {
	if B < C || D < A {
		return 0
	}

	if A < C && D < B {
		return D - C
	}
	if C < A && B < D {
		return B - A
	}

	if A < C {
		return B - C
	}

	return D - A
}


package main

import (
	"bufio"
	"container/heap"
	"fmt"
	"math"
	"os"
	"strconv"
)

const (
	initialBufSize = 10000
	maxBufSize     = 1000000
	mod            = 1e9 + 7
)

var (
	sc *bufio.Scanner = func() *bufio.Scanner {
		sc := bufio.NewScanner(os.Stdin)
		buf := make([]byte, initialBufSize)
		sc.Buffer(buf, maxBufSize)
		sc.Split(bufio.ScanWords)
		return sc
	}()
)

func main() {
	getInt()
	B := getInt()
	C := getInt()
	getInt()

	fmt.Println(max(0, B-C))
}

type Graph struct {
	n     int
	edges [][]int
}

func NewGraph(n int) *Graph {
	g := &Graph{
		n:     n,
		edges: make([][]int, n),
	}
	return g
}

func (g *Graph) AddEdge(u, v int) {
	g.edges[v] = append(g.edges[v], u)
	g.edges[u] = append(g.edges[u], v)
}

func dfs(c int, edges [][]int, visited map[int]struct{}) {
	visited[c] = struct{}{}

	for _, v := range edges[c] {
		_, flag := visited[v]
		if flag {
			continue
		}
		dfs(v, edges, visited)
	}
}

func bfs(c int, graph *Graph) {
	next := make([]int, 0)
	next = append(next, c)
	visited := make(map[int]struct{})

	for ; len(next) != 0; {
		u := next[0]
		next = next[1:]
		visited[u] = struct{}{}

		for _, v := range graph.edges[u] {
			_, flag := visited[v]
			if flag {
				continue
			}

			// なにか処理

			next = append(next, v)
		}
	}
}

func getInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func getIntArray(n int) []int {
	array := make([]int, n)
	for i := 0; i < n; i++ {
		array[i] = getInt()
	}
	return array
}

func getString() string {
	sc.Scan()
	return sc.Text()
}

func getStringArray(n int) []string {
	array := make([]string, n)
	for i := 0; i < n; i++ {
		array[i] = getString()
	}
	return array
}

func abs(a int) int {
	return int(math.Abs(float64(a)))
}

func pow(p, q int) int {
	return int(math.Pow(float64(p), float64(q)))
}

func powMod(n, p int) int {
	if p == 0 {
		return 1
	} else if p%2 == 0 {
		t := powMod(n, p/2)
		return calcMod(t * t)
	} else {
		return calcMod(n * powMod(n, p-1))
	}
}

func min(nums ...int) int {
	if len(nums) == 0 {
		panic("funciton min() requires at least one argument.")
	}
	res := nums[0]
	for i := 0; i < len(nums); i++ {
		res = int(math.Min(float64(res), float64(nums[i])))
	}
	return res
}

func max(nums ...int) int {
	if len(nums) == 0 {
		panic("funciton max() requires at least one argument.")
	}
	res := nums[0]
	for i := 0; i < len(nums); i++ {
		res = int(math.Max(float64(res), float64(nums[i])))
	}
	return res
}

func strSearch(a []string, b string) bool {
	for i := 0; i < len(a); i++ {
		if a[i] == b {
			return true
		}
	}
	return false
}

func printIntArray(array []int) {
	strArray := fmt.Sprint(array)
	fmt.Println(strArray[1 : len(strArray)-1])
}

func calcMod(x int) int {
	return x % mod
}

func reverse(s string) string {
	runes := []rune(s)
	for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
	return string(runes)
}

func isPrime(n int) bool {
	if n < 2 {
		return false
	} else if n == 2 {
		return true
	} else if n % 2 == 0 {
		return false
	}

	sqrtN := int(math.Sqrt(float64(n)))
	for i := 3; i <= sqrtN; i += 2 {
		if n % i == 0 {
			return false
		}
	}

	return true
}

func contains(s []int, e int) bool {
	for _, v := range s {
		if e == v {
			return true
		}
	}
	return false
}

func makeRange(min, max int) []int {
	a := make([]int, max-min+1)
	for i := range a {
		a[i] = min + i
	}
	return a
}

func powerset2(nums []int) [][]int {
	length := int(math.Pow(2, float64(len(nums))))
	result := make([][]int, length)

	index := 0
	result[index] = []int{}
	index++

	for _, n := range nums {
		max := index
		for i := 0; i < max; i++ {
			result[index] = copyAndAppend(result[i], n)
			index++
		}
	}

	return result
}

func copyAndAppend(nums []int, n int) []int {
	dst := make([]int, len(nums)+1)
	copy(dst, nums)
	dst[len(nums)] = n
	return dst
}

func calcGcd(x, y int) int {
	if y == 0 {
		return x
	} else if x >= y {
		return calcGcd(y, x % y)
	} else {
		return calcGcd(x, y % x)
	}
}

func getDivisor(n int) []int {
	var divisor []int
	divisor = append(divisor, 1)
	if n != 1 {
		divisor = append(divisor, n)
	}

	sqrt := int(math.Sqrt(float64(n)))
	for i := 2; i <= sqrt; i++ {
		if n % i == 0 {
			divisor = append(divisor, i)
			divisor = append(divisor, n/i)
		}
	}
	return divisor
}

type intHeap []int

func (h intHeap) Len() int {
	return len(h)
}

func (h intHeap) Less(i, j int) bool {
	return h[i] > h[j]
}

func (h intHeap) Swap(i, j int) {
	h[i], h[j] = h[j], h[i]
}

func (h *intHeap) Push(x interface{}) {
	*h = append(*h, x.(int))
}

func (h *intHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}

func initHeap() *intHeap {
	ih := &intHeap{}
	heap.Init(ih)
	return ih
}

func (h *intHeap) pushHeap(n int) {
	heap.Push(h, n)
}

func (h *intHeap) popHeap() int {
	return heap.Pop(h).(int)
}

func factMod(n int) int {
	value := 1
	for ; n > 1; n-- {
		value = calcMod(value * n)
	}
	return value
}

func combinationMod(n, k int) int {
	factN := factMod(n)
	factK := factMod(k)
	factNK := factMod(n - k)
	factKR := powMod(factK, mod - 2)
	factNKR := powMod(factNK, mod - 2)
	return calcMod(factN * calcMod(factKR * factNKR))
}


package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"reflect"
	"sort"
	"strconv"
	"strings"
	// "regexp"
)

/* sort */
type pair struct {
	index  int64
	p1, p2 interface{}
}
type pairs []pair

func (slice pairs) Len() int {
	return len(slice)
}

func (slice pairs) Less(i, j int) bool {
	return slice[i].index < slice[j].index
}

func (slice pairs) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}

/* sort */
type Int64Slice []int64

func (slice Int64Slice) Len() int {
	return len(slice)
}

func (slice Int64Slice) Less(i, j int) bool {
	return slice[i] < slice[j]
}

func (slice Int64Slice) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}
func Int64s(a []int64)                    { sort.Sort(Int64Slice(a)) }
func Int64sSliceAreSorted(a []int64) bool { return sort.IsSorted(Int64Slice(a)) }

const (
	initialBufSize = 1e4
	maxBufSize     = 1e8
	INF            = 1e8
)

var (
	scanner = bufio.NewScanner(os.Stdin)
	writer  = bufio.NewWriter(os.Stdout)
	di      = []int64{-1, 0, 1, 0}
	dj      = []int64{0, -1, 0, 1}
)

func main() {
	buf := make([]byte, initialBufSize)
	scanner.Buffer(buf, maxBufSize)
	scanner.Split(bufio.ScanWords)
	A, B, C, D := readInt(), readInt(), readInt(), readInt()
	ans := int64(0)
	if C > B {
		fmt.Println(0)
	} else {
		ans = B - C
		if B > D {
			ans -= B - D
		}
		if A > C {
			ans -= A - C
		}
		fmt.Println(ans)
	}
}

/*==========================================
 *             Library
 *==========================================*/
func NextPermutation(x sort.Interface) bool {
	n := x.Len() - 1
	if n < 1 {
		return false
	}
	j := n - 1
	for ; !x.Less(j, j+1); j-- {
		if j == 0 {
			return false
		}
	}
	l := n
	for !x.Less(j, l) {
		l--
	}
	x.Swap(j, l)
	for k, l := j+1, n; k < l; {
		x.Swap(k, l)
		k++
		l--
	}
	return true
}
func doubleAry(h int64, w int64, init int64) (res [][]int64) {
	res = make([][]int64, h)
	for i := int64(0); i < h; i++ {
		res[i] = make([]int64, w)
		for j := int64(0); j < w; j++ {
			res[i][j] = init
		}
	}
	return
}

func aryEq(a []int64, b []int64) bool {
	return reflect.DeepEqual(a, b)
}

func clone(n []int64) (r []int64) {
	r = make([]int64, len(n))
	for i := 0; i < len(n); i++ {
		r[i] = n[i]
	}
	return
}
func write(s string) {
	writer.WriteString(s)
}

func print() {
	writer.Flush()
}

// scanner.Split(bufio.ScanWords) をコメントアウトしないと使用不可
func readLine() (s string) {
	if scanner.Scan() {
		s = scanner.Text()
	}
	return s
}

func readInt() (read int64) {
	scanner.Scan()
	read, err := strconv.ParseInt(scanner.Text(), 10, 64)
	if err != nil {
		panic(err)
	}
	return
}

func readFloat() (read float64) {
	scanner.Scan()
	read, err := strconv.ParseFloat(scanner.Text(), 64)
	if err != nil {
		panic(err)
	}
	return
}

func readRunes() (read []rune) {
	scanner.Scan()
	for _, v := range scanner.Text() {
		read = append(read, v)
	}
	return
}

func readString() (read string) {
	scanner.Scan()
	read = scanner.Text()
	return
}

func readStrings() (read []string) {
	scanner.Scan()
	for _, v := range scanner.Text() {
		read = append(read, string(v))
	}
	return
}

func s2i(s string) int64 {
	var intVal, e = strconv.ParseInt(s, 10, 64)
	if e != nil {
		panic(e)
	}
	return intVal
}

func i2s(i int64) string {
	var strVal = strconv.FormatInt(i, 10)
	return strVal
}

func s2f(s string) float64 {
	var floatVal, e = strconv.ParseFloat(s, 64)
	if e != nil {
		panic(e)
	}
	return floatVal
}

func abs(i int64) int64 {
	return int64(math.Abs(float64(i)))
}

func max(a ...int64) int64 {
	ans := int64(0)
	for i, v := range a {
		if i == 0 {
			ans = v
		}
		if ans < v {
			ans = v
		}
	}
	return ans
}
func min(a ...int64) int64 {
	ans := int64(0)
	for i, v := range a {
		if i == 0 {
			ans = v
		}
		if ans > v {
			ans = v
		}
	}
	return ans
}

func sum(i []int64) int64 {
	sum := int64(0)
	for _, val := range i {
		sum += val
	}
	return sum
}

func split(s string) []string {
	return strings.Fields(s)
}

func strAry2intAry(strs []string) []int64 {
	var ret = make([]int64, 0, len(strs))
	for _, str := range strs {
		var intVal = s2i(str)
		ret = append(ret, intVal)
	}
	return ret
}

func intAry2strAry(nums []int64) []string {
	var ret = make([]string, 0, len(nums))
	for _, num := range nums {
		var strVal = i2s(num)
		ret = append(ret, strVal)
	}
	return ret
}

func ary2str(strs []string) string {
	return strings.Join(strs, " ")
}

func reverse(res []int64) []int64 {
	for i, j := 0, len(res)-1; i < j; i, j = i+1, j-1 {
		res[i], res[j] = res[j], res[i]
	}
	return res
}
func reverseStr(res []string) []string {
	for i, j := 0, len(res)-1; i < j; i, j = i+1, j-1 {
		res[i], res[j] = res[j], res[i]
	}
	return res
}

func ini(res []int, init int) {
	if len(res) == 0 {
		return
	}
	res[0] = init
	for i := 0; i < len(res); i++ {
		copy(res[i:], res[:i])
	}
}

//
// func regexpExample() {
//     // Your code here!
//     var str = "13:20"
//     r := regexp.MustCompile(`(\d+):(\d+)`)
//     fmt.Println(r.FindStringSubmatch(str))
// }

// type Country struct {
//     gold int
//     silver int
//     blonze int
// }

// // 複数ソートのサンプル
// func stableSortExample() []Country{
//     var country = []Country {
//         {gold:1, silver:2, blonze:3},
//         {gold:1, silver:2, blonze:3},
//         {gold:1, silver:3, blonze:2},
//         {gold:1, silver:3, blonze:3},
//     }
//     sort.SliceStable(country, func(i, j int) bool { return country[i].blonze > country[j].blonze })
//     sort.SliceStable(country, func(i, j int) bool { return country[i].silver > country[j].silver })
//     sort.SliceStable(country, func(i, j int) bool { return country[i].gold > country[j].gold })
//     return country
// }


A, B, C, D = gets.split.map &:to_i
ret = 0
if B < C || D < A
    ret = 0
elsif C <= A && B <= D
    ret = B - A
elsif C <= A && D <= B
    ret = D - A
elsif A <= C && D <= B
    ret = D - C
elsif A <= C && B <= D
    ret = B - C
end
puts ret


a, b, c, d = gets.chomp.split.map(&:to_i)

ans = [b, d].min - [a, c].max

if 0 < ans
  puts ans
else
  puts "0"
end


input = gets.chomp.split
a = input[0].to_i
b = input[1].to_i
c = input[2].to_i
d = input[3].to_i

start = a > c ? a : c
finish = b < d ? b : d
seconds = finish - start

puts seconds > 0 ? seconds : 0


a,b,c,d=gets.split.map(&:to_i)
p ([*a..b]&[*c..d]).size-1


a,b,c,d=gets.split.map(&:to_i)
p ([*a..b]&[*c..d]).size


a,b,c,d = gets.chomp.split(" ").map(&:to_i)
arr = Array.new(101,0)
(a..b).each do |i|
  arr[i] += 1
end
(c..d).each do |i|
  arr[i] += 1
end
count = 0
st = []
arr.each_with_index do |o,j|
  if o == 2
    st << j
  end
end
if st != []
    puts st.pop - st.shift
else
    puts "0"
end


use std::io;
use std::cmp::{min, max};

fn procon_read<T: std::str::FromStr>() ->  Vec<T> {
	let mut buf = String::new();
	io::stdin().read_line(&mut buf).expect("");
	let iter = buf.split_whitespace();
	let mut v: Vec<T> = Vec::new();
	for i in iter {
		v.push(i.parse().ok().unwrap());
	}
	v
}

fn main() {
	let v:Vec<i32> = procon_read();
	let a = v[0];
	let b = v[1];
	let c = v[2];
	let d = v[3];
	let mut pusht = 0;
	if !(c > b || d < a) {
		pusht = min(d, b) - max(a, c);
	}
	println!("{}", pusht);
}


use std::io::*;
use std::str::FromStr;

pub fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

use std::cmp::max;
use std::cmp::min;

fn main() {
    let a: i64 = read();
    let b: i64 = read();
    let c: i64 = read();
    let d: i64 = read();
    if a > c {
        println!("{}", max(min(d - a, b - a), 0));
        return;
    }
    if c > a {
        println!("{}", max(min(b - c, d - c), 0));
        return;
    }
    println!("{}", min(b, d) - a);
}


macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let mut s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};

    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };

    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };

    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };

    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };

    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}
fn main() {
    input!{
        u: [i32; 4],
    };
    println!(
        "{}",
        (0..100)
        .filter(|&x| x >= u[0] && x < u[1] && x >= u[2] && x < u[3])
        .count()
    );
}


#[allow(unused_macros, dead_code)]
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        let mut next = || { iter.next().unwrap() };
        input_inner!{next, $($r)*}
    };
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

#[allow(unused_macros, dead_code)]
macro_rules! input_inner {
    ($next:expr) => {};
    ($next:expr, ) => {};

    ($next:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };

    ($next:expr, mut $var:ident : $t:tt $($r:tt)*) => {
        let mut $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };
}

#[allow(unused_macros, dead_code)]
macro_rules! read_value {
    ($next:expr, ( $($t:tt),* )) => {
        ( $(read_value!($next, $t)),* )
    };

    ($next:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    };

    ($next:expr, chars) => {
        read_value!($next, String).chars().collect::<Vec<char>>()
    };

    ($next:expr, bytes) => {
        read_value!($next, String).into_bytes()
    };

    ($next:expr, usize1) => {
        read_value!($next, usize) - 1
    };

    ($next:expr, $t:ty) => {
        $next().parse::<$t>().expect("Parse error")
    };
}

#[allow(dead_code)]
struct UnionFind {
    parent: Vec<usize>,
    rank: Vec<usize>,
    size: Vec<usize>,
}

#[allow(dead_code)]
impl UnionFind {
    fn new(n: usize) -> UnionFind {
        let mut p = vec![0; n];
        for i in 0..n {
            p[i] = i;
        }
        return UnionFind {
            parent: p,
            rank: vec![0; n],
            size: vec![1; n],
        };
    }

    fn find(&mut self, x: usize) -> usize {
        if x == self.parent[x] {
            x
        } else {
            let p = self.parent[x];
            let pr = self.find(p);
            self.parent[x] = pr;
            pr
        }
    }

    fn same(&mut self, a: usize, b: usize) -> bool {
        self.find(a) == self.find(b)
    }

    fn unite(&mut self, a: usize, b: usize) {
        let a_root = self.find(a);
        let b_root = self.find(b);
        if a_root == b_root {
            return;
        }
        if self.rank[a_root] > self.rank[b_root] {
            self.parent[b_root] = a_root;
            self.size[a_root] += self.size[b_root];
        } else {
            self.parent[a_root] = b_root;
            self.size[b_root] += self.size[a_root];
            if self.rank[a_root] == self.rank[b_root] {
                self.rank[b_root] += 1;
            }
        }
    }

    fn get_size(&mut self, x: usize) -> usize {
        let root = self.find(x);
        self.size[root]
    }
}

const MOD_P: usize = 1000000007;

#[allow(dead_code)]
// fact(n) = n! mod p
fn fact(n: usize) -> usize {
    let mut acc = 1;
    for i in 1..n + 1 {
        acc = acc * i % MOD_P;
    }
    acc
}

#[allow(dead_code)]
fn mod_pow(b: usize, mut e: usize) -> usize {
    let mut base = b;
    let mut acc = 1;

    while e > 1 {
        if e % 2 == 1 {
            acc = acc * base % MOD_P;
        }
        e /= 2;
        base = base * base % MOD_P;
    }

    if e == 1 {
        acc = acc * base % MOD_P;
    }

    acc
}

#[allow(dead_code)]
fn comb(n: usize, r: usize) -> usize {
    // nCr = n! / (r! (n-r)!) = n! (r!)^(p-2) ((n-r)!)^(p-2)
    let x = ((n - r + 1)..(n + 1)).fold(1, |p, x| p * x % MOD_P);
    let y = mod_pow(fact(r), MOD_P - 2);
    x * y % MOD_P
}

#[derive(Clone, Copy, Debug)]
struct GF(usize);

impl std::ops::Add for GF {
    type Output = GF;
    fn add(self, rhs: GF) -> Self::Output {
        let mut d = self.0 + rhs.0;
        if d >= MOD_P {
            d -= MOD_P;
        }
        GF(d)
    }
}

impl std::ops::AddAssign for GF {
    fn add_assign(&mut self, rhs: GF) {
        *self = *self + rhs;
    }
}

impl std::ops::Sub for GF {
    type Output = GF;
    fn sub(self, rhs: GF) -> Self::Output {
        let mut d = self.0 + MOD_P - rhs.0;
        if d >= MOD_P {
            d -= MOD_P;
        }
        GF(d)
    }
}

impl std::ops::SubAssign for GF {
    fn sub_assign(&mut self, rhs: GF) {
        *self = *self - rhs;
    }
}

impl std::ops::Mul for GF {
    type Output = GF;
    fn mul(self, rhs: GF) -> Self::Output {
        let mut d = self.0 * rhs.0;
        d %= MOD_P;
        GF(d)
    }
}

impl std::ops::MulAssign for GF {
    fn mul_assign(&mut self, rhs: GF) {
        *self = *self * rhs;
    }
}

impl std::fmt::Display for GF {
    fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

#[allow(dead_code)]
impl GF {
    pub fn new(n: usize) -> GF {
        GF(n % MOD_P)
    }
    pub fn zero() -> GF {
        GF(0)
    }
    pub fn one() -> GF {
        GF(1)
    }
    pub fn pow(self, mut e: usize) -> GF {
        let mut acc = GF::one();
        let mut b = self;
        while e > 1 {
            if e % 2 == 1 {
                acc *= b;
            }
            b *= b;
            e /= 2;
        }
        if e == 1 {
            acc *= b;
        }
        acc
    }
    pub fn fact(self) -> GF {
        let mut acc = GF::one();
        for i in 1..=self.0 {
            acc *= GF::new(i);
        }
        acc
    }
    pub fn inv(self) -> GF {
        self.pow(MOD_P - 2)
    }
    pub fn comb(n: GF, r: GF) -> GF {
        // nCr = n! / (r! (n-r)!) = n! (r!)^(p-2) ((n-r)!)^(p-2)
        let x = ((n.0 - r.0 + 1)..=n.0).fold(GF::one(), |p, x| p * GF(x));
        let y = r.fact().inv();
        x * y
    }
}

#[allow(dead_code)]
#[derive(Debug)]
struct MemComb {
    inv: Vec<GF>,
    fact: Vec<GF>,
    factinv: Vec<GF>,
}

#[allow(dead_code)]
impl MemComb {
    pub fn new(n: usize) -> MemComb {
        let mut inv = vec![GF::one(); n + 1];
        let mut fact = vec![GF::one(); n + 1];
        let mut factinv = vec![GF::one(); n + 1];

        for i in 2..=n {
            fact[i] = fact[i - 1] * GF(i);
        }

        factinv[n] = fact[n].inv();
        for i in (1..n).rev() {
            factinv[i] = factinv[i + 1] * GF(i + 1); // 1/n! = 1/(n+1)! * (n+1)
            inv[i] = factinv[i] * fact[i - 1]; // 1/n = 1/n! * (n-1)!
        }
        inv[n] = factinv[n] * fact[n - 1];

        MemComb { inv, fact, factinv }
    }
}

#[allow(dead_code)]
fn gcd(a: usize, b: usize) -> usize {
    if b > a {
        gcd(b, a)
    } else if a % b == 0 {
        b
    } else {
        gcd(b, a % b)
    }
}

#[allow(dead_code)]
fn getline() -> String {
    let mut __ret = String::new();
    std::io::stdin().read_line(&mut __ret).ok();
    return __ret;
}

#[allow(unused_imports)]
use std::cmp::{max, min};

fn main() {
    input! {
        a: usize,
        b: usize,
        c: usize,
        d:usize,
    }
    let ans = if b <= c || d <= a {
        0
    } else if a <= c && b >= d {
        d - c
    } else if c <= a && d <= b {
        b - a
    } else if a <= c {
        b - c
    } else {
        d - a
    };
    println!("{}", ans);
}


use std::io;
use std::cmp::{min, max};

fn procon_read<T: std::str::FromStr>() ->  Vec<T> {
	let mut buf = String::new();
	io::stdin().read_line(&mut buf).expect("");
	let iter = buf.split_whitespace();
	let mut v: Vec<T> = Vec::new();
	for i in iter {
		v.push(i.parse().ok().unwrap());
	}
	v
}

fn main() {
	let v:Vec<i32> = procon_read();
	let a = v[0];
	let b = v[1];
	let c = v[2];
	let d = v[3];
	let mut pusht = 0;
	if (c >= a && c <= b) || (d >= a && d <= b) {
		pusht = min(d, b) - max(a, c);
	}
	println!("{}", pusht);
}


use std::io;
use std::cmp::min;

fn procon_read<T: std::str::FromStr>() ->  Vec<T> {
	let mut buf = String::new();
	io::stdin().read_line(&mut buf).expect("");
	let iter = buf.split_whitespace();
	let mut v: Vec<T> = Vec::new();
	for i in iter {
		v.push(i.parse().ok().unwrap());
	}
	v
}

fn main() {
	let v:Vec<i32> = procon_read();
	let a = v[0];
	let b = v[1];
	let c = v[2];
	let d = v[3];
	let mut pusht = 0;
	if c < b && d > a {
		if a < c {
			pusht = b - c;
		}
		if d < b {
			pusht = d - a;
		}
	}
	println!("{}", pusht);
}


let i=readLine()!.characters.split(" ").map{Int(String($0))!};print(max(min(i[1],i[3])-max(i[0],i[2]),0))


let i = readLine()!.characters.split(" ").map{Int(String($0))!};print(max(min(i[1],i[3])-max(i[0],i[2]),0))


import Foundation

#if swift(>=4.0)
extension String {
    func split(by separator: String) -> [String] {
        return self.components(separatedBy: separator)
    }
    func toArray() -> [String] {
        return self.map{String($0)}
    }
}
func exponentiate(_ lhs: Int, _ rhs: Int) -> Int {
    return (0..<rhs).reduce(1){i,_ in i*lhs}
}
#else
extension String {
    func split(by separator: String) -> [String] {
        return self.componentsSeparatedByString(separator)
    }
    var count: Int {
        return self.characters.count
    }
    func toArray() -> [String] {
        return self.characters.map{String($0)}
    }
    func uppercased() -> String {
        return self.uppercaseString
    }
    func lowercased() -> String {
        return self.lowercaseString
    }
}
//extension Array where Element == String {
//    func joined(separator separator: String) -> String {
//        return self.joinWithSeparator(separator)
//    }
//}
extension Array where Element: Comparable {
    func max() -> Element {
        return self.maxElement()!
    }
    func min() -> Element {
        return self.minElement()!
    }
    func sorted() -> Array {
        return self.sort()
    }
    func reversed() -> Array {
        return self.reverse()
    }
    mutating func sort() {
        self.sortInPlace()
    }
}
extension Array {
    init(repeating: Element, count: Int) {
        self.init(count: count, repeatedValue: repeating)
    }
}
func stride<T: Strideable>(from start: T, to end: T, by stride: T.Stride) -> StrideTo<T> {
    return start.stride(to: end, by: stride)
}
func exponentiate(lhs: Int, _ rhs: Int) -> Int {
    return (0..<rhs).reduce(1){i,_ in i*lhs}
}
#endif
func readInt() -> Int? {
    return Int(readLine()!)
}
func readStringSplit(by separator: String) -> [String] {
    return readLine()!.split(by: separator)
}
func readIntSplit(by separator: String) -> [Int] {
    return readLine()!.split(by: separator).map{Int($0)!}
}

/*************** テストスペース ***************/

/*************** メインプログラム ***************/

let input = readIntSplit(by: " ")
let (A, B, C, D) = (input[0], input[1], input[2], input[3])
let start = max(A, C)
let end = min(B, D)
print(max(end - start, 0))