#![allow(unused_imports)]
#![allow(unused_macros)]
#![allow(dead_code)]
#![allow(unused_labels)]

use std::cmp::*;
use std::collections::*;
use std::io::{Write, BufWriter};
// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
macro_rules! input {
    ($($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)*}
    };
}

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)*}
    };
}

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, usize1) => {
        read_value!($next, usize) - 1
    };

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

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

use std::io::*;
use std::str::FromStr;
use std::char::*;
macro_rules! debug {($($a:expr),*) => {eprintln!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);}}

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::f64;

fn min<T: PartialOrd>(a:T, b:T) -> T {
    if a < b { a }
    else { b }
}

fn max<T: PartialOrd>(a:T, b:T) -> T {
    if a < b { b }
    else { a }
}

const MAX:usize = 30;
const INF:i64 = std::i64::MAX;
const MOD:i64 = 1e9 as i64 + 7;

struct Graph {
    e: Vec<Vec<usize>>,
    v: Vec<usize>,
    u: Vec<usize>,
    f: Vec<bool>,
    c: i64,
    flag: bool,
    vc: Vec<i64>,
}

impl Graph {
    fn new(n:usize) -> Self {
        Graph {
            e: vec![vec![];n],
            v: vec![],
            u: vec![n;n],
            f: vec![false;n],
            c: 0,
            flag: true,
            vc: vec![0;n],
        }
    }

    fn dfs(&mut self, crt: usize) {
        self.f[crt] = true;
        self.c = self.e[crt].len() as i64;
        if self.c != 2 {
            self.flag = false;
        }

        for i in 0..self.e[crt].len() {
            let v = self.e[crt][i];
            if self.f[v] { continue; }
            self.dfs(v);
        }
    }
}

fn binary_search(a: &Vec<i64>) -> usize {
    let mut left = -1;
    let mut right = a.len() as i64;

    while right - left > 1 {
        let mid:usize = ((right+left)/2) as usize;
        //debug!(left,mid,right);
        if is_ok(mid) { right = mid as i64; }
        else { left = mid as i64; }
    }
    right as usize
}

fn is_ok(key: usize) -> bool {
    true
}

fn neighbors(tree: &BTreeSet<usize>, val: usize) -> (Option<&usize>, Option<&usize>) {
    use std::ops::Bound::*;

    let mut before = tree.range((Unbounded, Excluded(val)));
    let mut after = tree.range((Excluded(val), Unbounded));

    (before.next_back(), after.next())
}

fn main() {
    // In order to avoid potential stack overflow, spawn a new thread.
    let stack_size = 104_857_600; // 100 MB
    let thd = std::thread::Builder::new().stack_size(stack_size);
    thd.spawn(|| solve()).unwrap().join().unwrap();
}

const MAX_A:i64 = 1e16 as i64;

fn gcd(a:i64, b:i64) -> i64 {
    if b==0 {return a;}
    gcd(b, a%b)
}

fn solve() {
    let out = std::io::stdout();
    let mut out = BufWriter::new(out.lock());
    macro_rules! puts {
        ($($format:tt)*) => (let _ = write!(out,$($format)*););
    }

    input! {
        n: usize,
        a: [i64;n]
    }

    let mut ans = 0;
    let i = 0;
    if (a[i]==1 && a[i+1]==2) || (a[i]==2 && a[i+1]==1) {
        ans += 3;
    }
    else if (a[i]==1 && a[i+1]==3) || (a[i]==3 && a[i+1]==1) {
        ans += 4;
    }
    else {
        puts!("Infinite\n");
        return;
    }

    for i in 1..n-1 {
        if a[i]==1 && a[i+1]==2 {
            if a[i-1]==3 { ans += 2; }
            else { ans += 3; }
        }
        else if a[i]==2 && a[i+1]==1 {
            ans += 3;
        }
        else if a[i]==1 && a[i+1]==3 {
            ans += 4;
        }
        else if a[i]==3 && a[i+1]==1 {
            ans += 4;
        }
        else {
            puts!("Infinite\n");
            return;
        }
    }
    puts!("Finite\n");
    puts!("{}\n", ans);

}

/*

*/

// https://codeforces.com/contest/1156/problem/A
//
#![allow(unused_imports)]
use std::io::*;
use std::io::Write;
use std::fmt::*;
use std::str::*;
use std::cmp::*;
use std::collections::*;

// Input macros.
// Original by tanakh: https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
#[allow(unused_macros)]
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let 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)*}
    };
}

#[allow(unused_macros)]
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)*}
    };

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

#[allow(unused_macros)]
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, [ next / $t:tt ]) => {
        {
            let len = read_value!($iter, usize);
            (0..len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
        }
    };

    ($iter:expr, switch) => {
        {
            let ty = read_value!($iter, i32);
            if ty == 1 {
                vec![ty, read_value!($iter, i32), read_value!($iter, i32)]
            } else if ty == 2 {
                vec![ty, read_value!($iter, i32)]
            } else {
                vec![ty, read_value!($iter, i32)]
            }
        }
    };

    ($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")
    };
}

#[allow(unused_macros)]
macro_rules! read_line {
    ($t:tt) => {
        {
            let mut s = String::new();
            std::io::stdin().read_line(&mut s).unwrap();
            s.trim_right().parse::<$t>().unwrap()
        }
    }
}

#[allow(unused_macros)]
macro_rules! dvec {
    ($t:expr ; $len:expr) => {
        vec![$t; $len]
    };

    ($t:expr ; $len:expr, $($rest:expr),*) => {
        vec![dvec!($t; $($rest),*); $len]
    };
}

#[allow(unused_macros)]
macro_rules! ifv {
    ($t:expr, $a:expr, $b: expr) => {
        if $t { $a } else { $b }
    }
}

#[allow(unused_macros)]
macro_rules! fill {
    ($t:expr, $v:expr) => {
        for i in 0..$t.len() {
            $t[i] = $v;
        }
    };
}

#[allow(unused_macros)]
macro_rules! join {
    ($t:expr, $glue:expr) => {
        $t.into_iter().map(|w| w.to_string()).collect::<Vec<_>>().join($glue)
    };
}

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        eprintln!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
    }
}

// ===

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

    let INF = 1000000000i64;
    let table = vec![
        vec![-INF, 3, 4],
        vec![3, -INF, -INF],
        vec![4, -INF, -INF],
    ];

    let mut points = 0i64;
    for i in 1..n {
        points += table[a[i-1]][a[i]];
        if i >= 2 && a[i-2] == 2 && a[i-1] == 0 && a[i] == 1 {
            points -= 1;
        }
    }
    if points <= -1 {
        println!("Infinite");
    } else {
        println!("Finite");
        println!("{}", points);
    }
}

#[allow(unused_macros)]
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)]
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)]
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, usize1) => {
        read_value!($next, usize) - 1
    };

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

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        #[cfg(debug_assertions)]
        writeln!(&mut std::io::stderr(), concat!("[DEBUG] ", $(stringify!($a), "={:?} "),*), $($a),*);
    }
}

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

#[allow(unused_imports)]
use std::io::Write;
type I = usize;

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

    let mut ans: u64 = 0;
    for i in 1..n {
         let a1 = aa[i-1];
         let a2 = aa[i];
         let mut a = [a1, a2];
         a.sort();

         if a[0] != 1 {
             return println!("{}", "Infinite");
         }

         if a[1] == 2 {
            if a2 == 2 && i>=2 && aa[i-2] == 3 {
                ans += 2;
            } else {
                ans += 3;
            }
         } else {
            ans += 4;
         }
    }
    println!("{}", "Finite");
    println!("{}", ans);
}

#![allow(dead_code, unused_imports, unused_macros)]

use std::fmt::Debug;
use std::str::FromStr;

fn read_stdin() -> String {
    let mut s = String::new();
    std::io::stdin()
        .read_line(&mut s)
        .expect("cannot read stdin");
    s.trim().to_string()
}

fn read<T>() -> T
where
    T: FromStr,
    <T as FromStr>::Err: Debug,
{
    read_stdin().parse::<T>().unwrap()
}

fn read_usize() -> usize {
    read::<usize>()
}

fn read_2<A, B>() -> (A, B)
where
    A: FromStr,
    <A as FromStr>::Err: Debug,
    B: FromStr,
    <B as FromStr>::Err: Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    (a, b)
}

fn read_3<A, B, C>() -> (A, B, C)
where
    A: FromStr,
    <A as FromStr>::Err: Debug,
    B: FromStr,
    <B as FromStr>::Err: Debug,
    C: FromStr,
    <C as FromStr>::Err: Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    let c = s.next().unwrap().parse::<C>().unwrap();
    (a, b, c)
}

fn read_4<A, B, C, D>() -> (A, B, C, D)
where
    A: FromStr,
    <A as FromStr>::Err: Debug,
    B: FromStr,
    <B as FromStr>::Err: Debug,
    C: FromStr,
    <C as FromStr>::Err: Debug,
    D: FromStr,
    <D as FromStr>::Err: Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    let c = s.next().unwrap().parse::<C>().unwrap();
    let d = s.next().unwrap().parse::<D>().unwrap();
    (a, b, c, d)
}

fn read_multiple<T: FromStr>() -> Vec<T>
where
    <T as FromStr>::Err: Debug,
{
    read_stdin()
        .split_whitespace()
        .map(|x| x.parse::<T>().expect("cannot parse stdin"))
        .collect()
}

/// NOTE: sort iter beforehand if required
fn count<T>(iter: &mut impl Iterator<Item = T>) -> Vec<(T, usize)>
where
    T: std::cmp::Ord,
{
    let iter = iter.collect::<Vec<_>>();
    //iter.sort();
    let (mut v, o, c) =
        iter.into_iter()
            .fold((Vec::new(), None, 0), |(mut v, last, count), item| {
                if let Some(o) = last {
                    if item == o {
                        (v, Some(o), count + 1)
                    } else {
                        v.push((o, count));
                        (v, Some(item), 1)
                    }
                } else {
                    (v, Some(item), 1)
                }
            });
    if let Some(i) = o {
        v.push((i, c));
    }
    v
}

fn partial_sum<T>(v: impl Iterator<Item = T>) -> impl Iterator<Item = T>
where
    T: Default + std::ops::Add<Output = T> + Copy,
{
    v.scan(T::default(), |state, x| {
        *state = *state + x;
        Some(*state)
    })
}

fn partial_max<T>(v: impl Iterator<Item = T>) -> impl Iterator<Item = T>
where
    T: Default + Ord + Copy,
{
    v.scan(T::default(), |state, x| {
        *state = max(*state, x);
        Some(*state)
    })
}

fn partial_min(v: impl Iterator<Item = u64>) -> impl Iterator<Item = u64> {
    v.scan(std::u64::MAX, |state, x| {
        *state = min(*state, x);
        Some(*state)
    })
}

fn max_subarray(v: impl Iterator<Item = i64>) -> (i64, (usize, usize)) {
    //assert!(v.len() > 0);
    let mut best_sum = 0;
    let (mut best_start, mut best_end) = (0, 0);
    let mut current_sum = 0;
    let mut current_start = 0;
    for (end, val) in v.enumerate() {
        if current_sum <= 0 {
            current_start = end;
            current_sum = val;
        } else {
            current_sum += val;
        }
        if current_sum > best_sum {
            best_sum = current_sum;
            best_start = current_start;
            best_end = end + 1;
        }
    }
    (best_sum, (best_start, best_end))
}

fn gcd(mut a: u64, mut b: u64) -> u64 {
    while a != 0 {
        let old_m = a;
        a = b % a;
        b = old_m;
    }
    b
}

/// returns gcd, and pair (x, y), such that x * a + b * y == gcd
fn egcd(a: i64, b: i64) -> (i64, i64, i64) {
    if a == 0 {
        (b, 0, 1)
    } else {
        let (g, x, y) = egcd(b % a, a);
        (g, y - (b / a) * x, x)
    }
}

fn factorize(mut n: u64) -> Vec<u64> {
    if n <= 3 {
        return vec![n];
    }
    let mut v = Vec::new();
    while n % 2 == 0 {
        n /= 2;
        v.push(2);
    }
    while n % 3 == 0 {
        n /= 3;
        v.push(3);
    }
    let mut f = 6;
    while (f - 1) * (f - 1) <= n {
        while n % (f - 1) == 0 {
            n /= f - 1;
            v.push(f - 1);
        }
        while n % (f + 1) == 0 {
            n /= f + 1;
            v.push(f + 1);
        }
        f += 6;
    }
    if n > 1 {
        v.push(n);
    }
    v
}

fn compact_factors(n: u64) -> Vec<(u64, usize)> {
    count(&mut factorize(n).into_iter())
}

fn all_factors(n: u64) -> Vec<u64> {
    if n == 0 {
        return vec![0];
    } else if n == 1 {
        return vec![1];
    }
    let factors = compact_factors(n);
    let mut v = vec![1];
    for (fac, num) in factors {
        let ori = v.clone();
        for i in 1..num + 1 {
            v.append(
                &mut ori
                    .clone()
                    .into_iter()
                    .map(|f| f * fac.pow(i as u32))
                    .collect::<Vec<_>>(),
            )
        }
    }
    v.sort();
    v
}

fn abs_diff<T>(a: T, b: T) -> T
where
    T: PartialOrd + std::ops::Sub<Output = T>,
{
    if a > b {
        a - b
    } else {
        b - a
    }
}

struct Permutations<T> {
    inner: Vec<T>,
    state: Vec<usize>,
    i: usize,
    start: bool,
}

impl<T> Permutations<T> {
    fn new(inner: Vec<T>) -> Self {
        Self {
            state: vec![0; inner.len()],
            i: 0,
            start: true,
            inner,
        }
    }
}

/*impl<T, X> From<X> for Permutations<T>
where
    X: IntoIterator<Item = T>,
{
    fn from(f: X) -> Self {
        Self::new(f.into_iter().collect::<Vec<T>>())
    }
}*/

impl<T> Iterator for Permutations<T>
where
    T: Clone,
{
    type Item = Vec<T>;
    fn next(&mut self) -> Option<Self::Item> {
        if self.start {
            self.start = false;
            return Some(self.inner.clone());
        }
        while self.i < self.inner.len() {
            if self.state[self.i] < self.i {
                if self.i % 2 == 0 {
                    self.inner.swap(0, self.i)
                } else {
                    self.inner.swap(self.state[self.i], self.i)
                }
                self.state[self.i] += 1;
                self.i = 0;
                return Some(self.inner.clone());
            } else {
                self.state[self.i] = 0;
                self.i += 1;
            }
        }
        None
    }
}

use std::cmp::{max, min, Ord, Ordering};
use std::collections::{BinaryHeap, VecDeque};
use std::mem::swap;

macro_rules! max_with {
    ($x: expr, $y: expr) => {
        $x = max($x, $y)
    };
}

macro_rules! min_with {
    ($x: expr, $y: expr) => {
        $x = max($x, $y)
    };
}

fn is_prime(n: u64) -> bool {
    factorize(n).len() == 1
}

fn combination(n: u64, k: u64, m: u64) -> u64 {
    if n == 0 {
        return 1;
    }
    if k == 0 || k == n {
        return 1;
    }
    let new_k = if n - k < k { n - k } else { k };
    let mut res = 1;
    for i in ((n - new_k) + 1)..=n {
        res *= i;
        res %= m;
    }
    let mut den = 1;
    for i in 1..=(new_k) {
        den *= i;
        den %= m;
    }
    let (_one, inverse, _c) = egcd(den as i64, m as i64);
    let inverse = if inverse < 0 {
        m as i64 + inverse
    } else {
        inverse
    } as u64;
    //println!("inv: {} {}", den, inverse);
    res *= inverse;
    res %= m;
    res
}

use std::collections::HashSet;
use std::iter::FromIterator;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let _n = read_usize();
    let v = read_multiple::<u8>();
    let mut points = 0;
    let mut prev2 = 0;
    let mut prev = v[0];
    for a in v.into_iter().skip(1) {
        if prev == 1 {
            if a == 2 {
                points += 3
            } else {
                points += 4;
            }
        } else if prev == 2 {
            if a == 1 {
                points += 3
            } else {
                println!("Infinite");
                return Ok(());
            }
        } else {
            //prv == 3
            if a == 1 {
                points += 4
            } else {
                println!("Infinite");
                return Ok(());
            }
        }
        if prev2 == 3 && prev == 1 && a == 2 {
            points -= 1;
        }
        prev2 = prev;
        prev = a;
    }
    println!("Finite");
    println!("{}", points);
    Ok(())
}

#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
#[allow(unused_imports)]
use std::io::{stderr, stdin, stdout, BufWriter, StdoutLock, Write};
#[allow(unused_imports)]
use std::iter::FromIterator;
#[allow(unused_imports)]
use std::{i64, u64, usize};
#[allow(unused_macros)]
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)]
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)]
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 , [ $ t : tt ] ) => { { let len = read_value ! ( $ next , usize ) ; ( 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 Writer {
    s: String,
}
#[allow(unused_imports)]
use std::fmt::Display;
#[allow(dead_code)]
#[doc = " let mut writer = Writer::new();"]
#[doc = " writer.writeln(hoge);"]
#[doc = " writer.flush()"]
impl Writer {
    #[allow(dead_code)]
    pub fn new() -> Writer {
        Writer { s: String::new() }
    }
    #[allow(dead_code)]
    pub fn flush(&mut self) {
        print!("{}", self.s);
        self.s.clear();
    }
    pub fn write<T: Display>(&mut self, x: T) {
        self.s.push_str(&format!("{}", x));
    }
    pub fn writeln<T: Display>(&mut self, x: T) {
        self.s.push_str(&format!("{}", x));
        self.s.push('\n');
    }
    #[allow(dead_code)]
    pub fn write_vec<T: Display>(&mut self, xs: &Vec<T>) {
        if xs.len() == 0 {
            self.writeln("");
            return;
        }
        self.write(&format!("{}", xs[0]));
        for i in 1..xs.len() {
            self.write(&format!(" {}", xs[i]));
        }
        self.writeln("");
    }
}
#[allow(unused_macros)]
macro_rules ! dbg { ( $ ( $ a : expr ) ,* ) => { writeln ! ( & mut stderr ( ) , concat ! ( $ ( stringify ! ( $ a ) , " = {:?}, " ) ,* ) , $ ( $ a ) ,* ) . unwrap ( ) ; } }
#[allow(dead_code)]
const INF_U: u64 = 1_000_000_000_000_000;
#[allow(dead_code)]
const INF_I: i64 = 1_000_000_000_000_000;
#[allow(non_snake_case)]
#[allow(dead_code)]
fn main() {
    input! {
        n: usize,
        a: [usize; n]
    }
    let mut ans = 0;
    let mut flag = false;
    for i in 1..n {
        dbg!(ans);
        if a[i-1] == 1 {
            if a[i] == 2 {
                if flag { ans += 2; }
                else { ans += 3; }
            } else {
                ans += 4;
            }
        } else if a[i-1] == 2 {
            if a[i] == 1 {
                ans += 3;
            } else {
                println!("Infinite");
                return;
            }
        } else {
            if a[i] == 1 {
                ans += 4;
                flag = true;
                continue;
            } else {
                println!("Infinite");
                return;
            }
        }
        flag = false;
    }
    println!("Finite");
    println!("{}", ans);
}

#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
use std::io::{Write, BufWriter};
// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
macro_rules! input {
    ($($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)*}
    };
}

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)*}
    };
}

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, usize1) => {
        read_value!($next, usize) - 1
    };

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

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

fn solve() {
    let out = std::io::stdout();
    let mut out = BufWriter::new(out.lock());
    macro_rules! puts {
        ($($format:tt)*) => (write!(out,$($format)*).unwrap());
    }
    input! {
        n: usize,
        a: [i32; n],
    }
    let mut cnt = 0;
    for i in 0..n - 1 {
        if a[i] + a[i + 1] == 5 {
            puts!("Infinite\n");
            return;
        }
        cnt += a[i] + a[i + 1];
    }
    for i in 0..n - 2 {
        if a[i..i + 3] == [3, 1, 2] {
            cnt -= 1;
        }
    }
    puts!("Finite\n{}\n", cnt);
}

fn main() {
    // In order to avoid potential stack overflow, spawn a new thread.
    let stack_size = 104_857_600; // 100 MB
    let thd = std::thread::Builder::new().stack_size(stack_size);
    thd.spawn(|| solve()).unwrap().join().unwrap();
}

#[doc = " https://github.com/hatoo/competitive-rust-snippets"]
#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
#[allow(unused_imports)]
use std::iter::FromIterator;
#[macro_export]
macro_rules ! chmax { ( $ x : expr , $ ( $ v : expr ) ,+ ) => { $ ( $ x = std :: cmp :: max ( $ x ,$ v ) ; ) + } ; }
#[macro_export]
macro_rules ! chmin { ( $ x : expr , $ ( $ v : expr ) ,+ ) => { $ ( $ x = std :: cmp :: min ( $ x ,$ v ) ; ) + } ; }
#[macro_export]
macro_rules ! max { ( $ x : expr ) => ( $ x ) ; ( $ x : expr , $ ( $ xs : expr ) ,+ ) => { std :: cmp :: max ( $ x , max ! ( $ ( $ xs ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! min { ( $ x : expr ) => ( $ x ) ; ( $ x : expr , $ ( $ xs : expr ) ,+ ) => { std :: cmp :: min ( $ x , min ! ( $ ( $ xs ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! dvec { ( $ t : expr ; $ len : expr ) => { vec ! [ $ t ; $ len ] } ; ( $ t : expr ; $ len : expr , $ ( $ rest : expr ) ,* ) => { vec ! [ dvec ! ( $ t ; $ ( $ rest ) ,* ) ; $ len ] } ; }
#[doc = " main"]
#[allow(unused_imports)]
use std::io::{stdin, stdout, BufWriter, Write};
#[macro_export]
macro_rules ! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut parser = Parser :: from_str ( $ s ) ; input_inner ! { parser , $ ( $ r ) * } } ; ( parser = $ parser : ident , $ ( $ r : tt ) * ) => { input_inner ! { $ parser , $ ( $ r ) * } } ; ( new_stdin_parser = $ parser : ident , $ ( $ r : tt ) * ) => { let stdin = std :: io :: stdin ( ) ; let reader = std :: io :: BufReader :: new ( stdin . lock ( ) ) ; let mut $ parser = Parser :: new ( reader ) ; input_inner ! { $ parser , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { input ! { new_stdin_parser = parser , $ ( $ r ) * } } ; }
#[macro_export]
macro_rules ! input_inner { ( $ parser : ident ) => { } ; ( $ parser : ident , ) => { } ; ( $ parser : ident , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ parser , $ t ) ; input_inner ! { $ parser $ ( $ r ) * } } ; }
#[macro_export]
macro_rules ! read_value { ( $ parser : ident , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ parser , $ t ) ) ,* ) } ; ( $ parser : ident , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ parser , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ parser : ident , chars ) => { read_value ! ( $ parser , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ parser : ident , usize1 ) => { read_value ! ( $ parser , usize ) - 1 } ; ( $ parser : ident , $ t : ty ) => { $ parser . next ::<$ t > ( ) . expect ( "Parse error" ) } ; }
use std::io;
use std::io::BufRead;
use std::str;
pub struct Parser<R> {
    reader: R,
    buf: Vec<u8>,
    pos: usize,
}
impl Parser<io::Empty> {
    pub fn from_str(s: &str) -> Parser<io::Empty> {
        Parser {
            reader: io::empty(),
            buf: s.as_bytes().to_vec(),
            pos: 0,
        }
    }
}
impl<R: BufRead> Parser<R> {
    pub fn new(reader: R) -> Parser<R> {
        Parser {
            reader: reader,
            buf: vec![],
            pos: 0,
        }
    }
    pub fn update_buf(&mut self) {
        self.buf.clear();
        self.pos = 0;
        loop {
            let (len, complete) = {
                let buf2 = self.reader.fill_buf().unwrap();
                self.buf.extend_from_slice(buf2);
                let len = buf2.len();
                if len == 0 {
                    break;
                }
                (len, buf2[len - 1] <= 0x20)
            };
            self.reader.consume(len);
            if complete {
                break;
            }
        }
    }
    pub fn next<T: str::FromStr>(&mut self) -> Result<T, T::Err> {
        loop {
            let mut begin = self.pos;
            while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                begin += 1;
            }
            let mut end = begin;
            while end < self.buf.len() && (self.buf[end] > 0x20) {
                end += 1;
            }
            if begin != self.buf.len() {
                self.pos = end;
                return str::from_utf8(&self.buf[begin..end]).unwrap().parse::<T>();
            } else {
                self.update_buf();
            }
        }
    }
}
#[allow(unused_macros)]
macro_rules ! debug { ( $ ( $ a : expr ) ,* ) => { eprintln ! ( concat ! ( $ ( stringify ! ( $ a ) , " = {:?}, " ) ,* ) , $ ( $ a ) ,* ) ; } }
#[doc = " https://github.com/hatoo/competitive-rust-snippets"]
const BIG_STACK_SIZE: bool = true;
#[allow(dead_code)]
fn main() {
    use std::thread;
    if BIG_STACK_SIZE {
        thread::Builder::new()
            .stack_size(32 * 1024 * 1024)
            .name("solve".into())
            .spawn(solve)
            .unwrap()
            .join()
            .unwrap();
    } else {
        solve();
    }
}
fn solve() {
    let out = stdout();
    let mut out = BufWriter::new(out.lock());
    input!{
        n:usize,
        a:[usize;n]
    }
    let mut tot = 0;
    for i in 1..n {
        let x = i-1;
        let y = i;
        match (a[x],a[y]) {
            (1,2) | (2,1) => {
                if tot != -1 {
                    tot += 3
                }
            },
            (2,3) | (3,2) => {
                tot = -1
            },
            (1,3) | (3,1) => {
                if tot != -1 {
                    tot += 4
                }
            },
            _ => {

            }
        }
    }
    if tot == -1 {
        writeln!(out,"Infinite");
        return
    }
    for i in 2..n {
        match (a[i-2],a[i-1],a[i]) {
            (3,1,2) => {
                tot -= 1;
            },
            _ => {}
        }
    }
    writeln!(out,"Finite");
    writeln!(out,"{}",tot);
}

// https://codeforces.com/contest/1156/problem/A
//
#![allow(unused_imports)]
use std::io::*;
use std::io::Write;
use std::fmt::*;
use std::str::*;
use std::cmp::*;
use std::collections::*;

// Input macros.
// Original by tanakh: https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
#[allow(unused_macros)]
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let 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)*}
    };
}

#[allow(unused_macros)]
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)*}
    };

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

#[allow(unused_macros)]
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, [ next / $t:tt ]) => {
        {
            let len = read_value!($iter, usize);
            (0..len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
        }
    };

    ($iter:expr, switch) => {
        {
            let ty = read_value!($iter, i32);
            if ty == 1 {
                vec![ty, read_value!($iter, i32), read_value!($iter, i32)]
            } else if ty == 2 {
                vec![ty, read_value!($iter, i32)]
            } else {
                vec![ty, read_value!($iter, i32)]
            }
        }
    };

    ($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")
    };
}

#[allow(unused_macros)]
macro_rules! read_line {
    ($t:tt) => {
        {
            let mut s = String::new();
            std::io::stdin().read_line(&mut s).unwrap();
            s.trim_right().parse::<$t>().unwrap()
        }
    }
}

#[allow(unused_macros)]
macro_rules! dvec {
    ($t:expr ; $len:expr) => {
        vec![$t; $len]
    };

    ($t:expr ; $len:expr, $($rest:expr),*) => {
        vec![dvec!($t; $($rest),*); $len]
    };
}

#[allow(unused_macros)]
macro_rules! ifv {
    ($t:expr, $a:expr, $b: expr) => {
        if $t { $a } else { $b }
    }
}

#[allow(unused_macros)]
macro_rules! fill {
    ($t:expr, $v:expr) => {
        for i in 0..$t.len() {
            $t[i] = $v;
        }
    };
}

#[allow(unused_macros)]
macro_rules! join {
    ($t:expr, $glue:expr) => {
        $t.into_iter().map(|w| w.to_string()).collect::<Vec<_>>().join($glue)
    };
}

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        eprintln!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
    }
}

// ===

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

    let INF = 1000000000i64;
    let table = vec![
        vec![-INF, 3, 4],
        vec![3, -INF, -INF],
        vec![4, -INF, -INF],
    ];

    let mut points = 0i64;
    for i in 1..n {
        points += table[a[i-1]][a[i]];
    }
    if points <= -1 {
        println!("Infinite");
    } else {
        println!("Finite");
        println!("{}", points);
    }
}

#[allow(unused_macros)]
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)]
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)]
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, usize1) => {
        read_value!($next, usize) - 1
    };

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

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        #[cfg(debug_assertions)]
        writeln!(&mut std::io::stderr(), concat!("[DEBUG] ", $(stringify!($a), "={:?} "),*), $($a),*);
    }
}

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

#[allow(unused_imports)]
use std::io::Write;
type I = usize;

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

    let mut ans = 0;
    for i in 1..n {
         let a1 = aa[i-1];
         let a2 = aa[i];
         let mut a = [a1, a2];
         a.sort();

         if a == [2, 3] {
             println!("{}", "Infinite");
             return;
         }

         if a == [1, 2] {
             ans += 3;
         } else {
            ans += 4;
         }
    }
    println!("{}", "Finite");
    println!("{}", ans);
}

#[allow(unused_macros)]
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)]
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)]
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, usize1) => {
        read_value!($next, usize) - 1
    };

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

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        #[cfg(debug_assertions)]
        writeln!(&mut std::io::stderr(), concat!("[DEBUG] ", $(stringify!($a), "={:?} "),*), $($a),*);
    }
}

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

#[allow(unused_imports)]
use std::io::Write;
type I = usize;

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

    let mut ans: u64 = 0;
    for i in 1..n {
         let a1 = aa[i-1];
         let a2 = aa[i];
         let mut a = [a1, a2];
         a.sort();

         if a[0] != 1 {
             return println!("{}", "Infinite");
         }

         if a[1] == 2 {
             ans += 3;
         } else {
            ans += 4;
         }
    }
    println!("{}", "Finite");
    println!("{}", ans);
}

#[allow(unused_macros)]
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)]
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)]
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, usize1) => {
        read_value!($next, usize) - 1
    };

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

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        #[cfg(debug_assertions)]
        writeln!(&mut std::io::stderr(), concat!("[DEBUG] ", $(stringify!($a), "={:?} "),*), $($a),*);
    }
}

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

#[allow(unused_imports)]
use std::io::Write;
type I = usize;

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

    let mut ans = 0;
    for i in 1..n {
         let a1 = aa[i-1];
         let a2 = aa[i];
         let mut a = [a1, a2];
         a.sort();

         if a[0] != 1 {
             return println!("{}", "Infinite");
         }

         if a[1] == 2 {
             ans += 3;
         } else {
            ans += 4;
         }
    }
    println!("{}", "Finite");
    println!("{}", ans);
}

#[allow(unused_macros)]
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)]
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)]
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, usize1) => {
        read_value!($next, usize) - 1
    };

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

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        #[cfg(debug_assertions)]
        writeln!(&mut std::io::stderr(), concat!("[DEBUG] ", $(stringify!($a), "={:?} "),*), $($a),*);
    }
}

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

#[allow(unused_imports)]
use std::io::Write;
type I = usize;

fn f(i: u64) -> u64 {
    let ss = (i+1).to_string();
    let ss: Vec<char> = ss.chars().collect();
    let mut index = ss.len();
    for i in (0..ss.len()).rev() {
        if ss[i] == '0' {
            index = i;
        } else {
            break;
        }
    }
    let ret = &ss[0..index];
    let ret: String = ret.iter().collect();
    return ret.parse().unwrap();
}

fn main() {
    input!{
      mut n: u64,
    }
    let mut seen = std::collections::HashMap::new();

    let mut ans = 0;
    while !seen.contains_key(&n) {
        ans += 1;
        seen.insert(n, true);
        n = f(n);
    }
    println!("{}", ans);
}

#![allow(unused_imports)]
#![allow(unused_macros)]
#![allow(dead_code)]
#![allow(unused_labels)]

use std::cmp::*;
use std::collections::*;
use std::io::{Write, BufWriter};
// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
macro_rules! input {
    ($($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)*}
    };
}

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)*}
    };
}

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, usize1) => {
        read_value!($next, usize) - 1
    };

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

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

use std::io::*;
use std::str::FromStr;
use std::char::*;
macro_rules! debug {($($a:expr),*) => {eprintln!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);}}

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::f64;

fn min<T: PartialOrd>(a:T, b:T) -> T {
    if a < b { a }
    else { b }
}

fn max<T: PartialOrd>(a:T, b:T) -> T {
    if a < b { b }
    else { a }
}

const MAX:usize = 30;
const INF:i64 = std::i64::MAX;
const MOD:i64 = 1e9 as i64 + 7;

struct Graph {
    e: Vec<Vec<usize>>,
    v: Vec<usize>,
    u: Vec<usize>,
    f: Vec<bool>,
    c: i64,
    flag: bool,
    vc: Vec<i64>,
}

impl Graph {
    fn new(n:usize) -> Self {
        Graph {
            e: vec![vec![];n],
            v: vec![],
            u: vec![n;n],
            f: vec![false;n],
            c: 0,
            flag: true,
            vc: vec![0;n],
        }
    }

    fn dfs(&mut self, crt: usize) {
        self.f[crt] = true;
        self.c = self.e[crt].len() as i64;
        if self.c != 2 {
            self.flag = false;
        }

        for i in 0..self.e[crt].len() {
            let v = self.e[crt][i];
            if self.f[v] { continue; }
            self.dfs(v);
        }
    }
}

fn binary_search(a: &Vec<i64>) -> usize {
    let mut left = -1;
    let mut right = a.len() as i64;

    while right - left > 1 {
        let mid:usize = ((right+left)/2) as usize;
        //debug!(left,mid,right);
        if is_ok(mid) { right = mid as i64; }
        else { left = mid as i64; }
    }
    right as usize
}

fn is_ok(key: usize) -> bool {
    true
}

fn neighbors(tree: &BTreeSet<usize>, val: usize) -> (Option<&usize>, Option<&usize>) {
    use std::ops::Bound::*;

    let mut before = tree.range((Unbounded, Excluded(val)));
    let mut after = tree.range((Excluded(val), Unbounded));

    (before.next_back(), after.next())
}

fn main() {
    // In order to avoid potential stack overflow, spawn a new thread.
    let stack_size = 104_857_600; // 100 MB
    let thd = std::thread::Builder::new().stack_size(stack_size);
    thd.spawn(|| solve()).unwrap().join().unwrap();
}

const MAX_A:i64 = 1e16 as i64;

fn gcd(a:i64, b:i64) -> i64 {
    if b==0 {return a;}
    gcd(b, a%b)
}

fn solve() {
    let out = std::io::stdout();
    let mut out = BufWriter::new(out.lock());
    macro_rules! puts {
        ($($format:tt)*) => (let _ = write!(out,$($format)*););
    }

    input! {
        n: usize,
        a: [i64;n]
    }

    let mut ans = 0;
    for i in 0..n-1 {
        if (a[i]==1 && a[i+1]==2) || (a[i]==2 && a[i+1]==1) {
            ans += 3;
        }
        else if (a[i]==1 && a[i+1]==3) || (a[i]==3 && a[i+1]==1) {
            ans += 4;
        }
        else {
            puts!("Infinite\n");
            return;
        }
    }
    puts!("Finite\n");
    puts!("{}\n", ans);

}

/*

*/

#![allow(dead_code, unused_imports, unused_macros)]

use std::fmt::Debug;
use std::str::FromStr;

fn read_stdin() -> String {
    let mut s = String::new();
    std::io::stdin()
        .read_line(&mut s)
        .expect("cannot read stdin");
    s.trim().to_string()
}

fn read<T>() -> T
where
    T: FromStr,
    <T as FromStr>::Err: Debug,
{
    read_stdin().parse::<T>().unwrap()
}

fn read_usize() -> usize {
    read::<usize>()
}

fn read_2<A, B>() -> (A, B)
where
    A: FromStr,
    <A as FromStr>::Err: Debug,
    B: FromStr,
    <B as FromStr>::Err: Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    (a, b)
}

fn read_3<A, B, C>() -> (A, B, C)
where
    A: FromStr,
    <A as FromStr>::Err: Debug,
    B: FromStr,
    <B as FromStr>::Err: Debug,
    C: FromStr,
    <C as FromStr>::Err: Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    let c = s.next().unwrap().parse::<C>().unwrap();
    (a, b, c)
}

fn read_4<A, B, C, D>() -> (A, B, C, D)
where
    A: FromStr,
    <A as FromStr>::Err: Debug,
    B: FromStr,
    <B as FromStr>::Err: Debug,
    C: FromStr,
    <C as FromStr>::Err: Debug,
    D: FromStr,
    <D as FromStr>::Err: Debug,
{
    let s = read_stdin();
    let mut s = s.split_whitespace();
    let a = s.next().unwrap().parse::<A>().unwrap();
    let b = s.next().unwrap().parse::<B>().unwrap();
    let c = s.next().unwrap().parse::<C>().unwrap();
    let d = s.next().unwrap().parse::<D>().unwrap();
    (a, b, c, d)
}

fn read_multiple<T: FromStr>() -> Vec<T>
where
    <T as FromStr>::Err: Debug,
{
    read_stdin()
        .split_whitespace()
        .map(|x| x.parse::<T>().expect("cannot parse stdin"))
        .collect()
}

/// NOTE: sort iter beforehand if required
fn count<T>(iter: &mut impl Iterator<Item = T>) -> Vec<(T, usize)>
where
    T: std::cmp::Ord,
{
    let iter = iter.collect::<Vec<_>>();
    //iter.sort();
    let (mut v, o, c) =
        iter.into_iter()
            .fold((Vec::new(), None, 0), |(mut v, last, count), item| {
                if let Some(o) = last {
                    if item == o {
                        (v, Some(o), count + 1)
                    } else {
                        v.push((o, count));
                        (v, Some(item), 1)
                    }
                } else {
                    (v, Some(item), 1)
                }
            });
    if let Some(i) = o {
        v.push((i, c));
    }
    v
}

fn partial_sum<T>(v: impl Iterator<Item = T>) -> impl Iterator<Item = T>
where
    T: Default + std::ops::Add<Output = T> + Copy,
{
    v.scan(T::default(), |state, x| {
        *state = *state + x;
        Some(*state)
    })
}

fn partial_max<T>(v: impl Iterator<Item = T>) -> impl Iterator<Item = T>
where
    T: Default + Ord + Copy,
{
    v.scan(T::default(), |state, x| {
        *state = max(*state, x);
        Some(*state)
    })
}

fn partial_min(v: impl Iterator<Item = u64>) -> impl Iterator<Item = u64> {
    v.scan(std::u64::MAX, |state, x| {
        *state = min(*state, x);
        Some(*state)
    })
}

fn max_subarray(v: impl Iterator<Item = i64>) -> (i64, (usize, usize)) {
    //assert!(v.len() > 0);
    let mut best_sum = 0;
    let (mut best_start, mut best_end) = (0, 0);
    let mut current_sum = 0;
    let mut current_start = 0;
    for (end, val) in v.enumerate() {
        if current_sum <= 0 {
            current_start = end;
            current_sum = val;
        } else {
            current_sum += val;
        }
        if current_sum > best_sum {
            best_sum = current_sum;
            best_start = current_start;
            best_end = end + 1;
        }
    }
    (best_sum, (best_start, best_end))
}

fn gcd(mut a: u64, mut b: u64) -> u64 {
    while a != 0 {
        let old_m = a;
        a = b % a;
        b = old_m;
    }
    b
}

/// returns gcd, and pair (x, y), such that x * a + b * y == gcd
fn egcd(a: i64, b: i64) -> (i64, i64, i64) {
    if a == 0 {
        (b, 0, 1)
    } else {
        let (g, x, y) = egcd(b % a, a);
        (g, y - (b / a) * x, x)
    }
}

fn factorize(mut n: u64) -> Vec<u64> {
    if n <= 3 {
        return vec![n];
    }
    let mut v = Vec::new();
    while n % 2 == 0 {
        n /= 2;
        v.push(2);
    }
    while n % 3 == 0 {
        n /= 3;
        v.push(3);
    }
    let mut f = 6;
    while (f - 1) * (f - 1) <= n {
        while n % (f - 1) == 0 {
            n /= f - 1;
            v.push(f - 1);
        }
        while n % (f + 1) == 0 {
            n /= f + 1;
            v.push(f + 1);
        }
        f += 6;
    }
    if n > 1 {
        v.push(n);
    }
    v
}

fn compact_factors(n: u64) -> Vec<(u64, usize)> {
    count(&mut factorize(n).into_iter())
}

fn all_factors(n: u64) -> Vec<u64> {
    if n == 0 {
        return vec![0];
    } else if n == 1 {
        return vec![1];
    }
    let factors = compact_factors(n);
    let mut v = vec![1];
    for (fac, num) in factors {
        let ori = v.clone();
        for i in 1..num + 1 {
            v.append(
                &mut ori
                    .clone()
                    .into_iter()
                    .map(|f| f * fac.pow(i as u32))
                    .collect::<Vec<_>>(),
            )
        }
    }
    v.sort();
    v
}

fn abs_diff<T>(a: T, b: T) -> T
where
    T: PartialOrd + std::ops::Sub<Output = T>,
{
    if a > b {
        a - b
    } else {
        b - a
    }
}

struct Permutations<T> {
    inner: Vec<T>,
    state: Vec<usize>,
    i: usize,
    start: bool,
}

impl<T> Permutations<T> {
    fn new(inner: Vec<T>) -> Self {
        Self {
            state: vec![0; inner.len()],
            i: 0,
            start: true,
            inner,
        }
    }
}

/*impl<T, X> From<X> for Permutations<T>
where
    X: IntoIterator<Item = T>,
{
    fn from(f: X) -> Self {
        Self::new(f.into_iter().collect::<Vec<T>>())
    }
}*/

impl<T> Iterator for Permutations<T>
where
    T: Clone,
{
    type Item = Vec<T>;
    fn next(&mut self) -> Option<Self::Item> {
        if self.start {
            self.start = false;
            return Some(self.inner.clone());
        }
        while self.i < self.inner.len() {
            if self.state[self.i] < self.i {
                if self.i % 2 == 0 {
                    self.inner.swap(0, self.i)
                } else {
                    self.inner.swap(self.state[self.i], self.i)
                }
                self.state[self.i] += 1;
                self.i = 0;
                return Some(self.inner.clone());
            } else {
                self.state[self.i] = 0;
                self.i += 1;
            }
        }
        None
    }
}

use std::cmp::{max, min, Ord, Ordering};
use std::collections::{BinaryHeap, VecDeque};
use std::mem::swap;

macro_rules! max_with {
    ($x: expr, $y: expr) => {
        $x = max($x, $y)
    };
}

macro_rules! min_with {
    ($x: expr, $y: expr) => {
        $x = max($x, $y)
    };
}

fn is_prime(n: u64) -> bool {
    factorize(n).len() == 1
}

fn combination(n: u64, k: u64, m: u64) -> u64 {
    if n == 0 {
        return 1;
    }
    if k == 0 || k == n {
        return 1;
    }
    let new_k = if n - k < k { n - k } else { k };
    let mut res = 1;
    for i in ((n - new_k) + 1)..=n {
        res *= i;
        res %= m;
    }
    let mut den = 1;
    for i in 1..=(new_k) {
        den *= i;
        den %= m;
    }
    let (_one, inverse, _c) = egcd(den as i64, m as i64);
    let inverse = if inverse < 0 {
        m as i64 + inverse
    } else {
        inverse
    } as u64;
    //println!("inv: {} {}", den, inverse);
    res *= inverse;
    res %= m;
    res
}

use std::collections::HashSet;
use std::iter::FromIterator;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let _n = read_usize();
    let v = read_multiple::<u8>();
    let mut points = 0;
    let mut prev = v[0];
    for a in v.into_iter().skip(1) {
        if prev == 1 {
            if a == 2 {
                points += 3
            } else {
                points += 4;
            }
        } else if prev == 2 {
            if a == 1 {
                points += 3
            } else {
                println!("Infinite");
                return Ok(());
            }
        } else {
            //prv == 3
            if a == 1 {
                points += 4
            } else {
                println!("Infinite");
                return Ok(());
            }
        }
        prev = a;
    }
    println!("Finite");
    println!("{}", points);
    Ok(())
}

#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
#[allow(unused_imports)]
use std::io::{stderr, stdin, stdout, BufWriter, StdoutLock, Write};
#[allow(unused_imports)]
use std::iter::FromIterator;
#[allow(unused_imports)]
use std::{i64, u64, usize};
#[allow(unused_macros)]
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)]
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)]
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 , [ $ t : tt ] ) => { { let len = read_value ! ( $ next , usize ) ; ( 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 Writer {
    s: String,
}
#[allow(unused_imports)]
use std::fmt::Display;
#[allow(dead_code)]
#[doc = " let mut writer = Writer::new();"]
#[doc = " writer.writeln(hoge);"]
#[doc = " writer.flush()"]
impl Writer {
    #[allow(dead_code)]
    pub fn new() -> Writer {
        Writer { s: String::new() }
    }
    #[allow(dead_code)]
    pub fn flush(&mut self) {
        print!("{}", self.s);
        self.s.clear();
    }
    pub fn write<T: Display>(&mut self, x: T) {
        self.s.push_str(&format!("{}", x));
    }
    pub fn writeln<T: Display>(&mut self, x: T) {
        self.s.push_str(&format!("{}", x));
        self.s.push('\n');
    }
    #[allow(dead_code)]
    pub fn write_vec<T: Display>(&mut self, xs: &Vec<T>) {
        if xs.len() == 0 {
            self.writeln("");
            return;
        }
        self.write(&format!("{}", xs[0]));
        for i in 1..xs.len() {
            self.write(&format!(" {}", xs[i]));
        }
        self.writeln("");
    }
}
#[allow(unused_macros)]
macro_rules ! dbg { ( $ ( $ a : expr ) ,* ) => { writeln ! ( & mut stderr ( ) , concat ! ( $ ( stringify ! ( $ a ) , " = {:?}, " ) ,* ) , $ ( $ a ) ,* ) . unwrap ( ) ; } }
#[allow(dead_code)]
const INF_U: u64 = 1_000_000_000_000_000;
#[allow(dead_code)]
const INF_I: i64 = 1_000_000_000_000_000;
#[allow(non_snake_case)]
#[allow(dead_code)]
fn main() {
    input! {
        n: usize,
        a: [usize; n]
    }
    let mut ans = 0;
    for i in 1..n {
        if a[i-1] == 1 {
            if a[i] == 2 {
                ans += 3;
            } else {
                ans += 4;
            }
        } else if a[i-1] == 2 {
            if a[i] == 1 {
                ans += 3;
            } else {
                println!("Infinite");
                return;
            }
        } else {
            if a[i] == 1 {
                ans += 4;
            } else {
                println!("Infinite");
                return;
            }
        }
    }
    println!("Finite");
    println!("{}", ans);
}

#[doc = " https://github.com/hatoo/competitive-rust-snippets"]
#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
#[allow(unused_imports)]
use std::iter::FromIterator;
#[macro_export]
macro_rules ! chmax { ( $ x : expr , $ ( $ v : expr ) ,+ ) => { $ ( $ x = std :: cmp :: max ( $ x ,$ v ) ; ) + } ; }
#[macro_export]
macro_rules ! chmin { ( $ x : expr , $ ( $ v : expr ) ,+ ) => { $ ( $ x = std :: cmp :: min ( $ x ,$ v ) ; ) + } ; }
#[macro_export]
macro_rules ! max { ( $ x : expr ) => ( $ x ) ; ( $ x : expr , $ ( $ xs : expr ) ,+ ) => { std :: cmp :: max ( $ x , max ! ( $ ( $ xs ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! min { ( $ x : expr ) => ( $ x ) ; ( $ x : expr , $ ( $ xs : expr ) ,+ ) => { std :: cmp :: min ( $ x , min ! ( $ ( $ xs ) ,+ ) ) } ; }
#[macro_export]
macro_rules ! dvec { ( $ t : expr ; $ len : expr ) => { vec ! [ $ t ; $ len ] } ; ( $ t : expr ; $ len : expr , $ ( $ rest : expr ) ,* ) => { vec ! [ dvec ! ( $ t ; $ ( $ rest ) ,* ) ; $ len ] } ; }
#[doc = " main"]
#[allow(unused_imports)]
use std::io::{stdin, stdout, BufWriter, Write};
#[macro_export]
macro_rules ! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut parser = Parser :: from_str ( $ s ) ; input_inner ! { parser , $ ( $ r ) * } } ; ( parser = $ parser : ident , $ ( $ r : tt ) * ) => { input_inner ! { $ parser , $ ( $ r ) * } } ; ( new_stdin_parser = $ parser : ident , $ ( $ r : tt ) * ) => { let stdin = std :: io :: stdin ( ) ; let reader = std :: io :: BufReader :: new ( stdin . lock ( ) ) ; let mut $ parser = Parser :: new ( reader ) ; input_inner ! { $ parser , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { input ! { new_stdin_parser = parser , $ ( $ r ) * } } ; }
#[macro_export]
macro_rules ! input_inner { ( $ parser : ident ) => { } ; ( $ parser : ident , ) => { } ; ( $ parser : ident , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ parser , $ t ) ; input_inner ! { $ parser $ ( $ r ) * } } ; }
#[macro_export]
macro_rules ! read_value { ( $ parser : ident , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ parser , $ t ) ) ,* ) } ; ( $ parser : ident , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ parser , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ parser : ident , chars ) => { read_value ! ( $ parser , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ parser : ident , usize1 ) => { read_value ! ( $ parser , usize ) - 1 } ; ( $ parser : ident , $ t : ty ) => { $ parser . next ::<$ t > ( ) . expect ( "Parse error" ) } ; }
use std::io;
use std::io::BufRead;
use std::str;
pub struct Parser<R> {
    reader: R,
    buf: Vec<u8>,
    pos: usize,
}
impl Parser<io::Empty> {
    pub fn from_str(s: &str) -> Parser<io::Empty> {
        Parser {
            reader: io::empty(),
            buf: s.as_bytes().to_vec(),
            pos: 0,
        }
    }
}
impl<R: BufRead> Parser<R> {
    pub fn new(reader: R) -> Parser<R> {
        Parser {
            reader: reader,
            buf: vec![],
            pos: 0,
        }
    }
    pub fn update_buf(&mut self) {
        self.buf.clear();
        self.pos = 0;
        loop {
            let (len, complete) = {
                let buf2 = self.reader.fill_buf().unwrap();
                self.buf.extend_from_slice(buf2);
                let len = buf2.len();
                if len == 0 {
                    break;
                }
                (len, buf2[len - 1] <= 0x20)
            };
            self.reader.consume(len);
            if complete {
                break;
            }
        }
    }
    pub fn next<T: str::FromStr>(&mut self) -> Result<T, T::Err> {
        loop {
            let mut begin = self.pos;
            while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                begin += 1;
            }
            let mut end = begin;
            while end < self.buf.len() && (self.buf[end] > 0x20) {
                end += 1;
            }
            if begin != self.buf.len() {
                self.pos = end;
                return str::from_utf8(&self.buf[begin..end]).unwrap().parse::<T>();
            } else {
                self.update_buf();
            }
        }
    }
}
#[allow(unused_macros)]
macro_rules ! debug { ( $ ( $ a : expr ) ,* ) => { eprintln ! ( concat ! ( $ ( stringify ! ( $ a ) , " = {:?}, " ) ,* ) , $ ( $ a ) ,* ) ; } }
#[doc = " https://github.com/hatoo/competitive-rust-snippets"]
const BIG_STACK_SIZE: bool = true;
#[allow(dead_code)]
fn main() {
    use std::thread;
    if BIG_STACK_SIZE {
        thread::Builder::new()
            .stack_size(32 * 1024 * 1024)
            .name("solve".into())
            .spawn(solve)
            .unwrap()
            .join()
            .unwrap();
    } else {
        solve();
    }
}
fn solve() {
    let out = stdout();
    let mut out = BufWriter::new(out.lock());
    input!{
        n:usize,
        a:[usize;n]
    }
    let mut tot = 0;
    for i in 1..n {
        let x = i-1;
        let y = i;
        match (a[x],a[y]) {
            (1,2) | (2,1) => {
                if tot != -1 {
                    tot += 3
                }
            },
            (2,3) | (3,2) => {
                tot = -1
            },
            (1,3) | (3,1) => {
                if tot != -1 {
                    tot += 4
                }
            },
            (_,_) => {

            }
        }
    }
    if tot == -1 {
        writeln!(out,"Infinite");
    } else {
        writeln!(out,"Finite");
        writeln!(out,"{}",tot);
    }
}


use std::io;

fn main() {
    let mut s = String::new();
    io::stdin().read_line(&mut s).unwrap();
    let mut s = s.split_whitespace();
    let x: i32 = s.next().unwrap().parse().unwrap();
    let y: i32 = s.next().unwrap().parse().unwrap();
    let z: i32 = s.next().unwrap().parse().unwrap();
    let t1: i32 = s.next().unwrap().parse().unwrap();
    let t2: i32 = s.next().unwrap().parse().unwrap();
    let t3: i32 = s.next().unwrap().parse().unwrap();
    if (x - y).abs() * t1 < ((x - z).abs() + (x - y).abs()) * t2 + 3 * t3 {
        println!("NO");
    } else {
        println!("YES");
    }
}

fn read()->Vec<i32>{
    let mut line=String::new();
    std::io::stdin().read_line(&mut line).unwrap();
    line.split_whitespace().map(|x|x.parse::<i32>().unwrap()).collect()
}
use std::i32;
fn main(){
    let vec=read();
    let stairs=i32::abs(vec[0]-vec[1])*vec[3];
    let lift=i32::abs(vec[0]-vec[1])*vec[4]+3*vec[5]+i32::abs(vec[0]-vec[2])*vec[4];
    if lift<=stairs{
        println!("YES");
    }
    else{
        println!("NO");
    }
}

use std::io;

fn main() {
    let mut s = String::new();
    io::stdin().read_line(&mut s).unwrap();
    let mut s = s.split_whitespace();
    let x: i32 = s.next().unwrap().parse().unwrap();
    let y: i32 = s.next().unwrap().parse().unwrap();
    let z: i32 = s.next().unwrap().parse().unwrap();
    let t1: i32 = s.next().unwrap().parse().unwrap();
    let t2: i32 = s.next().unwrap().parse().unwrap();
    let t3: i32 = s.next().unwrap().parse().unwrap();
    if (x - y).abs() * t1 < ((x - z).abs() + (x - y).abs()) * t2 + 2 * t3 {
        println!("NO");
    } else {
        println!("YES");
    }
}


use std::io;

fn bs<F>(f: F, mut mi: i64, mut ma: i64) -> i64
where
    F: Fn(i64) -> bool,
{
    let mut mm = 0;
    while mi < ma {
        mm = (mi + ma) / 2;
        if f(mm) {
            mi = mm + 1;
        } else {
            ma = mm;
        }
    }
    if f(mm) {
        mm + 1
    } else {
        mm
    }
}

#[allow(dead_code)]
fn solve() -> Vec<String> {
    let mut input = "".split_ascii_whitespace();
    let mut read = || loop {
        if let Some(word) = input.next() {
            break word;
        }
        input = {
            let mut input = "".to_owned();
            io::stdin().read_line(&mut input).unwrap();
            if input.is_empty() {
                panic!("reached EOF");
            }
            Box::leak(input.into_boxed_str()).split_ascii_whitespace()
        };
    };
    macro_rules! read(($ty:ty) => (read().parse::<$ty>().unwrap()));

    let mut rr = vec!["".to_string(); 0];

    let t = 1;
    for _ in 0..t {
        let n = read!(i64);
        let k = read!(i64);

        let f = |i| {
            let mut u: i64 = 0;
            let mut kk = 1;
            while kk <= i {
                u += i / kk;
                kk *= k;
            }
            u < n
        };

        let r = bs(f, 0, n);
        rr.push(format!("{}", r));
    }

    rr
}

#[allow(dead_code)]
fn main() {
    let output = solve();
    println!("{}", output.join("\n"));
}

fn is_sufficient(v: u64, n: u64, k: u64) -> bool {
    let summand_count = ((v as f64).log(k as f64).trunc() + 1_f64) as usize;
    // dbg!(summand_count);
    let sum: u64 = (0..summand_count).map(|x| v / k.checked_pow(x as u32).unwrap()).sum();
    // dbg!(sum);
    sum >= n
}

fn solve(n: u64, k: u64) -> u64 {
    let mut l: u64 = 1;
    let mut r: u64 = n + 1;
    while r - l > 2 {
        let m = l + (r - l) / 2;
        // dbg!(l, m, r);
        if is_sufficient(m, n, k) {
            // dbg!("YES");
            r = m + 1;
        } else {
            // dbg!("NO");
            l = m;
        }
    }
    // dbg!(is_sufficient(4, n, k));
    if is_sufficient(l, n, k) {l} else {l + 1}
}

fn main() {
    let (n, k) = {
        let mut buf = String::new();
        std::io::stdin().read_line(&mut buf).unwrap();
        let mut n_k = buf.trim().split_whitespace().map(|x| x.parse::<u64>().unwrap());
        let n = n_k.next().unwrap();
        let k = n_k.next().unwrap();
        (n, k)
    };

    println!("{}", solve(n, k));
}


#![allow(dead_code)]
#![allow(unused_imports)]
#![allow(unused_macros)]
#![allow(overflowing_literals)]
#![allow(unused_must_use)]

use std::collections::*;
use std::io::*;
use std::cmp::{min, max};
use std::f64::consts::*;
use std::mem::swap;
use std::fs::File;
use std::rc::*;
use std::ascii::*;
use std::ops::*;

const INF: i32 = std::i32::MAX;
const LINF: i64 = std::i64::MAX;
const MOD: usize = 1000000007;

#[derive(PartialEq, PartialOrd, Eq, Ord, Copy, Clone)]
struct Pair<A: Eq + Ord + Copy + Clone, B: Eq + Ord + Copy + Clone>(A, B);

struct Input<Buf: BufRead>
{
	buffer: Buf
}

impl<Buf: BufRead> Input<Buf>
{
	fn read_line(&mut self) -> String {
		let mut v = Vec::new();
		let mut x = [255u8];
		self.buffer.read(&mut x).expect("EOF");
		while x[0] < b' ' && x[0] != 255u8 {
			x[0] = 255u8;
			self.buffer.read(&mut x).expect("EOF");
		}
		while x[0] >= b' ' && x[0] != 255u8 {
			v.push(x[0]);
			x[0] = 255u8;
			self.buffer.read(&mut x).expect("EOF");
		}
		String::from_utf8(v).unwrap()
	}

	fn read_word(&mut self) -> String {
		let mut v = Vec::new();
		let mut x = [255u8];
		self.buffer.read(&mut x).expect("EOF");
		while x[0] <= b' ' && x[0] != 255u8 {
			x[0] = 255u8;
			self.buffer.read(&mut x).expect("EOF");
		}
		while x[0] > b' ' && x[0] != 255u8 {
			v.push(x[0]);
			x[0] = 255u8;
			self.buffer.read(&mut x).expect("EOF");
		}
		String::from_utf8(v).unwrap()
	}
	#[inline]
	fn read_int(&mut self) -> i32 {
		self.read_word().parse::<i32>().expect("Parsing error")
	}
	#[inline]
	fn read_long(&mut self) -> i64 {
		self.read_word().parse::<i64>().expect("Parsing error")
	}
	#[inline]
	fn read_usize(&mut self) -> usize {
		self.read_word().parse::<usize>().expect("Parsing error")
	}
	#[inline]
	fn read_double(&mut self) -> f64 {
		self.read_word().parse::<f64>().expect("Parsing error")
	}
}
macro_rules! read {
    () => {};
	($inf:ident,$($t:ty),*) => ({($({$inf.read_word().parse::<$t>().expect("Parsing error")}),*)});
}
fn gcd<T: RemAssign + Ord + From<i32> + Copy + Clone>(x: T, y: T) -> T {
	let (mut a, mut b) = (x, y);
	while b > T::from(0) {
		a %= b;
		swap(&mut a, &mut b);
	}
	a
}

fn main() {
	match std::env::var("home") {
		Ok(_x) => {
			let mut inf = Input {
				buffer: BufReader::new(File::open("input.txt").expect("File not found"))
			};
			let mut ouf = BufWriter::new(stdout());
			solve(&mut inf, &mut ouf);
		}
		Err(_e) => {
			let mut inf = Input { buffer: BufReader::new(stdin()) };
			let mut ouf = BufWriter::new(stdout());
			solve(&mut inf, &mut ouf);
		}
	}
}

fn solve<Inner: BufRead, Output: Write>(inf: &mut Input<Inner>, ouf: &mut Output)
{
	let n = read!(inf,usize) * 2;
	let mut w = vec![0usize; n];
	for i in 0..n {
		w[i] = read!(inf,usize);
	}
	w.sort();
	let mut ans = MOD;
	for i in 0..n {
		for j in i + 1..n {
			let mut v = Vec::new();
			for k in 0..n {
				if k != i && k != j {
					v.push(w[k]);
				}
			}
			let mut pos = 0;
			let mut p = 0;
			while pos < v.len() {
				p += v[pos + 1] - v[pos];
				pos += 2;
			}
			ans = min(ans, p);
		}
	}
	writeln!(ouf, "{}", ans);
}

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

use std::io::prelude::*;
use std::io::BufReader;
use std::cmp::{max, min};

fn get_line() -> String {
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();
    input
}

fn get_vec<T>() -> Vec<T>
    where T: FromStr,
          <T as FromStr>::Err: std::fmt::Debug,
{
    get_line().split_whitespace().map(|k| k.parse().unwrap()).collect()
}

fn main() {
    let n: usize = get_line().trim().parse().unwrap();

    let mut w: Vec<i32> = get_vec();

    w.sort();

    let mut ans = None;

    for i in 0..2 * n {
        for j in i + 1..2 * n {
            let mut v = w.clone();
            v.remove(j);
            v.remove(i);
            let cur = v.into_iter().fold((0, false), |acc, x| {
                (if acc.1 {
                    acc.0 + x
                } else {
                    acc.0 - x
                },
                !acc.1)
            }).0;

            match ans {
                Some(x) if x <= cur => (),
                _ => ans = Some(cur),
            };
        }
    }

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

#![allow(dead_code)]
#![allow(unused_imports)]
#![allow(unused_macros)]
#![allow(overflowing_literals)]
#![allow(unused_must_use)]

use std::collections::*;
use std::io::*;
use std::cmp::{min, max};
use std::f64::consts::*;
use std::mem::swap;
use std::fs::File;
use std::rc::*;
use std::ascii::*;
use std::ops::*;

const INF: i32 = std::i32::MAX;
const LINF: i64 = std::i64::MAX;
const MOD: usize = 1000000007;

#[derive(PartialEq, PartialOrd, Eq, Ord, Copy, Clone)]
struct Pair<A: Eq + Ord + Copy + Clone, B: Eq + Ord + Copy + Clone>(A, B);

struct Input<Buf: BufRead>
{
	buffer: Buf
}

impl<Buf: BufRead> Input<Buf>
{
	fn read_line(&mut self) -> String {
		let mut v = Vec::new();
		let mut x = [255u8];
		self.buffer.read(&mut x).expect("EOF");
		while x[0] < b' ' && x[0] != 255u8 {
			x[0] = 255u8;
			self.buffer.read(&mut x).expect("EOF");
		}
		while x[0] >= b' ' && x[0] != 255u8 {
			v.push(x[0]);
			x[0] = 255u8;
			self.buffer.read(&mut x).expect("EOF");
		}
		String::from_utf8(v).unwrap()
	}

	fn read_word(&mut self) -> String {
		let mut v = Vec::new();
		let mut x = [255u8];
		self.buffer.read(&mut x).expect("EOF");
		while x[0] <= b' ' && x[0] != 255u8 {
			x[0] = 255u8;
			self.buffer.read(&mut x).expect("EOF");
		}
		while x[0] > b' ' && x[0] != 255u8 {
			v.push(x[0]);
			x[0] = 255u8;
			self.buffer.read(&mut x).expect("EOF");
		}
		String::from_utf8(v).unwrap()
	}
	#[inline]
	fn read_int(&mut self) -> i32 {
		self.read_word().parse::<i32>().expect("Parsing error")
	}
	#[inline]
	fn read_long(&mut self) -> i64 {
		self.read_word().parse::<i64>().expect("Parsing error")
	}
	#[inline]
	fn read_usize(&mut self) -> usize {
		self.read_word().parse::<usize>().expect("Parsing error")
	}
	#[inline]
	fn read_double(&mut self) -> f64 {
		self.read_word().parse::<f64>().expect("Parsing error")
	}
}
macro_rules! read {
    () => {};
	($inf:ident,$($t:ty),*) => ({($({$inf.read_word().parse::<$t>().expect("Parsing error")}),*)});
}
fn gcd<T: RemAssign + Ord + From<i32> + Copy + Clone>(x: T, y: T) -> T {
	let (mut a, mut b) = (x, y);
	while b > T::from(0) {
		a %= b;
		swap(&mut a, &mut b);
	}
	a
}

fn main() {
	match std::env::var("home") {
		Ok(_x) => {
			let mut inf = Input {
				buffer: BufReader::new(File::open("input.txt").expect("File not found"))
			};
			let mut ouf = BufWriter::new(stdout());
			solve(&mut inf, &mut ouf);
		}
		Err(_e) => {
			let mut inf = Input { buffer: BufReader::new(stdin()) };
			let mut ouf = BufWriter::new(stdout());
			solve(&mut inf, &mut ouf);
		}
	}
}

fn solve<Inner: BufRead, Output: Write>(inf: &mut Input<Inner>, ouf: &mut Output)
{
	let n = read!(inf,usize);
	let mut w = vec![0usize; 2 * n];
	for i in 0..2 * n {
		w[i] = read!(inf,usize);
	}
	w.sort();
	let mut ans = MOD;
	for i in 0..3 {
		let mut pos = i;
		let mut p = 0;
		while pos < 2 * n - 2 + i {
			p += w[pos + 1] - w[pos];
			pos += 2;
		}
		ans = min(ans, p);
	}
	writeln!(ouf, "{}", ans);
}

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

use std::io::prelude::*;
use std::io::BufReader;
use std::cmp::{max, min};

fn get_line() -> String {
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();
    input
}

fn get_vec<T>() -> Vec<T>
    where T: FromStr,
          <T as FromStr>::Err: std::fmt::Debug,
{
    get_line().split_whitespace().map(|k| k.parse().unwrap()).collect()
}

fn main() {
    let n: usize = get_line().trim().parse().unwrap();

    let mut w: Vec<u32> = get_vec();

    w.sort();

    let ans = min(w[2 * n - 3] - w[0], w[2 * n - 2] - w[1]);
    let ans = min(ans, w[2 * n - 1] - w[2]);

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

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

use std::io::prelude::*;
use std::io::BufReader;
use std::cmp::{max, min};

fn get_line() -> String {
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();
    input
}

fn get_vec<T>() -> Vec<T>
    where T: FromStr,
          <T as FromStr>::Err: std::fmt::Debug,
{
    get_line().split_whitespace().map(|k| k.parse().unwrap()).collect()
}

fn main() {
    let n: usize = get_line().trim().parse().unwrap();

    let mut w: Vec<i32> = get_vec();

    w.sort();

    let ans = (0..3).map(|i| {
        w.iter().cloned().skip(i).take(2 * (n - 1)).fold((0, false), |acc, x| {
            (if acc.1 {
                acc.0 + x
            } else {
                acc.0 - x
            }, !acc.1)
        }).0
    }).min().unwrap();

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


#[allow(unused_imports)]
use std::cmp::{max, min, Ordering};
#[allow(unused_imports)]
use std::collections::{HashMap, HashSet, BinaryHeap};
#[allow(unused_imports)]
use std::iter::FromIterator;
#[allow(unused_imports)]
use std::io::stdin;

mod util {
    use std::io::stdin;
    use std::str::FromStr;
    use std::fmt::Debug;

    #[allow(dead_code)]
    pub fn line() -> String {
        let mut line: String = String::new();
        stdin().read_line(&mut line).unwrap();
        line.trim().to_string()
    }

    #[allow(dead_code)]
    pub fn gets<T: FromStr>() -> Vec<T>
    where
        <T as FromStr>::Err: Debug,
    {
        let mut line: String = String::new();
        stdin().read_line(&mut line).unwrap();
        line.split_whitespace()
            .map(|t| t.parse().unwrap())
            .collect()
    }
}

#[allow(unused_macros)]
macro_rules! get {
    ($t:ty) => {
        {
            let mut line: String = String::new();
            stdin().read_line(&mut line).unwrap();
            line.trim().parse::<$t>().unwrap()
        }
    };
    ($($t:ty),*) => {
        {
            let mut line: String = String::new();
            stdin().read_line(&mut line).unwrap();
            let mut iter = line.split_whitespace();
            (
                $(iter.next().unwrap().parse::<$t>().unwrap(),)*
            )
        }
    };
    ($t:ty; $n:expr) => {
        (0..$n).map(|_|
                    get!($t)
                   ).collect::<Vec<_>>()
    };
    ($($t:ty),*; $n:expr) => {
        (0..$n).map(|_|
                    get!($($t),*)
                   ).collect::<Vec<_>>()
    };
    ($t:ty ;;) => {
        {
            let mut line: String = String::new();
            stdin().read_line(&mut line).unwrap();
            line.split_whitespace()
                .map(|t| t.parse::<$t>().unwrap())
                .collect::<Vec<_>>()
        }
    };
}

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        println!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
    }
}

fn main() {
    let _n = get!(usize);
    let seq: Vec<char> = util::line().chars().collect();

    let l = seq.iter().filter(|&&c| c == 'L').count();
    let r = seq.iter().filter(|&&c| c == 'R').count();
    let u = seq.iter().filter(|&&c| c == 'U').count();
    let d = seq.iter().filter(|&&c| c == 'D').count();

    println!("{}", 2 * min(l, r) + 2 * min(u, d));
}

use std::collections::HashMap;

macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let 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! {
        _n: usize,
        commands: chars,
    }

    let mut num_command = HashMap::new();

    commands
        .iter()
        .for_each(|x| *num_command.entry(x).or_insert(0) += 1);

    let num_l = *num_command.get(&'L').unwrap_or(&0);
    let num_r = *num_command.get(&'R').unwrap_or(&0);
    let num_u = *num_command.get(&'U').unwrap_or(&0);
    let num_d = *num_command.get(&'D').unwrap_or(&0);

    println!(
        "{}",
        std::cmp::min(num_l * 2, num_r * 2) + std::cmp::min(num_u * 2, num_d * 2)
    );
}

fn main() {
    let mut ri = ReadIn::new();
    let n = ri.int();
    ri.read_line();
    let s = ri.0;
    let mut c1 = 0;
    let mut c2 = 0;
    for c in s.chars() {
        if c == 'L' {
            c1 -= 1;
        }
        if c == 'R' {
            c1 += 1;
        }
        if c == 'U' {
            c2 -= 1;
        }
        if c == 'D' {
            c2 += 1;
        }
    }
    if c1 < 0 {
        c1 = -c1;
    }
    if c2 < 0 {
        c2 = -c2;
    }
    println!("{}", n - c1 - c2);
}

use std::iter::Map;
use std::str::SplitWhitespace;
use std::io::stdin;
use std::mem::forget;

pub struct ReadIn(pub String);

impl ReadIn {
    pub fn new() -> ReadIn {
        ReadIn(String::new())
    }
    fn read_i32(s: &str) -> i32 {
        s.parse().unwrap()
    }
    pub fn read_line(&mut self) {
        self.0.clear();
        forget(stdin().read_line(&mut self.0));
    }
    pub fn ints(&mut self) -> Map<SplitWhitespace, fn(&str) -> i32> {
        self.read_line();
        self.0.split_whitespace().map(ReadIn::read_i32)
    }
    pub fn int(&mut self) -> i32 {
        self.ints().next().unwrap()
    }
    pub fn int2(&mut self) -> (i32, i32) {
        let mut it = self.ints();
        (it.next().unwrap(), it.next().unwrap())
    }
}

use std::cmp::min;
use std::io::stdin;
fn main() {
    let mut _text = String::new();
    stdin().read_line(&mut _text).unwrap();
    let (uc, dc, rc, lc) = command_counter(parse());
    let counter = min(uc, dc) * 2 + min(lc, rc) * 2;
    println!("{}", counter)
}
#[derive(Debug, Copy, Clone)]
enum Command {
    U,
    D,
    L,
    R,
}

fn parse() -> Vec<Command> {
    let mut text = String::new();
    stdin().read_line(&mut text).unwrap();
    let fu = |e: char| -> Command {
        match e {
            'U' => Command::U,
            'D' => Command::D,
            'L' => Command::L,
            _ => Command::R,
        }
    };
    let text: Vec<Command> = text.trim().chars().map(fu).collect();
    text
}
fn command_counter(arr: Vec<Command>) -> (usize, usize, usize, usize) {
    let mut uc = 0;
    let mut dc = 0;
    let mut lc = 0;
    let mut rc = 0;
    for i in arr {
        match i {
            Command::U => uc += 1,
            Command::D => dc += 1,
            Command::L => lc += 1,
            Command::R => rc += 1,
        }
    }
    (uc, dc, rc, lc)
}

use std::cmp::min;
use std::io;
use std::io::Stdin;
use std::str::FromStr;

fn read_line(stdin : &Stdin, line : &mut String) {
    match stdin.read_line(line) {
        Ok(_) => return,
        Err(msg) => panic!("Could not read line! Message: {}.", msg),
    }
}

fn parse_t<T : FromStr>(s : &str) -> T {
    match s.trim().parse() {
        Ok(y) => y,
        Err(_) => panic!("Could not read from string!"),
    }
}

fn read_t<T : FromStr>(stdin : &Stdin) -> T {
    let mut line = String::new();
    read_line(stdin, &mut line);
    parse_t(&line)
}

fn max_moves(moves : &str) -> usize {
    let lrud = "LRUD".as_bytes();
    let left = lrud[0];
    let right = lrud[1];
    let up = lrud[2];
    let down = lrud[3];
    let mut num_left = 0;
    let mut num_right = 0;
    let mut num_up = 0;
    let mut num_down = 0;
    for &b in moves.as_bytes().iter() {
        if b == left {
            num_left = num_left + 1;
        } else if b == right {
            num_right = num_right + 1;
        } else if b == up {
            num_up = num_up + 1;
        } else if b == down {
            num_down = num_down + 1;
        } else {
            panic!("Unknown move!");
        }
    }
    let x = min(num_left, num_right);
    let y = min(num_up, num_down);
    x + x + y + y
}

fn main() {
    let stdin = io::stdin();
    let _ : usize = read_t(&stdin);
    let mut moves = String::new();
    read_line(&stdin, &mut moves);
    let moves = moves.trim();
    let x = max_moves(moves);
    println!("{}", x);
}

use std::io::stdin;
fn main() {
    let mut _text = String::new();
    stdin().read_line(&mut _text).unwrap();
    let commands = parse();
    let mut robot = Robot::new();
    let mut counter = 0;
    let mut results = vec!(0);
    for i in commands {
        robot.obey(i);
        counter +=1;
        if robot.x ==0 && robot.y ==0 {
           results.push(counter);
        }
    }
    println!("{}",results[results.len()-1])

}
enum Command {
    U,
    D,
    L,
    R,
}
struct Robot {
    x: usize,
    y: usize,
}
impl Robot {
    fn new() -> Robot {
        Robot { x: 0, y: 0 }
    }
    fn obey(&mut self, c: Command) {
        match c {
            Command::U => {
                self.y += 1;
            }
            Command::D => {
                self.y -= 1;
            }
            Command::L => {
                self.x -= 1;
            }
            Command::R => {
                self.x += 1;
            }
        };
    }
}

fn parse() -> Vec<Command> {
    let mut text = String::new();
    stdin().read_line(&mut text).unwrap();
    let fu = |e: char| -> Command {
        match e {
            'U' => Command::U,
            'D' => Command::D,
            'L' => Command::L,
            _ => Command::R,
        }
    };
    let text: Vec<Command> = text.trim().chars().map(fu).collect();
    text
}