///****In the name of ALLAH, most Gracious, most Compassionate****//

#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")

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

typedef long long ll;
typedef pair <int, int> pii;

#define ALL(a) a.begin(), a.end()
#define FastIO ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
#define IN freopen("input.txt","r+",stdin)
#define OUT freopen("output.txt","w+",stdout)

#define DBG(a) cerr<< "line "<<__LINE__ <<" : "<< #a <<" --> "<<(a)<<endl
#define NL cout<<endl

template < class T1,class T2>
ostream &operator <<(ostream &os,const pair < T1,T2 > &p)
{
    os<<"{"<<p.first<<","<<p.second<<"}";
    return os;
}

const int N=3e5+5;
const int oo=1e9+7;

vector<pii> g[N];

int ans[N];

int n;

void dfs(int u)
{
    for(pii vc: g[u])
    {
        if(ans[vc.first]==-1)
        {
            if(vc.second == ans[u])
                ans[vc.first] = (vc.second %n)+1;
            else
                ans[vc.first] = vc.second;
            dfs(vc.first);
        }
    }
}


int32_t main()
{
    FastIO;
    int m;
    cin>>n>>m;
    while(m--)
    {
        int u,v,c;
        cin>>u>>v>>c;
        g[u].push_back({v,c});
        g[v].push_back({u,c});
    }

    memset(ans , -1 , sizeof ans) ;

    ans[1] =1;
    dfs(1);
    for(int i=1;i<=n;i++)
        cout<<ans[i]<<"\n";

}

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

#define FOR(i,s,e) for(int i=(s);(i)<(int)(e);++(i))
#define REP(i,e) FOR(i,0,e)
#define each(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define all(o) (o).begin(), (o).end()

typedef long long ll;
const int N = 200000;
int n;
int a[N];

class union_find_tree {
  private:
    vector<int> v;
    vector<int> connected_size;
    map<int,int> parent;
    map<int,int> rank;

  public:
    union_find_tree(int m) {
      v.resize(m);
      connected_size.resize(m);
      for (int i=0; i<m; i++) v[i] = i;
      for (int i=0; i<(int)v.size(); i++) {
        parent[v[i]] = v[i];
        rank[v[i]] = 1;
        connected_size[v[i]] = 1;
      }
    }

    union_find_tree(vector<int> _v) {
      v = _v;
      for (int i=0; i<(int)v.size(); i++) {
        parent[v[i]] = v[i];
        rank[v[i]] = 1;
        connected_size[v[i]] = 1;
      }
    }

    ~union_find_tree() {
      v.clear();
      parent.clear();
      rank.clear();
      connected_size.clear();
    }
    
    int root (int x) {
      return parent[x] == x ? x : parent[x] = root(parent[x]);
    }

    bool is_same(int x, int y) {
      return root(x) == root(y);
    }  

    void unite(int x, int y) {
      x = root(x);
      y = root(y);
      
      if (x == y) return;

      if (rank[x] < rank[y]) {
        parent[x] = y;
        connected_size[y] += connected_size[x];
      } else {
        parent[y] = x;
        connected_size[x] += connected_size[y];
        if (rank[x] == rank[y]) rank[x]++; 
      }
      return;
    }

    int get_connected_size(int x) {
      return connected_size[x];
    }
};

int main() {
  fscanf(stdin, "%d ", &n);
  REP(i,n) {
    fscanf(stdin, "%d ", a+i);
    a[i]--;
  }
  union_find_tree u(N);
  REP(i,n/2) u.unite(a[i],a[n-1-i]);
  int res = 0;
  REP(i,N) {
    if (u.root(i) != i) continue;
    res += u.get_connected_size(i) - 1;
  }
  fprintf(stdout, "%d\n", res);
  return 0;
}
