#include <bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(), (x).end()
using lli = long long int;
struct Edge {
  int from;
  int to;
  int cost;
  int idx;

  Edge() {}
  Edge(int f, int t) : Edge(f, t, 1, -1) {}
  Edge(int f, int t, int c, int i) : from(f), to(t), cost(c), idx(i) {}

  inline int next(int v) const { return v ^ from ^ to; }
};

struct Graph {
  Graph() {}
  Graph(const vector<vector<Edge>>& g) : g(g) {}
  Graph(int n, const vector<Edge>& edges, bool unordered = true) : g(n) {
    for (const auto& e : edges) {
      g[e.from].push_back(e);
      if (unordered) {
        g[e.to].push_back(e);
      }
    }
  }

  inline int N() const { return g.size(); }

  vector<vector<int>> ToVector() {
    vector<vector<int>> result(g.size());
    for (int i = 0; i < g.size(); ++i) {
      result[i].reserve(g[i].size());
      for (auto& e : g[i]) result[i].push_back(e.next(i));
    }
    return result;
  }

  vector<vector<Edge>> g;
};
vector<Edge> ReadEdges(int m, bool weighted = false) {
  vector<Edge> edges(m);
  for (int i = 0; i < m; ++i) {
    auto& e = edges[i];
    cin >> e.from >> e.to;
    e.idx = i;
    e.cost = 1;
    --e.from;
    --e.to;
    if (weighted) cin >> e.cost;
  }
  return edges;
}
Graph* ReadGraph(bool unordered = true, bool weighted = false) {
  int n, m;
  cin >> n >> m;
  return new Graph(n, ReadEdges(m, weighted), unordered);
}
template <typename T = lli>
struct SumF {
  using TCost = T;
  static T MaxValue() { return std::numeric_limits<T>::max() / 2; }
  static T Default() { return 0ll; }
  static T Sum(const T& from, const Edge& e) { return from + e.cost; }
};
template <typename TSum = SumF<lli>>
struct ShortestPathSolver {
 public:
  ShortestPathSolver(const Graph* g, int source)
      : graph_(g),
        source_(source),
        distances(g->N(), TSum::MaxValue()),
        parents(g->N()) {}
  ShortestPathSolver<TSum>& Do() {
    Run();
    return *this;
  }
  virtual void Run() {}
  virtual ~ShortestPathSolver() {}

  vector<const Edge*> PathTo(int to) {
    vector<const Edge*> path;
    while (parents[to] != nullptr) {
      path.push_back(parents[to]);
      to = parents[to]->next(to);
    }
    reverse(all(path));
    return path;
  }
  typename TSum::TCost DistanceOr(int to, typename TSum::TCost value) {
    return parents[to] == nullptr && to != source_ ? value : distances[to];
  }

  const Graph* graph_;
  const int source_;
  vector<typename TSum::TCost> distances;
  vector<const Edge*> parents;
};
template<typename TSum = SumF<lli>>
struct BfsSolver : public ShortestPathSolver<TSum>{
  BfsSolver(const Graph* g, int source) : ShortestPathSolver<TSum>(g, source) {}

  void Run() override {
    queue<int> q;
    distances[source_] = TSum::Default();
    q.emplace(source_);
    while (!q.empty()) {
      auto v = q.front(); q.pop();
      for (const auto& e : graph_->g[v]) {
        int to = e.next(v);
        if (parents[to] == nullptr && to != source_) {
          distances[to] = TSum::Sum(distances[v], e);
          parents[to] = &e;
          q.emplace(to);
        }
      }
    }
  }

  using B = ShortestPathSolver<TSum>;
  using B::graph_;
  using B::source_;
  using B::distances;
  using B::parents;
};

int main() {
  ios_base::sync_with_stdio(false); cin.tie(NULL);
  auto g = ReadGraph();
  auto helper = BfsSolver(g, 0).Do();
  for (auto v : helper.distances) {
    if (v  > g->N()) {
      cout << "No";
      return 0;
    }
  }
  cout << "Yes" << endl;
  for (int i = 1; i < helper.parents.size(); ++i) {
    cout << helper.parents[i]->next(i)+1 << endl;
  }
  return 0;
}

Measured memory_bytes: 19428