Recently, Mike was very busy with studying for exams and contests. Now he is going to chill a bit by doing some sight seeing in the city.

City consists of n intersections numbered from 1 to n. Mike starts walking from his house located at the intersection number 1 and goes along some sequence of intersections. Walking from intersection number i to intersection j requires |i - j| units of energy. The total energy spent by Mike to visit a sequence of intersections p1 = 1, p2, ..., pk is equal to <image> units of energy.

Of course, walking would be boring if there were no shortcuts. A shortcut is a special path that allows Mike walking from one intersection to another requiring only 1 unit of energy. There are exactly n shortcuts in Mike's city, the ith of them allows walking from intersection i to intersection ai (i ≤ ai ≤ ai + 1) (but not in the opposite direction), thus there is exactly one shortcut starting at each intersection. Formally, if Mike chooses a sequence p1 = 1, p2, ..., pk then for each 1 ≤ i < k satisfying pi + 1 = api and api ≠ pi Mike will spend only 1 unit of energy instead of |pi - pi + 1| walking from the intersection pi to intersection pi + 1. For example, if Mike chooses a sequence p1 = 1, p2 = ap1, p3 = ap2, ..., pk = apk - 1, he spends exactly k - 1 units of total energy walking around them.

Before going on his adventure, Mike asks you to find the minimum amount of energy required to reach each of the intersections from his home. Formally, for each 1 ≤ i ≤ n Mike is interested in finding minimum possible total energy of some sequence p1 = 1, p2, ..., pk = i.

Input

The first line contains an integer n (1 ≤ n ≤ 200 000) — the number of Mike's city intersection.

The second line contains n integers a1, a2, ..., an (i ≤ ai ≤ n , <image>, describing shortcuts of Mike's city, allowing to walk from intersection i to intersection ai using only 1 unit of energy. Please note that the shortcuts don't allow walking in opposite directions (from ai to i).

Output

In the only line print n integers m1, m2, ..., mn, where mi denotes the least amount of total energy required to walk from intersection 1 to intersection i.

Examples

Input

3
2 2 3


Output

0 1 2 


Input

5
1 2 3 4 5


Output

0 1 2 3 4 


Input

7
4 4 4 4 7 7 7


Output

0 1 2 1 2 3 3 

Note

In the first sample case desired sequences are:

1: 1; m1 = 0;

2: 1, 2; m2 = 1;

3: 1, 3; m3 = |3 - 1| = 2.

In the second sample case the sequence for any intersection 1 < i is always 1, i and mi = |1 - i|.

In the third sample case — consider the following intersection sequences:

1: 1; m1 = 0;

2: 1, 2; m2 = |2 - 1| = 1;

3: 1, 4, 3; m3 = 1 + |4 - 3| = 2;

4: 1, 4; m4 = 1;

5: 1, 4, 5; m5 = 1 + |4 - 5| = 2;

6: 1, 4, 6; m6 = 1 + |4 - 6| = 3;

7: 1, 4, 5, 7; m7 = 1 + |4 - 5| + 1 = 3.










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





public class Main {
    
    
    
    
   static class sort implements Comparator<int[]>
   {
        public int compare(int[] a,int[] b)
        {
            
            return -b[0]+a[0];
        }
   }
   static class sort1 implements Comparator<long[]>
   {
        public int compare(long[] a,long[] b)
        {
            
          long c = -(a[0]-a[1]) + (b[0]-b[1]);

          if(c==0l) return 0;
          if(c>0l) return 1;
          return -1;
        }
   }
   static class sort5 implements Comparator<long[]>
   {
        public int compare(long[] a,long[] b)
        {
            
           double d1,d2;
           d1 = (a[0]+0.00)/(a[1]+0.00);
           d2 = (b[0]+0.00)/(b[1]+0.00);
           //int v = Double.comapre(d2,d1);
           double eph = 0.000000000000001;
           double d = (d2-d1);
          // pr(d1+" "+d2);
           if(d>eph) return 1;
           else if(d<eph) return -1;
           if(a[1]>b[1]) return 1;
           else if(b[1]>a[1]) return -1;
           return 0;
        }
   }
   static class sort11 implements Comparator<double[]>
   {
        public int compare(double[] a,double[] b)
        {
            //if(a[0] == b[0]) return a[1]-b[1];
           if(a[1] < b[1]) return -1;
           else if(a[1] > b[1]) return 1;
           return 0;
        }
   }
   public static String[] F(BufferedReader bf) throws Exception
    {
        return (bf.readLine().split(" "));
    }
    
   public static void pr(PrintWriter out,Object o)
   {
      
    out.println(o.toString());//out.flush();
    
   }
   public static void prW(PrintWriter out,Object o)
   {
      
    out.print(o.toString());//out.flush();
    
   }
   public static int intIn(String st)
   {
      return Integer.parseInt(st);
   }
   
   
    
    public static void pr(Object o)
    {
        System.out.println(o.toString());
    }
    public static void prW(Object o)
    {
        System.out.print(o.toString());
    }
    
   
    public static int inInt(String s)
    {
        return Integer.parseInt(s);
    }
    public static long in(String s)
    {
        return Long.parseLong(s);
    }
 
 
    static int[] toIntArray(String[] m) 
    { 
        int[] p=new int[m.length];
        for(int o=0;o<m.length;o++)
        {
            p[o]= inInt(m[o]);
        }
        return p;
    }
    static double[] toDArray(String[] m) 
    { 
        double[] p=new double[m.length];
        for(int o=0;o<m.length;o++)
        {
            p[o]= Double.parseDouble(m[o]);
        }
        return p;
    }
    static long[] toLArray(String[] m) 
    { 
       long[] p=new long[m.length];
        for(int o=0;o<m.length;o++)
        {
            p[o]= in(m[o]);
        }
        return p;
    }
   
     static long gcd(long a, long b)
        {
          if (b == 0)
            return a;
          return gcd(b, a % b); 
        }
     
        static long pow(long x, long y, long p)
      {
        if(y == 0) return 1l;
        long res = 1; // Initialize result
     
        x = x % p; // Update x if it is more than or
        // equal to p
     
        if (x == 0)
          return 0l; // In case x is divisible by p;
     
        while (y > 0)
        {
     
          // If y is odd, multiply x with result
          if ((y & 1) != 0)
            res = (res * x) % p;
     
          // y must be even now
          y = y >> 1; // y = y/2
          x = (x * x) % p;
        }
        return res;
      }
    
   
    static int nCr(int n, int r, int p)
    {
        if (r > n - r)
            r = n - r;
 
        // The array C is going to store last
        // row of pascal triangle at the end.
        // And last entry of last row is nCr
        int C[] = new int[r + 1];
 
        C[0] = 1; // Top row of Pascal Triangle
 
        // One by constructs remaining rows of Pascal
        // Triangle from top to bottom
        for (int i = 1; i <= n; i++) {
 
            // Fill entries of current row using previous
            // row values
            for (int j = Math.min(i, r); j > 0; j--)
 
                // nCj = (n-1)Cj + (n-1)C(j-1);
                C[j] = (C[j] + C[j - 1]) % p;
        }
        return C[r];
    }
    // F(o,-1,tm,vis,par,o,mat);
   public static int log(int x)
   {
       boolean bol = true;

       if(((x-1)&x) == 0) bol=false;

       int c=0;
       while(x > 0)
       {
        x=(x/2);
        c++;
       }

       if(!bol) c--;
       return c;

   }

   
   static class sor implements Comparator<long[]>
   {
      public int compare(long[] a,long[] b)
      {
         if(a[0] == b[0])
         {
            if(a[1] < b[1]) return -1;
            return 1;
         }
         if(a[0] > b[0]) return 1;
         return -1;
      }
   }


    static long ncr(int n, int r)
    {
 
        // p holds the value of n*(n-1)*(n-2)...,
        // k holds the value of r*(r-1)...
        long p = 1, k = 1;
        if(n<r) return 0l;
 
        // C(n, r) == C(n, n-r),
        // choosing the smaller value
        if (n - r < r) {
            r = n - r;
        }
 
        if (r != 0) {
            while (r > 0) {
                p *= n;
                k *= r;
 
                // gcd of p, k
                long m = __gcd(p, k);
 
                // dividing by gcd, to simplify
                // product division by their gcd
                // saves from the overflow
                p /= m;
                k /= m;
 
                n--;
                r--;
            }
 
            // k should be simplified to 1
            // as C(n, r) is a natural number
            // (denominator should be 1 ) .
        }
        else {
            p = 1;
        }
 
        // if our approach is correct p = ans and k =1
        return p;
    }
       static class DSU {
    
    int[] p;int[] sz;int op;int c;;
    int[] last;
    public void G(int n)
    {
        last=new int[n];
        p=new int[n];
        sz=new int[n];c=n;
        op=n;
        for(int h=0;h<n;h++)
        {
            sz[h]=1;p[h]=h;
            last[h]=h;
        }
    }
    public int find(int x)
    {
        int y=x;
        while(x!=p[x]) x=p[x];
        while(y!=p[y])
        {
            int tem=p[y];
            p[y]=x;y=tem;
        }
        return p[y];
    }
    public void union(int a,int b)
    {
        int x,y;
        x=find(a);y=find(b);
        if(x==y) return;
        if(sz[x]>sz[y])
        {
            p[y] = x;
            sz[x]+=sz[y];
            last[x]=Math.max(last[x],last[y]);
        }
        else
        {
            p[x]=y;sz[y]+=sz[x];
            last[y]=Math.max(last[y],last[x]);
        }
        c--;
        
    }}
    static long __gcd(long n1, long n2)
    {

        if(n1==0l) return n2;
        if(n2==0l) return n1;
        if(n1==1l || n2==1l) return 1l;
       // long gcd = 1;
        if(n1 == n2)  return n1;
        if(n1>n2) return __gcd(n1%n2,n2);
        return __gcd(n1,n2%n1);
        
    }
    static long big = -1000000000000000l;
    static long max=big*100l;
   
    public static void main (String[] args) throws Exception {
        
        BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(System.out);;;
        
        //int[] map=new int[1000001];
      
       int yy=1;//inInt(bf.readLine());
       


        //Long[][][] dp = new Long[100001][101][2];
        for(int w=0;w<yy;w++)
        {
            // String str = bf.readLine();
          out.flush();
         
            String[] xlp = bf.readLine().split(" ");;;;;;
            //String st = bf.readLine();
        int n;//boolean bol=false;
           int  m;//long a,b,c;
           int l;
           //int  k;//pr(out,"vbc");
         n=inInt(xlp[0]);//m=inInt(xlp[1]);//int ta=inInt(xlp[2]);int tb=inInt(xlp[3]);k=inInt(xlp[4]);
        //l=inInt(xlp[2]); k =inInt(xlp[3]);
         
         List<List<Integer>> list=new ArrayList<>();

         for(int i=0;i<n;i++) list.add(new ArrayList<>());

            int[] arr = toIntArray(F(bf));

      for(int i=0;i<n;i++)
      {
            list.get(arr[i]-1).add(i);
      }
      //pr(out,list);
      int min=0;
      prW(out,0+" ");
      int[] dp = new int[n];
      TreeMap<Integer,Integer> tm=new TreeMap<>();
      dp[0]=0;
      for(int i=1;i<n;i++) dp[i]=i;
      if((arr[0]-1) != (0))
      dp[arr[0]-1] = 1;
       tm.put(arr[0],arr[0]-1);
      for(int i=1;i<n;i++)
      {
            int v = Math.min(dp[i],min+i);
            /*for(int x : list.get(i))
            {
                  if(x != i)
                  v= Math.min(v,dp[x]+1);
            }*/
            while(tm.size() > 0 && tm.get(tm.firstKey())<=i) tm.remove(tm.firstKey());
            //pr(out,v);
            if(tm.size() > 0){
                  Integer mi  = tm.firstKey();
                  v = Math.min(v,mi-i);
            }
            if((arr[i]-1) != (i))
            dp[arr[i]-1] = Math.min(dp[arr[i]-1],v+1);
      int val = dp[arr[i]-1]+arr[i]-1;
      int index = tm.getOrDefault(val,0);
            tm.put(dp[arr[i]-1]+arr[i]-1,Math.max(arr[i]-1,index));
           // pr(out,v);
            dp[i] = v;
            prW(out,dp[i]+" ");
            min=Math.min(min,dp[i]-i);
      }

      



         





        

          




      

         
         
         



         
         
   }
    out.close();
   bf.close();
}}


/*
98
17 17 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 57 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 87 90 90 90 90 90 90 90 90 90 90 90 92 92 92 92 92 92 92 92 92 92 92 92 92 92 92 92 92 92 92 92 92 92 92 92 92 92 95 95 95 95 95 97 98 98



Kickstart
 String rp;
            rp = "Case #"+(w+1)+": "+(n-ans)+" ";
static int[][] dir={{0,1},{1,0},{-1,0},{0,-1}};

static class SegmentTreeRMQ 
    { 
    int st[]; 
    int minVal(int x, int y) { 
        return (x > y) ? x : y; 
    } 
  
    
    int getMid(int s, int e) { 
        return s + (e - s) / 2; 
    } 
  
    
    int RMQUtil(int ss, int se, int qs, int qe, int index) 
    { 
        
        if (qs <= ss && qe >= se) 
            return st[index]; 
  
        // If segment of this node is outside the given range 
        if (se < qs || ss > qe) 
            return Integer.MIN_VALUE; 
  
        // If a part of this segment overlaps with the given range 
        int mid = getMid(ss, se); 
        return minVal(RMQUtil(ss, mid, qs, qe, 2 * index + 1), 
                RMQUtil(mid + 1, se, qs, qe, 2 * index + 2)); 
    } 
  
    // Return minimum of elements in range from index qs (query 
    // start) to qe (query end).  It mainly uses RMQUtil() 
    int RMQ(int n, int qs, int qe) 
    { 
        // Check for erroneous input values 
        
  
        return RMQUtil(0, n - 1, qs, qe, 0); 
    } 
  
    // A recursive function that constructs Segment Tree for 
    // array[ss..se]. si is index of current node in segment tree st 
    int constructSTUtil(int arr[], int ss, int se, int si) 
    { 
        // If there is one element in array, store it in current 
        //  node of segment tree and return 
        if (ss == se) { 
            st[si] = arr[ss]; 
            return arr[ss]; 
        } 
  
        // If there are more than one elements, then recur for left and 
        // right subtrees and store the minimum of two values in this node 
        int mid = getMid(ss, se); 
        st[si] = minVal(constructSTUtil(arr, ss, mid, si * 2 + 1), 
                constructSTUtil(arr, mid + 1, se, si * 2 + 2)); 
        return st[si]; 
    } 
  
    
    void con(int arr[]) 
    { 
        // Allocate memory for segment tree 
  
        //Height of segment tree 
        int n = (arr.length);
        int x = (int) (Math.ceil(Math.log(n) / Math.log(2))); 
  
        //Maximum size of segment tree 
        int max_size = 2 * (int) Math.pow(2, x) - 1; 
        st = new int[max_size]; // allocate memory 
  
        // Fill the allocated memory st 
        constructSTUtil(arr, 0, n - 1, 0); 
    }
    }
     static class DSU {
    
    int[] p;int[] sz;int op;int c;;
    int[] last;
    public void G(int n)
    {
        last=new int[n];
        p=new int[n];
        sz=new int[n];c=n;
        op=n;
        for(int h=0;h<n;h++)
        {
            sz[h]=1;p[h]=h;
            last[h]=h;
        }
    }
    public int find(int x)
    {
        int y=x;
        while(x!=p[x]) x=p[x];
        while(y!=p[y])
        {
            int tem=p[y];
            p[y]=x;y=tem;
        }
        return p[y];
    }
    public void union(int a,int b)
    {
        int x,y;
        x=find(a);y=find(b);
        if(x==y) return;
        if(sz[x]>sz[y])
        {
            p[y] = x;
            sz[x]+=sz[y];
            last[x]=Math.max(last[x],last[y]);
        }
        else
        {
            p[x]=y;sz[y]+=sz[x];
            last[y]=Math.max(last[y],last[x]);
        }
        c--;
        
    }}

    static long pow(long x, long y, long p)
      {
        long res = 1; // Initialize result
     
        x = x % p; // Update x if it is more than or
        // equal to p
     
        if (x == 0)
          return 0l; // In case x is divisible by p;
     
        while (y > 0)
        {
     
          // If y is odd, multiply x with result
          if ((y & 1) != 0)
            res = (res * x) % p;
     
          // y must be even now
          y = y >> 1; // y = y/2
          x = (x * x) % p;
        }
        return res;
      }
      static long gcd(long a, long b)
        {
          if (b == 0)
            return a;
          return gcd(b, a % b); 
        }
        static int gcd(int a, int b,int o)
        {
          if (b == 0)
            return a;
          return gcd(b, a % b,o); 
        }

Geometric median

public static double F(double[] x,double[] w)
    {
        double d1,d2;
        double S=0.00;
        for(double dp : w) S += dp;
        int k = 0;
        double sum = S - w[0]; // sum is the total weight of all `x[i] > x[k]`

        while(sum > S/2)
        {
            ++k;
            sum -= w[k];
        }
        d1=x[k];
        return d1;
        k = w.length-1;
       sum = S - w[k]; // sum is the total weight of all `x[i] > x[k]`

        while(sum > S/2)
        {
            --k;
            sum -= w[k];
        }
        d2=x[k];
        return new double[]{d1,d2};
    }
*/

















